diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcInitiatedLspRequestVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcInitiatedLspRequestVer1.java
index 970c197..4dc2d21 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcInitiatedLspRequestVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcInitiatedLspRequestVer1.java
@@ -1,297 +1,297 @@
-/*
- * 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 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.PcepLspObject;
-import org.onosproject.pcepio.protocol.PcepSrpObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides PcInitiatedLspRequest for PCEP Initiate message.
- * Reference : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03.
- */
-public class PcInitiatedLspRequestVer1 implements PcInitiatedLspRequest {
-
-    /*
-     * <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>
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcInitiatedLspRequestVer1.class);
-
-    //PCEP SRP Object
-    private PcepSrpObject srpObject;
-    //PCEP LSP Object
-    private PcepLspObject lspObject;
-    //PCEP End Point Object
-    private PcepEndPointsObject endPointsObject;
-    //PCEP ERO Object
-    private PcepEroObject eroObject;
-    //PCEP Attribute list
-    private PcepAttribute pcepAttribute;
-
-    /**
-     * Default constructor.
-     */
-    public PcInitiatedLspRequestVer1() {
-        srpObject = null;
-        lspObject = null;
-        endPointsObject = null;
-        eroObject = null;
-        pcepAttribute = null;
-
-    }
-
-    /**
-     * Constructor to initialize all parameters of PC initiated lsp request.
-     *
-     * @param srpObject PCEP srp Object
-     * @param lspObject PCEP lsp object
-     * @param endPointsObject PCPE endpoints object
-     * @param eroObject PCEP ero object
-     * @param pcepAttribute PCEP attribute
-     */
-    public PcInitiatedLspRequestVer1(PcepSrpObject srpObject, PcepLspObject lspObject,
-            PcepEndPointsObject endPointsObject, PcepEroObject eroObject, PcepAttribute pcepAttribute) {
-        this.srpObject = srpObject;
-        this.lspObject = lspObject;
-        this.endPointsObject = endPointsObject;
-        this.eroObject = eroObject;
-        this.pcepAttribute = pcepAttribute;
-
-    }
-
-    @Override
-    public PcepSrpObject getSrpObject() {
-        return srpObject;
-    }
-
-    @Override
-    public PcepLspObject getLspObject() {
-        return lspObject;
-    }
-
-    @Override
-    public PcepEndPointsObject getEndPointsObject() {
-        return endPointsObject;
-    }
-
-    @Override
-    public PcepEroObject getEroObject() {
-        return eroObject;
-    }
-
-    @Override
-    public PcepAttribute getPcepAttribute() {
-        return pcepAttribute;
-    }
-
-    @Override
-    public void setSrpObject(PcepSrpObject srpobj) {
-        this.srpObject = srpobj;
-
-    }
-
-    @Override
-    public void setLspObject(PcepLspObject lspObject) {
-        this.lspObject = lspObject;
-    }
-
-    @Override
-    public void setEndPointsObject(PcepEndPointsObject endPointsObject) {
-        this.endPointsObject = endPointsObject;
-    }
-
-    @Override
-    public void setEroObject(PcepEroObject eroObject) {
-        this.eroObject = eroObject;
-    }
-
-    @Override
-    public void setPcepAttribute(PcepAttribute pcepAttribute) {
-        this.pcepAttribute = pcepAttribute;
-    }
-
-    /**
-     * Builder class for PC initiated lsp reuqest.
-     */
-    public static class Builder implements PcInitiatedLspRequest.Builder {
-
-        private boolean bIsSRPObjectSet = false;
-        private boolean bIsLSPObjectSet = false;
-        private boolean bIsEndPointsObjectSet = false;
-        private boolean bIsEROObjectSet = false;
-        private boolean bIsPcepAttributeSet = false;
-        private boolean bIsbRFlagSet = false;
-
-        //PCEP SRP Object
-        private PcepSrpObject srpObject;
-        //PCEP LSP Object
-        private PcepLspObject lspObject;
-        //PCEP End Point Object
-        private PcepEndPointsObject endPointsObject;
-        //PCEP ERO Object
-        private PcepEroObject eroObject;
-        //PCEP Attribute list
-        private PcepAttribute pcepAttribute;
-
-        @Override
-        public PcInitiatedLspRequest build() throws PcepParseException {
-
-            //PCEP SRP Object
-            PcepSrpObject srpObject = null;
-            //PCEP LSP Object
-            PcepLspObject lspObject = null;
-            //PCEP End Point Object
-            PcepEndPointsObject endPointsObject = null;
-            //PCEP ERO Object
-            PcepEroObject eroObject = null;
-            //PCEP Attribute list
-            PcepAttribute pcepAttribute = null;
-            boolean bRFlag = false;
-
-            if (!this.bIsSRPObjectSet) {
-                throw new PcepParseException("Srp object NOT Set while building PcInitiatedLspRequest");
-            } else {
-                srpObject = this.srpObject;
-                bRFlag = srpObject.getRFlag();
-            }
-
-            if (bRFlag) {
-                this.bIsbRFlagSet = true;
-            } else {
-                this.bIsbRFlagSet = false;
-            }
-
-            if (!this.bIsLSPObjectSet) {
-                throw new PcepParseException("LSP Object NOT Set while building PcInitiatedLspRequest");
-            } else {
-                lspObject = this.lspObject;
-            }
-            if (!this.bIsbRFlagSet) {
-
-                if (!this.bIsEndPointsObjectSet) {
-                    throw new PcepParseException("EndPoints Object NOT Set while building PcInitiatedLspRequest");
-                } else {
-                    endPointsObject = this.endPointsObject;
-                }
-                if (!this.bIsEROObjectSet) {
-                    throw new PcepParseException("ERO Object NOT Set while building PcInitiatedLspRequest");
-                } else {
-                    eroObject = this.eroObject;
-                }
-                if (bIsPcepAttributeSet) {
-                    pcepAttribute = this.pcepAttribute;
-                }
-            }
-            return new PcInitiatedLspRequestVer1(srpObject, lspObject, endPointsObject, eroObject, pcepAttribute);
-        }
-
-        @Override
-        public PcepSrpObject getSrpObject() {
-            return this.srpObject;
-        }
-
-        @Override
-        public PcepLspObject getLspObject() {
-            return this.lspObject;
-        }
-
-        @Override
-        public PcepEndPointsObject getEndPointsObject() {
-            return this.endPointsObject;
-        }
-
-        @Override
-        public PcepEroObject getEroObject() {
-            return this.eroObject;
-        }
-
-        @Override
-        public PcepAttribute getPcepAttribute() {
-            return this.pcepAttribute;
-        }
-
-        @Override
-        public Builder setSrpObject(PcepSrpObject srpobj) {
-            this.srpObject = srpobj;
-            this.bIsSRPObjectSet = true;
-            return this;
-
-        }
-
-        @Override
-        public Builder setLspObject(PcepLspObject lspObject) {
-            this.lspObject = lspObject;
-            this.bIsLSPObjectSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setEndPointsObject(PcepEndPointsObject endPointsObject) {
-            this.endPointsObject = endPointsObject;
-            this.bIsEndPointsObjectSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setEroObject(PcepEroObject eroObject) {
-            this.eroObject = eroObject;
-            this.bIsEROObjectSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setPcepAttribute(PcepAttribute pcepAttribute) {
-            this.pcepAttribute = pcepAttribute;
-            this.bIsPcepAttributeSet = true;
-            return this;
-        }
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-        toStrHelper.add("SrpObject", srpObject).add("LspObject", lspObject);
-
-        if (endPointsObject instanceof PcepEndPointsObject) {
-            toStrHelper.add("EndPointObject", endPointsObject);
-        }
-        if (eroObject instanceof PcepEroObject) {
-            toStrHelper.add("EroObject", eroObject);
-        }
-        if (pcepAttribute instanceof PcepAttribute) {
-            toStrHelper.add("PcepAttribute", pcepAttribute);
-        }
-        return toStrHelper.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 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.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides PcInitiatedLspRequest for PCEP Initiate message.
+ * Reference : PCE initiated tunnel setup draft-ietf-pce-pce-initiated-lsp-03.
+ */
+public class PcInitiatedLspRequestVer1 implements PcInitiatedLspRequest {
+
+    /*
+     * <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>
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcInitiatedLspRequestVer1.class);
+
+    //PCEP SRP Object
+    private PcepSrpObject srpObject;
+    //PCEP LSP Object
+    private PcepLspObject lspObject;
+    //PCEP End Point Object
+    private PcepEndPointsObject endPointsObject;
+    //PCEP ERO Object
+    private PcepEroObject eroObject;
+    //PCEP Attribute list
+    private PcepAttribute pcepAttribute;
+
+    /**
+     * Default constructor.
+     */
+    public PcInitiatedLspRequestVer1() {
+        srpObject = null;
+        lspObject = null;
+        endPointsObject = null;
+        eroObject = null;
+        pcepAttribute = null;
+
+    }
+
+    /**
+     * Constructor to initialize all parameters of PC initiated lsp request.
+     *
+     * @param srpObject PCEP srp Object
+     * @param lspObject PCEP lsp object
+     * @param endPointsObject PCPE endpoints object
+     * @param eroObject PCEP ero object
+     * @param pcepAttribute PCEP attribute
+     */
+    public PcInitiatedLspRequestVer1(PcepSrpObject srpObject, PcepLspObject lspObject,
+            PcepEndPointsObject endPointsObject, PcepEroObject eroObject, PcepAttribute pcepAttribute) {
+        this.srpObject = srpObject;
+        this.lspObject = lspObject;
+        this.endPointsObject = endPointsObject;
+        this.eroObject = eroObject;
+        this.pcepAttribute = pcepAttribute;
+
+    }
+
+    @Override
+    public PcepSrpObject getSrpObject() {
+        return srpObject;
+    }
+
+    @Override
+    public PcepLspObject getLspObject() {
+        return lspObject;
+    }
+
+    @Override
+    public PcepEndPointsObject getEndPointsObject() {
+        return endPointsObject;
+    }
+
+    @Override
+    public PcepEroObject getEroObject() {
+        return eroObject;
+    }
+
+    @Override
+    public PcepAttribute getPcepAttribute() {
+        return pcepAttribute;
+    }
+
+    @Override
+    public void setSrpObject(PcepSrpObject srpobj) {
+        this.srpObject = srpobj;
+
+    }
+
+    @Override
+    public void setLspObject(PcepLspObject lspObject) {
+        this.lspObject = lspObject;
+    }
+
+    @Override
+    public void setEndPointsObject(PcepEndPointsObject endPointsObject) {
+        this.endPointsObject = endPointsObject;
+    }
+
+    @Override
+    public void setEroObject(PcepEroObject eroObject) {
+        this.eroObject = eroObject;
+    }
+
+    @Override
+    public void setPcepAttribute(PcepAttribute pcepAttribute) {
+        this.pcepAttribute = pcepAttribute;
+    }
+
+    /**
+     * Builder class for PC initiated lsp reuqest.
+     */
+    public static class Builder implements PcInitiatedLspRequest.Builder {
+
+        private boolean bIsSRPObjectSet = false;
+        private boolean bIsLSPObjectSet = false;
+        private boolean bIsEndPointsObjectSet = false;
+        private boolean bIsEROObjectSet = false;
+        private boolean bIsPcepAttributeSet = false;
+        private boolean bIsbRFlagSet = false;
+
+        //PCEP SRP Object
+        private PcepSrpObject srpObject;
+        //PCEP LSP Object
+        private PcepLspObject lspObject;
+        //PCEP End Point Object
+        private PcepEndPointsObject endPointsObject;
+        //PCEP ERO Object
+        private PcepEroObject eroObject;
+        //PCEP Attribute list
+        private PcepAttribute pcepAttribute;
+
+        @Override
+        public PcInitiatedLspRequest build() throws PcepParseException {
+
+            //PCEP SRP Object
+            PcepSrpObject srpObject = null;
+            //PCEP LSP Object
+            PcepLspObject lspObject = null;
+            //PCEP End Point Object
+            PcepEndPointsObject endPointsObject = null;
+            //PCEP ERO Object
+            PcepEroObject eroObject = null;
+            //PCEP Attribute list
+            PcepAttribute pcepAttribute = null;
+            boolean bRFlag = false;
+
+            if (!this.bIsSRPObjectSet) {
+                throw new PcepParseException("Srp object NOT Set while building PcInitiatedLspRequest");
+            } else {
+                srpObject = this.srpObject;
+                bRFlag = srpObject.getRFlag();
+            }
+
+            if (bRFlag) {
+                this.bIsbRFlagSet = true;
+            } else {
+                this.bIsbRFlagSet = false;
+            }
+
+            if (!this.bIsLSPObjectSet) {
+                throw new PcepParseException("LSP Object NOT Set while building PcInitiatedLspRequest");
+            } else {
+                lspObject = this.lspObject;
+            }
+            if (!this.bIsbRFlagSet) {
+
+                if (!this.bIsEndPointsObjectSet) {
+                    throw new PcepParseException("EndPoints Object NOT Set while building PcInitiatedLspRequest");
+                } else {
+                    endPointsObject = this.endPointsObject;
+                }
+                if (!this.bIsEROObjectSet) {
+                    throw new PcepParseException("ERO Object NOT Set while building PcInitiatedLspRequest");
+                } else {
+                    eroObject = this.eroObject;
+                }
+                if (bIsPcepAttributeSet) {
+                    pcepAttribute = this.pcepAttribute;
+                }
+            }
+            return new PcInitiatedLspRequestVer1(srpObject, lspObject, endPointsObject, eroObject, pcepAttribute);
+        }
+
+        @Override
+        public PcepSrpObject getSrpObject() {
+            return this.srpObject;
+        }
+
+        @Override
+        public PcepLspObject getLspObject() {
+            return this.lspObject;
+        }
+
+        @Override
+        public PcepEndPointsObject getEndPointsObject() {
+            return this.endPointsObject;
+        }
+
+        @Override
+        public PcepEroObject getEroObject() {
+            return this.eroObject;
+        }
+
+        @Override
+        public PcepAttribute getPcepAttribute() {
+            return this.pcepAttribute;
+        }
+
+        @Override
+        public Builder setSrpObject(PcepSrpObject srpobj) {
+            this.srpObject = srpobj;
+            this.bIsSRPObjectSet = true;
+            return this;
+
+        }
+
+        @Override
+        public Builder setLspObject(PcepLspObject lspObject) {
+            this.lspObject = lspObject;
+            this.bIsLSPObjectSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setEndPointsObject(PcepEndPointsObject endPointsObject) {
+            this.endPointsObject = endPointsObject;
+            this.bIsEndPointsObjectSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setEroObject(PcepEroObject eroObject) {
+            this.eroObject = eroObject;
+            this.bIsEROObjectSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setPcepAttribute(PcepAttribute pcepAttribute) {
+            this.pcepAttribute = pcepAttribute;
+            this.bIsPcepAttributeSet = true;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+        toStrHelper.add("SrpObject", srpObject).add("LspObject", lspObject);
+
+        if (endPointsObject instanceof PcepEndPointsObject) {
+            toStrHelper.add("EndPointObject", endPointsObject);
+        }
+        if (eroObject instanceof PcepEroObject) {
+            toStrHelper.add("EroObject", eroObject);
+        }
+        if (pcepAttribute instanceof PcepAttribute) {
+            toStrHelper.add("PcepAttribute", pcepAttribute);
+        }
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepAttributeVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepAttributeVer1.java
index a63fd27..3e3e562 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepAttributeVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepAttributeVer1.java
@@ -1,440 +1,440 @@
-/*
- * 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.PcepAttribute;
-import org.onosproject.pcepio.protocol.PcepBandwidthObject;
-import org.onosproject.pcepio.protocol.PcepIroObject;
-import org.onosproject.pcepio.protocol.PcepLspaObject;
-import org.onosproject.pcepio.protocol.PcepMetricObject;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides PCEP Attribute List.
- */
-public class PcepAttributeVer1 implements PcepAttribute {
-
-    /* Reference : RFC5440
-     *  where:
-     *      <attribute-list>                  ::=[<LSPA>]
-     *                                           [<BANDWIDTH>]
-     *                                           [<metric-list>]
-     *                                           [<IRO>]
-     *
-     *      <metric-list>                     ::=<METRIC>[<metric-list>]
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepAttributeVer1.class);
-
-    public static final int OBJECT_HEADER_LENGTH = 4;
-
-    //PCEP LSPA Object
-    private PcepLspaObject lspaObject;
-    private boolean isLspaObjectSet;
-
-    //PCEP Bandwidth Object
-    private PcepBandwidthObject bandwidthObject;
-    private boolean isBandwidthObjectSet;
-
-    //PCEP Metric list
-    private LinkedList<PcepMetricObject> llMetricList;
-    private boolean isMetricListSet;
-
-    //PCEP IRO object
-    private PcepIroObject iroObject;
-    private boolean isIroObjectSet;
-
-    /**
-     * Default constructor to initialize member variables.
-     */
-    public PcepAttributeVer1() {
-
-        lspaObject = null;
-        bandwidthObject = null;
-        llMetricList = null;
-        iroObject = null;
-        this.isLspaObjectSet = false;
-        this.isBandwidthObjectSet = false;
-        this.isMetricListSet = false;
-        this.isIroObjectSet = false;
-    }
-
-    /**
-     * Constructor to initialize all parameters for PCEP attribute.
-     *
-     * @param lspaObject         PCEP lspa Object.
-     * @param bandwidthObject    PCEP bandwidth object.
-     * @param llMetricList       list of PCEP metric objects.
-     * @param iroObject          PCEP iro object.
-     */
-    public PcepAttributeVer1(PcepLspaObject lspaObject, PcepBandwidthObject bandwidthObject,
-            LinkedList<PcepMetricObject> llMetricList, PcepIroObject iroObject) {
-
-        this.lspaObject = lspaObject;
-        this.bandwidthObject = bandwidthObject;
-        this.llMetricList = llMetricList;
-        this.iroObject = iroObject;
-        if (lspaObject == null) {
-            this.isLspaObjectSet = false;
-        } else {
-            this.isLspaObjectSet = true;
-        }
-        if (bandwidthObject == null) {
-            this.isBandwidthObjectSet = false;
-        } else {
-            this.isBandwidthObjectSet = true;
-        }
-        if (llMetricList == null) {
-            this.isMetricListSet = false;
-        } else {
-            this.isMetricListSet = true;
-        }
-        if (iroObject == null) {
-            this.isIroObjectSet = false;
-        } else {
-            this.isIroObjectSet = true;
-        }
-    }
-
-    /**
-     * constructor to initialize bandwidthObject.
-     *
-     * @param bandwidthObject bandwidth object
-     */
-    public PcepAttributeVer1(PcepBandwidthObject bandwidthObject) {
-        this.isLspaObjectSet = false;
-
-        this.bandwidthObject = bandwidthObject;
-        this.isBandwidthObjectSet = true;
-
-        this.isMetricListSet = false;
-
-        this.isIroObjectSet = false;
-    }
-
-    /**
-     * Parse list for MeticObject.
-     *
-     * @param cb of type channel buffer
-     * @return true if parsing metric list is success
-     * @throws PcepParseException when a non metric object is received
-     */
-    public boolean parseMetricList(ChannelBuffer cb) throws PcepParseException {
-
-        if (null == llMetricList) {
-            llMetricList = new LinkedList<PcepMetricObject>();
-        }
-
-        PcepMetricObject metriclist;
-
-        //caller should verify for metric object
-        byte yObjClass = PcepMetricObjectVer1.METRIC_OBJ_CLASS;
-        byte yObjType = PcepMetricObjectVer1.METRIC_OBJ_TYPE;
-
-        while ((yObjClass == PcepMetricObjectVer1.METRIC_OBJ_CLASS)
-                && (yObjType == PcepMetricObjectVer1.METRIC_OBJ_TYPE)) {
-
-            metriclist = PcepMetricObjectVer1.read(cb);
-            llMetricList.add(metriclist);
-            yObjClass = 0;
-            yObjType = 0;
-
-            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
-                cb.markReaderIndex();
-                PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-                cb.resetReaderIndex();
-                yObjClass = tempObjHeader.getObjClass();
-                yObjType = tempObjHeader.getObjType();
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Reads lspa , bandwidth , Metriclist and Iro objects and sets the objects.
-     *
-     * @param cb of type channel buffer
-     * @return instance of Pcep Attribute
-     * @throws PcepParseException while parsing Pcep Attributes from channel buffer
-     */
-
-    public static PcepAttribute read(ChannelBuffer cb) throws PcepParseException {
-        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
-            return null;
-        }
-        //check whether any pcep attribute is present
-        cb.markReaderIndex();
-        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-        cb.resetReaderIndex();
-        byte yObjClass = tempObjHeader.getObjClass();
-
-        if (PcepLspaObjectVer1.LSPA_OBJ_CLASS != yObjClass && PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS != yObjClass
-                && PcepMetricObjectVer1.METRIC_OBJ_CLASS != yObjClass && PcepIroObjectVer1.IRO_OBJ_CLASS != yObjClass) {
-            //No PCEP attribute is present
-            return null;
-        }
-
-        PcepAttributeVer1 pcepAttribute = new PcepAttributeVer1();
-
-        //If LSPA present then store it.LSPA is optional
-        if (yObjClass == PcepLspaObjectVer1.LSPA_OBJ_CLASS) {
-            pcepAttribute.setLspaObject(PcepLspaObjectVer1.read(cb));
-            yObjClass = checkNextObject(cb);
-        }
-
-        //If BANDWIDTH present then store it.BANDWIDTH is optional
-        if (yObjClass == PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS) {
-            pcepAttribute.setBandwidthObject(PcepBandwidthObjectVer1.read(cb));
-            yObjClass = checkNextObject(cb);
-        }
-
-        //If Metric list present then store it.MetricList is optional
-        if (yObjClass == PcepMetricObjectVer1.METRIC_OBJ_CLASS) {
-            pcepAttribute.parseMetricList(cb);
-            yObjClass = checkNextObject(cb);
-        }
-
-        //If IRO present then store it.IRO is optional
-        if (yObjClass == PcepIroObjectVer1.IRO_OBJ_CLASS) {
-            pcepAttribute.setIroObject(PcepIroObjectVer1.read(cb));
-        }
-
-        PcepLspaObject lspaObject = pcepAttribute.getLspaObject();
-        PcepBandwidthObject bandwidthObject = pcepAttribute.getBandwidthObject();
-        LinkedList<PcepMetricObject> metriclist = pcepAttribute.llMetricList;
-        PcepIroObject iroObject = pcepAttribute.getIroObject();
-
-        return new PcepAttributeVer1(lspaObject, bandwidthObject, metriclist, iroObject);
-    }
-
-    /**
-     * Checks whether there is a more object or not.
-     *
-     * @param cb of type channel buffer
-     * @return instance of object header
-     */
-    private static byte checkNextObject(ChannelBuffer cb) {
-        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
-            return 0;
-        }
-        cb.markReaderIndex();
-        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-        cb.resetReaderIndex();
-        return tempObjHeader.getObjClass();
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-        int iLenStartIndex = cb.writerIndex();
-        //PCEP LSPA object is optional
-        if (this.isLspaObjectSet) {
-            this.lspaObject.write(cb);
-        }
-
-        //PCEP BANDWIDTH object is optional
-        if (this.isBandwidthObjectSet) {
-            this.bandwidthObject.write(cb);
-        }
-
-        //PCEP Metric list is optional
-        if (this.isMetricListSet) {
-            ListIterator<PcepMetricObject> listIterator = this.llMetricList.listIterator();
-            while (listIterator.hasNext()) {
-                listIterator.next().write(cb);
-            }
-        }
-
-        //PCEP  IRO object is optional
-        if (this.isIroObjectSet) {
-            this.iroObject.write(cb);
-        }
-        return cb.writerIndex() - iLenStartIndex;
-    }
-
-    @Override
-    public PcepLspaObject getLspaObject() {
-        return lspaObject;
-    }
-
-    @Override
-    public PcepBandwidthObject getBandwidthObject() {
-        return bandwidthObject;
-    }
-
-    @Override
-    public LinkedList<PcepMetricObject> getMetricObjectList() {
-        return llMetricList;
-    }
-
-    @Override
-    public PcepIroObject getIroObject() {
-        return iroObject;
-    }
-
-    @Override
-    public void setBandwidthObject(PcepBandwidthObject bandwidthObject) {
-        this.isBandwidthObjectSet = true;
-        this.bandwidthObject = bandwidthObject;
-    }
-
-    @Override
-    public void setMetricObjectList(LinkedList<PcepMetricObject> llMetricList) {
-        this.isMetricListSet = true;
-        this.llMetricList = llMetricList;
-
-    }
-
-    @Override
-    public void setLspaObject(PcepLspaObject lspaObject) {
-        this.isLspaObjectSet = true;
-        this.lspaObject = lspaObject;
-    }
-
-    @Override
-    public void setIroObject(PcepIroObject iroObject) {
-        this.isIroObjectSet = true;
-        this.iroObject = iroObject;
-    }
-
-    /**
-     * Builder class for PCEP attributes.
-     */
-    public static class Builder implements PcepAttribute.Builder {
-
-        //PCEP LSPA Object
-        private PcepLspaObject lspaObject;
-        private boolean isLspaObjectSet;
-
-        //PCEP BANDWIDTH Object
-        private PcepBandwidthObject bandwidthObject;
-        private boolean isBandwidthObjectSet;
-
-        //PCEP Metric list
-        private LinkedList<PcepMetricObject> llMetricList;
-        private boolean isMetricListSet;
-
-        //PCEP IRO object
-        private PcepIroObject iroObject;
-        private boolean isIroObjectSet;
-
-        @Override
-        public PcepAttribute build() {
-
-            //PCEP LSPA Object
-            PcepLspaObject lspaObject = null;
-
-            //PCEP BANDWIDTH Object
-            PcepBandwidthObject bandwidthObject = null;
-
-            //PCEP Metric list
-            LinkedList<PcepMetricObject> llMetricList = null;
-
-            //PCEP IRO object
-            PcepIroObject iroObject = null;
-
-            if (this.isLspaObjectSet) {
-                lspaObject = this.lspaObject;
-            }
-            if (this.isBandwidthObjectSet) {
-                bandwidthObject = this.bandwidthObject;
-            }
-            if (this.isMetricListSet) {
-                llMetricList = this.llMetricList;
-            }
-            if (this.isIroObjectSet) {
-                iroObject = this.iroObject;
-            }
-            return new PcepAttributeVer1(lspaObject, bandwidthObject, llMetricList, iroObject);
-        }
-
-        @Override
-        public PcepLspaObject getLspaObject() {
-            return this.lspaObject;
-        }
-
-        @Override
-        public PcepBandwidthObject getBandwidthObject() {
-            return this.bandwidthObject;
-        }
-
-        @Override
-        public LinkedList<PcepMetricObject> getMetricObjectList() {
-            return this.llMetricList;
-        }
-
-        @Override
-        public PcepIroObject getIroObject() {
-            return this.iroObject;
-        }
-
-        @Override
-        public Builder setBandwidthObject(PcepBandwidthObject bandwidthObject) {
-            this.isBandwidthObjectSet = true;
-            this.bandwidthObject = bandwidthObject;
-            return this;
-        }
-
-        @Override
-        public Builder setMetricObjectList(LinkedList<PcepMetricObject> llMetricList) {
-            this.isMetricListSet = true;
-            this.llMetricList = llMetricList;
-            return this;
-        }
-
-        @Override
-        public Builder setLspaObject(PcepLspaObject lspaObject) {
-            this.isLspaObjectSet = true;
-            this.lspaObject = lspaObject;
-            return this;
-        }
-
-        @Override
-        public Builder setIroObject(PcepIroObject iroObject) {
-            this.isIroObjectSet = true;
-            this.iroObject = iroObject;
-            return this;
-        }
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        if (lspaObject instanceof PcepLspaObject) {
-            toStrHelper.add("lspaObject", lspaObject);
-        }
-        if (bandwidthObject instanceof PcepBandwidthObject) {
-            toStrHelper.add("bandwidthObject", bandwidthObject);
-        }
-        if (llMetricList instanceof PcepMetricObject) {
-            toStrHelper.add("MetricObjectList", llMetricList);
-        }
-        if (iroObject instanceof PcepIroObject) {
-            toStrHelper.add("IroObject", iroObject);
-        }
-        return toStrHelper.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.PcepAttribute;
+import org.onosproject.pcepio.protocol.PcepBandwidthObject;
+import org.onosproject.pcepio.protocol.PcepIroObject;
+import org.onosproject.pcepio.protocol.PcepLspaObject;
+import org.onosproject.pcepio.protocol.PcepMetricObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides PCEP Attribute List.
+ */
+public class PcepAttributeVer1 implements PcepAttribute {
+
+    /* Reference : RFC5440
+     *  where:
+     *      <attribute-list>                  ::=[<LSPA>]
+     *                                           [<BANDWIDTH>]
+     *                                           [<metric-list>]
+     *                                           [<IRO>]
+     *
+     *      <metric-list>                     ::=<METRIC>[<metric-list>]
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepAttributeVer1.class);
+
+    public static final int OBJECT_HEADER_LENGTH = 4;
+
+    //PCEP LSPA Object
+    private PcepLspaObject lspaObject;
+    private boolean isLspaObjectSet;
+
+    //PCEP Bandwidth Object
+    private PcepBandwidthObject bandwidthObject;
+    private boolean isBandwidthObjectSet;
+
+    //PCEP Metric list
+    private LinkedList<PcepMetricObject> llMetricList;
+    private boolean isMetricListSet;
+
+    //PCEP IRO object
+    private PcepIroObject iroObject;
+    private boolean isIroObjectSet;
+
+    /**
+     * Default constructor to initialize member variables.
+     */
+    public PcepAttributeVer1() {
+
+        lspaObject = null;
+        bandwidthObject = null;
+        llMetricList = null;
+        iroObject = null;
+        this.isLspaObjectSet = false;
+        this.isBandwidthObjectSet = false;
+        this.isMetricListSet = false;
+        this.isIroObjectSet = false;
+    }
+
+    /**
+     * Constructor to initialize all parameters for PCEP attribute.
+     *
+     * @param lspaObject         PCEP lspa Object.
+     * @param bandwidthObject    PCEP bandwidth object.
+     * @param llMetricList       list of PCEP metric objects.
+     * @param iroObject          PCEP iro object.
+     */
+    public PcepAttributeVer1(PcepLspaObject lspaObject, PcepBandwidthObject bandwidthObject,
+            LinkedList<PcepMetricObject> llMetricList, PcepIroObject iroObject) {
+
+        this.lspaObject = lspaObject;
+        this.bandwidthObject = bandwidthObject;
+        this.llMetricList = llMetricList;
+        this.iroObject = iroObject;
+        if (lspaObject == null) {
+            this.isLspaObjectSet = false;
+        } else {
+            this.isLspaObjectSet = true;
+        }
+        if (bandwidthObject == null) {
+            this.isBandwidthObjectSet = false;
+        } else {
+            this.isBandwidthObjectSet = true;
+        }
+        if (llMetricList == null) {
+            this.isMetricListSet = false;
+        } else {
+            this.isMetricListSet = true;
+        }
+        if (iroObject == null) {
+            this.isIroObjectSet = false;
+        } else {
+            this.isIroObjectSet = true;
+        }
+    }
+
+    /**
+     * constructor to initialize bandwidthObject.
+     *
+     * @param bandwidthObject bandwidth object
+     */
+    public PcepAttributeVer1(PcepBandwidthObject bandwidthObject) {
+        this.isLspaObjectSet = false;
+
+        this.bandwidthObject = bandwidthObject;
+        this.isBandwidthObjectSet = true;
+
+        this.isMetricListSet = false;
+
+        this.isIroObjectSet = false;
+    }
+
+    /**
+     * Parse list for MeticObject.
+     *
+     * @param cb of type channel buffer
+     * @return true if parsing metric list is success
+     * @throws PcepParseException when a non metric object is received
+     */
+    public boolean parseMetricList(ChannelBuffer cb) throws PcepParseException {
+
+        if (null == llMetricList) {
+            llMetricList = new LinkedList<PcepMetricObject>();
+        }
+
+        PcepMetricObject metriclist;
+
+        //caller should verify for metric object
+        byte yObjClass = PcepMetricObjectVer1.METRIC_OBJ_CLASS;
+        byte yObjType = PcepMetricObjectVer1.METRIC_OBJ_TYPE;
+
+        while ((yObjClass == PcepMetricObjectVer1.METRIC_OBJ_CLASS)
+                && (yObjType == PcepMetricObjectVer1.METRIC_OBJ_TYPE)) {
+
+            metriclist = PcepMetricObjectVer1.read(cb);
+            llMetricList.add(metriclist);
+            yObjClass = 0;
+            yObjType = 0;
+
+            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
+                cb.markReaderIndex();
+                PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                yObjClass = tempObjHeader.getObjClass();
+                yObjType = tempObjHeader.getObjType();
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Reads lspa , bandwidth , Metriclist and Iro objects and sets the objects.
+     *
+     * @param cb of type channel buffer
+     * @return instance of Pcep Attribute
+     * @throws PcepParseException while parsing Pcep Attributes from channel buffer
+     */
+
+    public static PcepAttribute read(ChannelBuffer cb) throws PcepParseException {
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            return null;
+        }
+        //check whether any pcep attribute is present
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        byte yObjClass = tempObjHeader.getObjClass();
+
+        if (PcepLspaObjectVer1.LSPA_OBJ_CLASS != yObjClass && PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS != yObjClass
+                && PcepMetricObjectVer1.METRIC_OBJ_CLASS != yObjClass && PcepIroObjectVer1.IRO_OBJ_CLASS != yObjClass) {
+            //No PCEP attribute is present
+            return null;
+        }
+
+        PcepAttributeVer1 pcepAttribute = new PcepAttributeVer1();
+
+        //If LSPA present then store it.LSPA is optional
+        if (yObjClass == PcepLspaObjectVer1.LSPA_OBJ_CLASS) {
+            pcepAttribute.setLspaObject(PcepLspaObjectVer1.read(cb));
+            yObjClass = checkNextObject(cb);
+        }
+
+        //If BANDWIDTH present then store it.BANDWIDTH is optional
+        if (yObjClass == PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS) {
+            pcepAttribute.setBandwidthObject(PcepBandwidthObjectVer1.read(cb));
+            yObjClass = checkNextObject(cb);
+        }
+
+        //If Metric list present then store it.MetricList is optional
+        if (yObjClass == PcepMetricObjectVer1.METRIC_OBJ_CLASS) {
+            pcepAttribute.parseMetricList(cb);
+            yObjClass = checkNextObject(cb);
+        }
+
+        //If IRO present then store it.IRO is optional
+        if (yObjClass == PcepIroObjectVer1.IRO_OBJ_CLASS) {
+            pcepAttribute.setIroObject(PcepIroObjectVer1.read(cb));
+        }
+
+        PcepLspaObject lspaObject = pcepAttribute.getLspaObject();
+        PcepBandwidthObject bandwidthObject = pcepAttribute.getBandwidthObject();
+        LinkedList<PcepMetricObject> metriclist = pcepAttribute.llMetricList;
+        PcepIroObject iroObject = pcepAttribute.getIroObject();
+
+        return new PcepAttributeVer1(lspaObject, bandwidthObject, metriclist, iroObject);
+    }
+
+    /**
+     * Checks whether there is a more object or not.
+     *
+     * @param cb of type channel buffer
+     * @return instance of object header
+     */
+    private static byte checkNextObject(ChannelBuffer cb) {
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            return 0;
+        }
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        return tempObjHeader.getObjClass();
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+        int iLenStartIndex = cb.writerIndex();
+        //PCEP LSPA object is optional
+        if (this.isLspaObjectSet) {
+            this.lspaObject.write(cb);
+        }
+
+        //PCEP BANDWIDTH object is optional
+        if (this.isBandwidthObjectSet) {
+            this.bandwidthObject.write(cb);
+        }
+
+        //PCEP Metric list is optional
+        if (this.isMetricListSet) {
+            ListIterator<PcepMetricObject> listIterator = this.llMetricList.listIterator();
+            while (listIterator.hasNext()) {
+                listIterator.next().write(cb);
+            }
+        }
+
+        //PCEP  IRO object is optional
+        if (this.isIroObjectSet) {
+            this.iroObject.write(cb);
+        }
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    @Override
+    public PcepLspaObject getLspaObject() {
+        return lspaObject;
+    }
+
+    @Override
+    public PcepBandwidthObject getBandwidthObject() {
+        return bandwidthObject;
+    }
+
+    @Override
+    public LinkedList<PcepMetricObject> getMetricObjectList() {
+        return llMetricList;
+    }
+
+    @Override
+    public PcepIroObject getIroObject() {
+        return iroObject;
+    }
+
+    @Override
+    public void setBandwidthObject(PcepBandwidthObject bandwidthObject) {
+        this.isBandwidthObjectSet = true;
+        this.bandwidthObject = bandwidthObject;
+    }
+
+    @Override
+    public void setMetricObjectList(LinkedList<PcepMetricObject> llMetricList) {
+        this.isMetricListSet = true;
+        this.llMetricList = llMetricList;
+
+    }
+
+    @Override
+    public void setLspaObject(PcepLspaObject lspaObject) {
+        this.isLspaObjectSet = true;
+        this.lspaObject = lspaObject;
+    }
+
+    @Override
+    public void setIroObject(PcepIroObject iroObject) {
+        this.isIroObjectSet = true;
+        this.iroObject = iroObject;
+    }
+
+    /**
+     * Builder class for PCEP attributes.
+     */
+    public static class Builder implements PcepAttribute.Builder {
+
+        //PCEP LSPA Object
+        private PcepLspaObject lspaObject;
+        private boolean isLspaObjectSet;
+
+        //PCEP BANDWIDTH Object
+        private PcepBandwidthObject bandwidthObject;
+        private boolean isBandwidthObjectSet;
+
+        //PCEP Metric list
+        private LinkedList<PcepMetricObject> llMetricList;
+        private boolean isMetricListSet;
+
+        //PCEP IRO object
+        private PcepIroObject iroObject;
+        private boolean isIroObjectSet;
+
+        @Override
+        public PcepAttribute build() {
+
+            //PCEP LSPA Object
+            PcepLspaObject lspaObject = null;
+
+            //PCEP BANDWIDTH Object
+            PcepBandwidthObject bandwidthObject = null;
+
+            //PCEP Metric list
+            LinkedList<PcepMetricObject> llMetricList = null;
+
+            //PCEP IRO object
+            PcepIroObject iroObject = null;
+
+            if (this.isLspaObjectSet) {
+                lspaObject = this.lspaObject;
+            }
+            if (this.isBandwidthObjectSet) {
+                bandwidthObject = this.bandwidthObject;
+            }
+            if (this.isMetricListSet) {
+                llMetricList = this.llMetricList;
+            }
+            if (this.isIroObjectSet) {
+                iroObject = this.iroObject;
+            }
+            return new PcepAttributeVer1(lspaObject, bandwidthObject, llMetricList, iroObject);
+        }
+
+        @Override
+        public PcepLspaObject getLspaObject() {
+            return this.lspaObject;
+        }
+
+        @Override
+        public PcepBandwidthObject getBandwidthObject() {
+            return this.bandwidthObject;
+        }
+
+        @Override
+        public LinkedList<PcepMetricObject> getMetricObjectList() {
+            return this.llMetricList;
+        }
+
+        @Override
+        public PcepIroObject getIroObject() {
+            return this.iroObject;
+        }
+
+        @Override
+        public Builder setBandwidthObject(PcepBandwidthObject bandwidthObject) {
+            this.isBandwidthObjectSet = true;
+            this.bandwidthObject = bandwidthObject;
+            return this;
+        }
+
+        @Override
+        public Builder setMetricObjectList(LinkedList<PcepMetricObject> llMetricList) {
+            this.isMetricListSet = true;
+            this.llMetricList = llMetricList;
+            return this;
+        }
+
+        @Override
+        public Builder setLspaObject(PcepLspaObject lspaObject) {
+            this.isLspaObjectSet = true;
+            this.lspaObject = lspaObject;
+            return this;
+        }
+
+        @Override
+        public Builder setIroObject(PcepIroObject iroObject) {
+            this.isIroObjectSet = true;
+            this.iroObject = iroObject;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        if (lspaObject instanceof PcepLspaObject) {
+            toStrHelper.add("lspaObject", lspaObject);
+        }
+        if (bandwidthObject instanceof PcepBandwidthObject) {
+            toStrHelper.add("bandwidthObject", bandwidthObject);
+        }
+        if (llMetricList instanceof PcepMetricObject) {
+            toStrHelper.add("MetricObjectList", llMetricList);
+        }
+        if (iroObject instanceof PcepIroObject) {
+            toStrHelper.add("IroObject", iroObject);
+        }
+        return toStrHelper.toString();
+    }
 }
\ No newline at end of file
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEndPointsObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEndPointsObjectVer1.java
index 79668d0..131fd75 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEndPointsObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEndPointsObjectVer1.java
@@ -1,255 +1,255 @@
-/*
- * 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 org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepEndPointsObject;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP Endpoints Object.
- */
-public class PcepEndPointsObjectVer1 implements PcepEndPointsObject {
-
-    /*
-     * RFC : 5440 , section : 7.6
-     * An End point is defined as follows:
-    END-POINTS Object-Class is 4.
-
-    END-POINTS Object-Type is 1 for IPv4 and 2 for IPv6.
-    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)       |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |                     Source IPv4 address                       |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-      |                  Destination IPv4 address                     |
-      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepEndPointsObjectVer1.class);
-
-    static final byte END_POINTS_OBJ_TYPE = 1;
-    static final byte END_POINTS_OBJ_CLASS = 4;
-    static final byte END_POINTS_OBJECT_VERSION = 1;
-    static final short END_POINTS_OBJ_MINIMUM_LENGTH = 12;
-    public static byte endPointObjType;
-
-    static final PcepObjectHeader DEFAULT_END_POINTS_OBJECT_HEADER = new PcepObjectHeader(END_POINTS_OBJ_CLASS,
-            END_POINTS_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
-            END_POINTS_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader endPointsObjHeader;
-    public int sourceIpAddress;
-    public int destIpAddress;
-
-    /**
-     * Constructor to initialize all variables.
-     *
-     * @param endPointsObjHeader end points object header
-     * @param sourceIpAddress source IP address
-     * @param destIpAddress destination IP address
-     */
-    public PcepEndPointsObjectVer1(PcepObjectHeader endPointsObjHeader, int sourceIpAddress, int destIpAddress) {
-
-        this.endPointsObjHeader = endPointsObjHeader;
-        this.sourceIpAddress = sourceIpAddress;
-        this.destIpAddress = destIpAddress;
-    }
-
-    /**
-     * Sets End Points Object Header.
-     *
-     * @param obj of PcepObjectHeader
-     */
-    public void setEndPointsObjHeader(PcepObjectHeader obj) {
-        this.endPointsObjHeader = obj;
-    }
-
-    @Override
-    public void setSourceIpAddress(int sourceIpAddress) {
-        this.sourceIpAddress = sourceIpAddress;
-    }
-
-    @Override
-    public void setDestIpAddress(int destIpAddress) {
-        this.destIpAddress = destIpAddress;
-    }
-
-    @Override
-    public int getSourceIpAddress() {
-        return this.sourceIpAddress;
-    }
-
-    @Override
-    public int getDestIpAddress() {
-        return this.destIpAddress;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of PcepEndPointsObject.
-     *
-     * @param cb of channel buffer
-     * @return object of PcepEndPointsObject
-     * @throws PcepParseException while parsing channel buffer
-     */
-    public static PcepEndPointsObject read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader endPointsObjHeader;
-        int sourceIpAddress;
-        int destIpAddress;
-
-        endPointsObjHeader = PcepObjectHeader.read(cb);
-        if (END_POINTS_OBJ_TYPE == endPointsObjHeader.getObjType()
-                && END_POINTS_OBJ_CLASS == endPointsObjHeader.getObjClass()) {
-            sourceIpAddress = cb.readInt();
-            destIpAddress = cb.readInt();
-        } else {
-            throw new PcepParseException("Expected PcepEndPointsObject.");
-        }
-        return new PcepEndPointsObjectVer1(endPointsObjHeader, sourceIpAddress, destIpAddress);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        int objStartIndex = cb.writerIndex();
-        //write common header
-        int objLenIndex = endPointsObjHeader.write(cb);
-
-        //write source IPv4 IP
-        cb.writeInt(sourceIpAddress);
-        //write destination IPv4 IP
-        cb.writeInt(destIpAddress);
-
-        int length = cb.writerIndex() - objStartIndex;
-        //now write EndPoints Object Length
-        cb.setShort(objLenIndex, (short) length);
-        //will be helpful during print().
-        endPointsObjHeader.setObjLen((short) length);
-
-        return cb.writerIndex();
-
-    }
-
-    /**
-     * Builder class for PCEP end points objects.
-     */
-    public static class Builder implements PcepEndPointsObject.Builder {
-
-        private boolean bIsHeaderSet = false;
-        private boolean bIsSourceIpAddressset = false;
-        private boolean bIsDestIpAddressset = false;
-        private PcepObjectHeader endpointsObjHeader;
-        private int sourceIpAddress;
-        private int destIpAddress;
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepEndPointsObject build() throws PcepParseException {
-
-            PcepObjectHeader endpointsObjHeader = this.bIsHeaderSet ? this.endpointsObjHeader
-                    : DEFAULT_END_POINTS_OBJECT_HEADER;
-
-            if (bIsPFlagSet) {
-                endpointsObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                endpointsObjHeader.setIFlag(bIFlag);
-            }
-
-            if (!this.bIsSourceIpAddressset) {
-                throw new PcepParseException("SourceIpAddress not set while building EndPoints object");
-            }
-
-            if (!this.bIsDestIpAddressset) {
-                throw new PcepParseException("DestIpAddress not set while building EndPoints object");
-            }
-
-            return new PcepEndPointsObjectVer1(endpointsObjHeader, this.sourceIpAddress, this.destIpAddress);
-        }
-
-        @Override
-        public PcepObjectHeader getEndPointsObjHeader() {
-            return this.endpointsObjHeader;
-        }
-
-        @Override
-        public Builder setEndPointsObjHeader(PcepObjectHeader obj) {
-            this.endpointsObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public int getSourceIpAddress() {
-            return this.sourceIpAddress;
-        }
-
-        @Override
-        public Builder setSourceIpAddress(int sourceIpAddress) {
-            this.sourceIpAddress = sourceIpAddress;
-            this.bIsSourceIpAddressset = true;
-            return this;
-        }
-
-        @Override
-        public int getDestIpAddress() {
-            return this.destIpAddress;
-        }
-
-        @Override
-        public Builder setDestIpAddress(int destIpAddress) {
-            this.destIpAddress = destIpAddress;
-            this.bIsDestIpAddressset = true;
-            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("sourceIpAddress", sourceIpAddress)
-                .add("destIpAddress", destIpAddress).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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepEndPointsObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP Endpoints Object.
+ */
+public class PcepEndPointsObjectVer1 implements PcepEndPointsObject {
+
+    /*
+     * RFC : 5440 , section : 7.6
+     * An End point is defined as follows:
+    END-POINTS Object-Class is 4.
+
+    END-POINTS Object-Type is 1 for IPv4 and 2 for IPv6.
+    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)       |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                     Source IPv4 address                       |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                  Destination IPv4 address                     |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepEndPointsObjectVer1.class);
+
+    static final byte END_POINTS_OBJ_TYPE = 1;
+    static final byte END_POINTS_OBJ_CLASS = 4;
+    static final byte END_POINTS_OBJECT_VERSION = 1;
+    static final short END_POINTS_OBJ_MINIMUM_LENGTH = 12;
+    public static byte endPointObjType;
+
+    static final PcepObjectHeader DEFAULT_END_POINTS_OBJECT_HEADER = new PcepObjectHeader(END_POINTS_OBJ_CLASS,
+            END_POINTS_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
+            END_POINTS_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader endPointsObjHeader;
+    public int sourceIpAddress;
+    public int destIpAddress;
+
+    /**
+     * Constructor to initialize all variables.
+     *
+     * @param endPointsObjHeader end points object header
+     * @param sourceIpAddress source IP address
+     * @param destIpAddress destination IP address
+     */
+    public PcepEndPointsObjectVer1(PcepObjectHeader endPointsObjHeader, int sourceIpAddress, int destIpAddress) {
+
+        this.endPointsObjHeader = endPointsObjHeader;
+        this.sourceIpAddress = sourceIpAddress;
+        this.destIpAddress = destIpAddress;
+    }
+
+    /**
+     * Sets End Points Object Header.
+     *
+     * @param obj of PcepObjectHeader
+     */
+    public void setEndPointsObjHeader(PcepObjectHeader obj) {
+        this.endPointsObjHeader = obj;
+    }
+
+    @Override
+    public void setSourceIpAddress(int sourceIpAddress) {
+        this.sourceIpAddress = sourceIpAddress;
+    }
+
+    @Override
+    public void setDestIpAddress(int destIpAddress) {
+        this.destIpAddress = destIpAddress;
+    }
+
+    @Override
+    public int getSourceIpAddress() {
+        return this.sourceIpAddress;
+    }
+
+    @Override
+    public int getDestIpAddress() {
+        return this.destIpAddress;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of PcepEndPointsObject.
+     *
+     * @param cb of channel buffer
+     * @return object of PcepEndPointsObject
+     * @throws PcepParseException while parsing channel buffer
+     */
+    public static PcepEndPointsObject read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader endPointsObjHeader;
+        int sourceIpAddress;
+        int destIpAddress;
+
+        endPointsObjHeader = PcepObjectHeader.read(cb);
+        if (END_POINTS_OBJ_TYPE == endPointsObjHeader.getObjType()
+                && END_POINTS_OBJ_CLASS == endPointsObjHeader.getObjClass()) {
+            sourceIpAddress = cb.readInt();
+            destIpAddress = cb.readInt();
+        } else {
+            throw new PcepParseException("Expected PcepEndPointsObject.");
+        }
+        return new PcepEndPointsObjectVer1(endPointsObjHeader, sourceIpAddress, destIpAddress);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+        //write common header
+        int objLenIndex = endPointsObjHeader.write(cb);
+
+        //write source IPv4 IP
+        cb.writeInt(sourceIpAddress);
+        //write destination IPv4 IP
+        cb.writeInt(destIpAddress);
+
+        int length = cb.writerIndex() - objStartIndex;
+        //now write EndPoints Object Length
+        cb.setShort(objLenIndex, (short) length);
+        //will be helpful during print().
+        endPointsObjHeader.setObjLen((short) length);
+
+        return cb.writerIndex();
+
+    }
+
+    /**
+     * Builder class for PCEP end points objects.
+     */
+    public static class Builder implements PcepEndPointsObject.Builder {
+
+        private boolean bIsHeaderSet = false;
+        private boolean bIsSourceIpAddressset = false;
+        private boolean bIsDestIpAddressset = false;
+        private PcepObjectHeader endpointsObjHeader;
+        private int sourceIpAddress;
+        private int destIpAddress;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepEndPointsObject build() throws PcepParseException {
+
+            PcepObjectHeader endpointsObjHeader = this.bIsHeaderSet ? this.endpointsObjHeader
+                    : DEFAULT_END_POINTS_OBJECT_HEADER;
+
+            if (bIsPFlagSet) {
+                endpointsObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                endpointsObjHeader.setIFlag(bIFlag);
+            }
+
+            if (!this.bIsSourceIpAddressset) {
+                throw new PcepParseException("SourceIpAddress not set while building EndPoints object");
+            }
+
+            if (!this.bIsDestIpAddressset) {
+                throw new PcepParseException("DestIpAddress not set while building EndPoints object");
+            }
+
+            return new PcepEndPointsObjectVer1(endpointsObjHeader, this.sourceIpAddress, this.destIpAddress);
+        }
+
+        @Override
+        public PcepObjectHeader getEndPointsObjHeader() {
+            return this.endpointsObjHeader;
+        }
+
+        @Override
+        public Builder setEndPointsObjHeader(PcepObjectHeader obj) {
+            this.endpointsObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getSourceIpAddress() {
+            return this.sourceIpAddress;
+        }
+
+        @Override
+        public Builder setSourceIpAddress(int sourceIpAddress) {
+            this.sourceIpAddress = sourceIpAddress;
+            this.bIsSourceIpAddressset = true;
+            return this;
+        }
+
+        @Override
+        public int getDestIpAddress() {
+            return this.destIpAddress;
+        }
+
+        @Override
+        public Builder setDestIpAddress(int destIpAddress) {
+            this.destIpAddress = destIpAddress;
+            this.bIsDestIpAddressset = true;
+            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("sourceIpAddress", sourceIpAddress)
+                .add("destIpAddress", destIpAddress).toString();
+    }
+
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
index 86f13bb..131d657 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepEroObjectVer1.java
@@ -1,406 +1,406 @@
-/*
- * 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.PcepEroObject;
-import org.onosproject.pcepio.types.AutonomousSystemTlv;
-import org.onosproject.pcepio.types.IPv4SubObject;
-import org.onosproject.pcepio.types.IPv6SubObject;
-import org.onosproject.pcepio.types.PathKeySubObject;
-import org.onosproject.pcepio.types.PcepErrorDetailInfo;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.onosproject.pcepio.types.PcepValueType;
-import org.onosproject.pcepio.types.SrEroSubObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP Ero Object.
- */
-public class PcepEroObjectVer1 implements PcepEroObject {
-    /*
-     * rfc3209
-      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)       |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                                                               |
-     //                        (Subobjects)                          //
-     |                                                               |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     If a Path message contains multiple EXPLICIT_ROUTE objects, only the
-     first object is meaningful.  Subsequent EXPLICIT_ROUTE objects MAY be
-     ignored and SHOULD NOT be propagated.
-
-     In current implementation, only strict hops are supported. So,
-     empty ERO with no sub-objects is considered illegal.
-
-     Subobjects:
-      0                   1
-      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
-     |L|    Type     |     Length    | (Subobject contents)          |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
-
-      L
-
-         The L bit is an attribute of the subobject.  The L bit is set
-         if the subobject represents a loose hop in the explicit route.
-         If the bit is not set, the subobject represents a strict hop in
-         the explicit route.
-
-      Type
-
-         The Type indicates the type of contents of the subobject.
-
-
-      Subobject 1: IPv4 address
-
-      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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |L|    Type     |     Length    | IPv4 address (4 bytes)        |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     | IPv4 address (continued)      | Prefix Length |      Resvd    |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     Subobject 2:  IPv6 Prefix
-
-      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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |L|    Type     |     Length    | IPv6 address (16 bytes)       |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     | IPv6 address (continued)                                      |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     | IPv6 address (continued)                                      |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     | IPv6 address (continued)                                      |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     | IPv6 address (continued)      | Prefix Length |      Resvd    |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     Subobject 3:  Autonomous System Number
-
-     The contents of an Autonomous System (AS) number subobject are a 2-
-     octet AS number.  The abstract node represented by this subobject is
-     the set of nodes belonging to the autonomous system.
-
-     The length of the AS number subobject is 4 octets.
-
-     Subobject 4: PATH_KEY_32_BIT_SUB_OBJ_TYPE:
-
-      Pathkey subobject(RFC 5520):
-      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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |L|    Type     |     Length    |           Path-Key            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                         PCE ID (4 bytes)                      |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     Subobject 5: SR_ERO_SUB_OBJ_TYPE:
-
-       SR-ERO subobject: (draft-ietf-pce-segment-routing-00)
-      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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |L|    Type     |     Length    |  ST   |     Flags     |F|S|C|M|
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                              SID                              |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //                        NAI (variable)                       //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepEroObjectVer1.class);
-
-    public static final byte ERO_OBJ_TYPE = 1;
-    public static final byte ERO_OBJ_CLASS = 7;
-    public static final byte ERO_OBJECT_VERSION = 1;
-    public static final short ERO_OBJ_MINIMUM_LENGTH = 12;
-    public static final byte IPV4_TYPE = 1;
-    public static final byte PATH_KEY_32_BIT_SUB_OBJ_TYPE = 64;
-    public static final int LABEL_SUB_OBJ_TYPE = 3;
-    public static final int SR_ERO_SUB_OBJ_TYPE = 96;
-    public static final int OBJECT_HEADER_LENGTH = 4;
-    public static final int YTYPE_SHIFT_VALUE = 0x7F;
-
-    static final PcepObjectHeader DEFAULT_ERO_OBJECT_HEADER = new PcepObjectHeader(ERO_OBJ_CLASS, ERO_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, ERO_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader eroObjHeader;
-    private LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
-
-    /**
-     * reset variables.
-     */
-    public PcepEroObjectVer1() {
-        this.eroObjHeader = null;
-        this.llSubObjects = null;
-    }
-
-    /**
-     * Constructor to initialize parameters of ERO object.
-     *
-     * @param eroObjHeader ERO object header
-     * @param llSubObjects list of sub objects.
-     */
-    public PcepEroObjectVer1(PcepObjectHeader eroObjHeader, LinkedList<PcepValueType> llSubObjects) {
-
-        this.eroObjHeader = eroObjHeader;
-        this.llSubObjects = llSubObjects;
-    }
-
-    /**
-     * Returns ERO object header.
-     *
-     * @return eroObjHeader ERO object header
-     */
-    public PcepObjectHeader getEroObjHeader() {
-        return this.eroObjHeader;
-    }
-
-    /**
-     * Sets Object Header.
-     *
-     * @param obj ERO object header
-     */
-    public void setEroObjHeader(PcepObjectHeader obj) {
-        this.eroObjHeader = obj;
-    }
-
-    @Override
-    public LinkedList<PcepValueType> getSubObjects() {
-        return this.llSubObjects;
-    }
-
-    @Override
-    public void setSubObjects(LinkedList<PcepValueType> llSubObjects) {
-        this.llSubObjects = llSubObjects;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of PcepEroObject.
-     *
-     * @param cb channel buffer.
-     * @return  object of PcepEroObject
-     * @throws PcepParseException when ERO object is not present in channel buffer
-     */
-    public static PcepEroObject read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader eroObjHeader;
-        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
-
-        eroObjHeader = PcepObjectHeader.read(cb);
-
-        if (eroObjHeader.getObjClass() != PcepEroObjectVer1.ERO_OBJ_CLASS) {
-            log.debug("ErrorType:" + PcepErrorDetailInfo.ERROR_TYPE_6 + " ErrorValue:"
-                    + PcepErrorDetailInfo.ERROR_VALUE_9);
-            throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_6, PcepErrorDetailInfo.ERROR_VALUE_9);
-        }
-
-        if (eroObjHeader.getObjLen() > OBJECT_HEADER_LENGTH) {
-            ChannelBuffer tempCb = cb.readBytes(eroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
-            llSubObjects = parseSubObjects(tempCb);
-        }
-        return new PcepEroObjectVer1(eroObjHeader, llSubObjects);
-    }
-
-    /**
-     * Parse list of Sub Objects.
-     *
-     * @param cb channel buffer
-     * @return list of Sub Objects
-     * @throws PcepParseException when fails to parse sub object list
-     */
-    protected static LinkedList<PcepValueType> parseSubObjects(ChannelBuffer cb) throws PcepParseException {
-
-        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
-
-        while (0 < cb.readableBytes()) {
-
-            //check the Type of the TLV
-            byte yType = cb.readByte();
-            yType = (byte) (yType & (YTYPE_SHIFT_VALUE));
-            byte hLength = cb.readByte();
-
-            PcepValueType subObj;
-
-            switch (yType) {
-
-            case IPv4SubObject.TYPE:
-                subObj = IPv4SubObject.read(cb);
-                break;
-            case IPv6SubObject.TYPE:
-                byte[] ipv6Value = new byte[IPv6SubObject.VALUE_LENGTH];
-                cb.readBytes(ipv6Value, 0, IPv6SubObject.VALUE_LENGTH);
-                subObj = new IPv6SubObject(ipv6Value);
-                break;
-            case AutonomousSystemTlv.TYPE:
-                subObj = AutonomousSystemTlv.read(cb);
-                break;
-            case PathKeySubObject.TYPE:
-                subObj = PathKeySubObject.read(cb);
-                break;
-            case SrEroSubObject.TYPE:
-                subObj = SrEroSubObject.read(cb);
-                break;
-            default:
-                throw new PcepParseException("Unexpected sub object. Type: " + (int) yType);
-            }
-            // Check for the padding
-            int pad = hLength % 4;
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= cb.readableBytes()) {
-                    cb.skipBytes(pad);
-                }
-            }
-
-            llSubObjects.add(subObj);
-        }
-        if (0 < cb.readableBytes()) {
-            throw new PcepParseException("Subobject parsing error. Extra bytes received.");
-        }
-        return llSubObjects;
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        //write Object header
-        int objStartIndex = cb.writerIndex();
-
-        int objLenIndex = eroObjHeader.write(cb);
-
-        if (objLenIndex <= 0) {
-            throw new PcepParseException("Failed to write ERO object header. Index " + objLenIndex);
-        }
-
-        ListIterator<PcepValueType> listIterator = llSubObjects.listIterator();
-
-        while (listIterator.hasNext()) {
-            listIterator.next().write(cb);
-        }
-
-        //Update object length now
-        int length = cb.writerIndex() - objStartIndex;
-        cb.setShort(objLenIndex, (short) length);
-        //will be helpful during print().
-        eroObjHeader.setObjLen((short) length);
-
-        //As per RFC the length of object should be multiples of 4
-        int pad = length % 4;
-
-        if (pad != 0) {
-            pad = 4 - pad;
-            for (int i = 0; i < pad; i++) {
-                cb.writeByte((byte) 0);
-            }
-            length = length + pad;
-        }
-
-        objLenIndex = cb.writerIndex();
-        return objLenIndex;
-    }
-
-    /**
-     * Builder class for PCEP ERO object.
-     */
-    public static class Builder implements PcepEroObject.Builder {
-
-        private boolean bIsHeaderSet = false;
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        private PcepObjectHeader eroObjHeader;
-        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
-
-        @Override
-        public PcepEroObject build() {
-
-            PcepObjectHeader eroObjHeader = this.bIsHeaderSet ? this.eroObjHeader : DEFAULT_ERO_OBJECT_HEADER;
-
-            if (bIsPFlagSet) {
-                eroObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                eroObjHeader.setIFlag(bIFlag);
-            }
-
-            return new PcepEroObjectVer1(eroObjHeader, this.llSubObjects);
-        }
-
-        @Override
-        public PcepObjectHeader getEroObjHeader() {
-            return this.eroObjHeader;
-        }
-
-        @Override
-        public Builder setEroObjHeader(PcepObjectHeader obj) {
-            this.eroObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public LinkedList<PcepValueType> getSubObjects() {
-            return this.llSubObjects;
-        }
-
-        @Override
-        public Builder setSubObjects(LinkedList<PcepValueType> llSubObjects) {
-            this.llSubObjects = llSubObjects;
-            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("EroObjHeader", eroObjHeader).add("SubObjects", llSubObjects)
-                .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.PcepEroObject;
+import org.onosproject.pcepio.types.AutonomousSystemTlv;
+import org.onosproject.pcepio.types.IPv4SubObject;
+import org.onosproject.pcepio.types.IPv6SubObject;
+import org.onosproject.pcepio.types.PathKeySubObject;
+import org.onosproject.pcepio.types.PcepErrorDetailInfo;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.onosproject.pcepio.types.PcepValueType;
+import org.onosproject.pcepio.types.SrEroSubObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP Ero Object.
+ */
+public class PcepEroObjectVer1 implements PcepEroObject {
+    /*
+     * rfc3209
+      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)       |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                                                               |
+     //                        (Subobjects)                          //
+     |                                                               |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     If a Path message contains multiple EXPLICIT_ROUTE objects, only the
+     first object is meaningful.  Subsequent EXPLICIT_ROUTE objects MAY be
+     ignored and SHOULD NOT be propagated.
+
+     In current implementation, only strict hops are supported. So,
+     empty ERO with no sub-objects is considered illegal.
+
+     Subobjects:
+      0                   1
+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
+     |L|    Type     |     Length    | (Subobject contents)          |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------//----------------+
+
+      L
+
+         The L bit is an attribute of the subobject.  The L bit is set
+         if the subobject represents a loose hop in the explicit route.
+         If the bit is not set, the subobject represents a strict hop in
+         the explicit route.
+
+      Type
+
+         The Type indicates the type of contents of the subobject.
+
+
+      Subobject 1: IPv4 address
+
+      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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |L|    Type     |     Length    | IPv4 address (4 bytes)        |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     | IPv4 address (continued)      | Prefix Length |      Resvd    |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     Subobject 2:  IPv6 Prefix
+
+      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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |L|    Type     |     Length    | IPv6 address (16 bytes)       |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     | IPv6 address (continued)                                      |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     | IPv6 address (continued)                                      |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     | IPv6 address (continued)                                      |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     | IPv6 address (continued)      | Prefix Length |      Resvd    |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     Subobject 3:  Autonomous System Number
+
+     The contents of an Autonomous System (AS) number subobject are a 2-
+     octet AS number.  The abstract node represented by this subobject is
+     the set of nodes belonging to the autonomous system.
+
+     The length of the AS number subobject is 4 octets.
+
+     Subobject 4: PATH_KEY_32_BIT_SUB_OBJ_TYPE:
+
+      Pathkey subobject(RFC 5520):
+      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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |L|    Type     |     Length    |           Path-Key            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                         PCE ID (4 bytes)                      |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     Subobject 5: SR_ERO_SUB_OBJ_TYPE:
+
+       SR-ERO subobject: (draft-ietf-pce-segment-routing-00)
+      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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |L|    Type     |     Length    |  ST   |     Flags     |F|S|C|M|
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                              SID                              |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //                        NAI (variable)                       //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepEroObjectVer1.class);
+
+    public static final byte ERO_OBJ_TYPE = 1;
+    public static final byte ERO_OBJ_CLASS = 7;
+    public static final byte ERO_OBJECT_VERSION = 1;
+    public static final short ERO_OBJ_MINIMUM_LENGTH = 12;
+    public static final byte IPV4_TYPE = 1;
+    public static final byte PATH_KEY_32_BIT_SUB_OBJ_TYPE = 64;
+    public static final int LABEL_SUB_OBJ_TYPE = 3;
+    public static final int SR_ERO_SUB_OBJ_TYPE = 96;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+    public static final int YTYPE_SHIFT_VALUE = 0x7F;
+
+    static final PcepObjectHeader DEFAULT_ERO_OBJECT_HEADER = new PcepObjectHeader(ERO_OBJ_CLASS, ERO_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, ERO_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader eroObjHeader;
+    private LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+    /**
+     * reset variables.
+     */
+    public PcepEroObjectVer1() {
+        this.eroObjHeader = null;
+        this.llSubObjects = null;
+    }
+
+    /**
+     * Constructor to initialize parameters of ERO object.
+     *
+     * @param eroObjHeader ERO object header
+     * @param llSubObjects list of sub objects.
+     */
+    public PcepEroObjectVer1(PcepObjectHeader eroObjHeader, LinkedList<PcepValueType> llSubObjects) {
+
+        this.eroObjHeader = eroObjHeader;
+        this.llSubObjects = llSubObjects;
+    }
+
+    /**
+     * Returns ERO object header.
+     *
+     * @return eroObjHeader ERO object header
+     */
+    public PcepObjectHeader getEroObjHeader() {
+        return this.eroObjHeader;
+    }
+
+    /**
+     * Sets Object Header.
+     *
+     * @param obj ERO object header
+     */
+    public void setEroObjHeader(PcepObjectHeader obj) {
+        this.eroObjHeader = obj;
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getSubObjects() {
+        return this.llSubObjects;
+    }
+
+    @Override
+    public void setSubObjects(LinkedList<PcepValueType> llSubObjects) {
+        this.llSubObjects = llSubObjects;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of PcepEroObject.
+     *
+     * @param cb channel buffer.
+     * @return  object of PcepEroObject
+     * @throws PcepParseException when ERO object is not present in channel buffer
+     */
+    public static PcepEroObject read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader eroObjHeader;
+        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+        eroObjHeader = PcepObjectHeader.read(cb);
+
+        if (eroObjHeader.getObjClass() != PcepEroObjectVer1.ERO_OBJ_CLASS) {
+            log.debug("ErrorType:" + PcepErrorDetailInfo.ERROR_TYPE_6 + " ErrorValue:"
+                    + PcepErrorDetailInfo.ERROR_VALUE_9);
+            throw new PcepParseException(PcepErrorDetailInfo.ERROR_TYPE_6, PcepErrorDetailInfo.ERROR_VALUE_9);
+        }
+
+        if (eroObjHeader.getObjLen() > OBJECT_HEADER_LENGTH) {
+            ChannelBuffer tempCb = cb.readBytes(eroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+            llSubObjects = parseSubObjects(tempCb);
+        }
+        return new PcepEroObjectVer1(eroObjHeader, llSubObjects);
+    }
+
+    /**
+     * Parse list of Sub Objects.
+     *
+     * @param cb channel buffer
+     * @return list of Sub Objects
+     * @throws PcepParseException when fails to parse sub object list
+     */
+    protected static LinkedList<PcepValueType> parseSubObjects(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+        while (0 < cb.readableBytes()) {
+
+            //check the Type of the TLV
+            byte yType = cb.readByte();
+            yType = (byte) (yType & (YTYPE_SHIFT_VALUE));
+            byte hLength = cb.readByte();
+
+            PcepValueType subObj;
+
+            switch (yType) {
+
+            case IPv4SubObject.TYPE:
+                subObj = IPv4SubObject.read(cb);
+                break;
+            case IPv6SubObject.TYPE:
+                byte[] ipv6Value = new byte[IPv6SubObject.VALUE_LENGTH];
+                cb.readBytes(ipv6Value, 0, IPv6SubObject.VALUE_LENGTH);
+                subObj = new IPv6SubObject(ipv6Value);
+                break;
+            case AutonomousSystemTlv.TYPE:
+                subObj = AutonomousSystemTlv.read(cb);
+                break;
+            case PathKeySubObject.TYPE:
+                subObj = PathKeySubObject.read(cb);
+                break;
+            case SrEroSubObject.TYPE:
+                subObj = SrEroSubObject.read(cb);
+                break;
+            default:
+                throw new PcepParseException("Unexpected sub object. Type: " + (int) yType);
+            }
+            // Check for the padding
+            int pad = hLength % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= cb.readableBytes()) {
+                    cb.skipBytes(pad);
+                }
+            }
+
+            llSubObjects.add(subObj);
+        }
+        if (0 < cb.readableBytes()) {
+            throw new PcepParseException("Subobject parsing error. Extra bytes received.");
+        }
+        return llSubObjects;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        int objLenIndex = eroObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("Failed to write ERO object header. Index " + objLenIndex);
+        }
+
+        ListIterator<PcepValueType> listIterator = llSubObjects.listIterator();
+
+        while (listIterator.hasNext()) {
+            listIterator.next().write(cb);
+        }
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+        cb.setShort(objLenIndex, (short) length);
+        //will be helpful during print().
+        eroObjHeader.setObjLen((short) length);
+
+        //As per RFC the length of object should be multiples of 4
+        int pad = length % 4;
+
+        if (pad != 0) {
+            pad = 4 - pad;
+            for (int i = 0; i < pad; i++) {
+                cb.writeByte((byte) 0);
+            }
+            length = length + pad;
+        }
+
+        objLenIndex = cb.writerIndex();
+        return objLenIndex;
+    }
+
+    /**
+     * Builder class for PCEP ERO object.
+     */
+    public static class Builder implements PcepEroObject.Builder {
+
+        private boolean bIsHeaderSet = false;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        private PcepObjectHeader eroObjHeader;
+        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+        @Override
+        public PcepEroObject build() {
+
+            PcepObjectHeader eroObjHeader = this.bIsHeaderSet ? this.eroObjHeader : DEFAULT_ERO_OBJECT_HEADER;
+
+            if (bIsPFlagSet) {
+                eroObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                eroObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepEroObjectVer1(eroObjHeader, this.llSubObjects);
+        }
+
+        @Override
+        public PcepObjectHeader getEroObjHeader() {
+            return this.eroObjHeader;
+        }
+
+        @Override
+        public Builder setEroObjHeader(PcepObjectHeader obj) {
+            this.eroObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepValueType> getSubObjects() {
+            return this.llSubObjects;
+        }
+
+        @Override
+        public Builder setSubObjects(LinkedList<PcepValueType> llSubObjects) {
+            this.llSubObjects = llSubObjects;
+            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("EroObjHeader", eroObjHeader).add("SubObjects", llSubObjects)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java
index e22f7a9..a666afe 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorInfoVer1.java
@@ -1,203 +1,203 @@
-/*
- * 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.PcepError;
-import org.onosproject.pcepio.protocol.PcepErrorInfo;
-import org.onosproject.pcepio.protocol.PcepErrorObject;
-import org.onosproject.pcepio.protocol.PcepRPObject;
-import org.onosproject.pcepio.protocol.PcepTEObject;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP Error Info.
- * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
- */
-public class PcepErrorInfoVer1 implements PcepErrorInfo {
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepErrorInfoVer1.class);
-    //Error list is optional
-    private LinkedList<PcepError> errList;
-
-    /**
-     * Constructor to add PCEP error object to the list.
-     *
-     * @param llRPObjList list of PCEP RP object
-     * @param llTEObjList list of PCEP TE object
-     * @param llErrObjList list of PCEP error object
-     */
-    public PcepErrorInfoVer1(LinkedList<PcepRPObject> llRPObjList, LinkedList<PcepTEObject> llTEObjList,
-            LinkedList<PcepErrorObject> llErrObjList) {
-        this.errList = new LinkedList<PcepError>();
-        if ((null != llErrObjList) && (!llErrObjList.isEmpty())) {
-            this.errList.add(new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList));
-        }
-    }
-
-    /**
-     * Constructor to initialize error info.
-     *
-     * @param errll linked list or pcep error
-     */
-    public PcepErrorInfoVer1(LinkedList<PcepError> errll) {
-        this.errList = errll;
-    }
-
-    @Override
-    public boolean isErrorInfoPresent() {
-        return (!this.errList.isEmpty()) ? true : false;
-    }
-
-    @Override
-    public void read(ChannelBuffer cb) throws PcepParseException {
-        PcepObjectHeader tempObjHeader;
-
-        while (0 < cb.readableBytes()) {
-            cb.markReaderIndex();
-            tempObjHeader = PcepObjectHeader.read(cb);
-            cb.resetReaderIndex();
-            byte yObjClass = tempObjHeader.getObjClass();
-            if ((yObjClass != PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjClass != PcepTEObjectVer1.TE_OBJ_CLASS)
-                    && (yObjClass != PcepErrorObjectVer1.ERROR_OBJ_CLASS)) {
-                throw new PcepParseException("Unknown Object is present in PCEP-ERROR. Object Class: " + yObjClass);
-            }
-
-            this.errList.add(PcepErrorVer1.read(cb));
-        }
-    }
-
-    @Override
-    public void write(ChannelBuffer cb) throws PcepParseException {
-        //write <error>
-        ListIterator<PcepError> listIterator = errList.listIterator();
-        while (listIterator.hasNext()) {
-            PcepError pcepError = listIterator.next();
-
-            //RP Object list is optional
-            LinkedList<PcepRPObject> llRPObjList = pcepError.getRPObjList();
-            if (llRPObjList != null) {
-                ListIterator<PcepRPObject> rpListIterator = llRPObjList.listIterator();
-                while (rpListIterator.hasNext()) {
-                    rpListIterator.next().write(cb);
-                }
-            }
-
-            //TE Object list is optional
-            LinkedList<PcepTEObject> llTEObjList = pcepError.getTEObjList();
-            if (llTEObjList != null) {
-                ListIterator<PcepTEObject> teListIterator = llTEObjList.listIterator();
-                while (teListIterator.hasNext()) {
-                    teListIterator.next().write(cb);
-                }
-            }
-
-            // <error-obj-list> is mandatory
-            boolean bIsErrorObjListFound = false;
-
-            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
-            if (llErrObjList != null) {
-                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
-                while (errObjListIterator.hasNext()) {
-                    errObjListIterator.next().write(cb);
-                    bIsErrorObjListFound = true;
-                }
-            }
-
-            if (!bIsErrorObjListFound) {
-                throw new PcepParseException("<error-obj-list> is mandatory.");
-            }
-        }
-    }
-
-    @Override
-    public LinkedList<Integer> getErrorType() {
-        LinkedList<Integer> errorType = new LinkedList<Integer>();
-        ListIterator<PcepError> listIterator = errList.listIterator();
-        PcepErrorObject errObj;
-        int error;
-        while (listIterator.hasNext()) {
-            PcepError pcepError = listIterator.next();
-            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
-            if (llErrObjList != null) {
-                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
-                while (errObjListIterator.hasNext()) {
-                    errObj = errObjListIterator.next();
-                    error = errObj.getErrorType();
-                    errorType.add(error);
-                }
-            }
-        }
-        return errorType;
-    }
-
-    @Override
-    public LinkedList<Integer> getErrorValue() {
-        LinkedList<Integer> errorValue = new LinkedList<Integer>();
-        ListIterator<PcepError> listIterator = errList.listIterator();
-        PcepErrorObject errObj;
-        int error;
-        while (listIterator.hasNext()) {
-            PcepError pcepError = listIterator.next();
-            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
-            if (llErrObjList != null) {
-                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
-                while (errObjListIterator.hasNext()) {
-                    errObj = errObjListIterator.next();
-                    error = errObj.getErrorValue();
-                    errorValue.add(error);
-                }
-            }
-        }
-        return errorValue;
-    }
-
-    /**
-     * Builder class for PCEP error info.
-     */
-    public static class Builder implements PcepErrorInfo.Builder {
-        private LinkedList<PcepError> errll;
-
-        @Override
-        public PcepErrorInfo build() {
-            return new PcepErrorInfoVer1(errll);
-        }
-
-        @Override
-        public LinkedList<PcepError> getPcepErrorList() {
-            return this.errll;
-        }
-
-        @Override
-        public Builder setPcepErrorList(LinkedList<PcepError> errll) {
-            this.errll = errll;
-            return this;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("ErrorList", errList).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.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepRPObject;
+import org.onosproject.pcepio.protocol.PcepTEObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP Error Info.
+ * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
+ */
+public class PcepErrorInfoVer1 implements PcepErrorInfo {
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepErrorInfoVer1.class);
+    //Error list is optional
+    private LinkedList<PcepError> errList;
+
+    /**
+     * Constructor to add PCEP error object to the list.
+     *
+     * @param llRPObjList list of PCEP RP object
+     * @param llTEObjList list of PCEP TE object
+     * @param llErrObjList list of PCEP error object
+     */
+    public PcepErrorInfoVer1(LinkedList<PcepRPObject> llRPObjList, LinkedList<PcepTEObject> llTEObjList,
+            LinkedList<PcepErrorObject> llErrObjList) {
+        this.errList = new LinkedList<PcepError>();
+        if ((null != llErrObjList) && (!llErrObjList.isEmpty())) {
+            this.errList.add(new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList));
+        }
+    }
+
+    /**
+     * Constructor to initialize error info.
+     *
+     * @param errll linked list or pcep error
+     */
+    public PcepErrorInfoVer1(LinkedList<PcepError> errll) {
+        this.errList = errll;
+    }
+
+    @Override
+    public boolean isErrorInfoPresent() {
+        return (!this.errList.isEmpty()) ? true : false;
+    }
+
+    @Override
+    public void read(ChannelBuffer cb) throws PcepParseException {
+        PcepObjectHeader tempObjHeader;
+
+        while (0 < cb.readableBytes()) {
+            cb.markReaderIndex();
+            tempObjHeader = PcepObjectHeader.read(cb);
+            cb.resetReaderIndex();
+            byte yObjClass = tempObjHeader.getObjClass();
+            if ((yObjClass != PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjClass != PcepTEObjectVer1.TE_OBJ_CLASS)
+                    && (yObjClass != PcepErrorObjectVer1.ERROR_OBJ_CLASS)) {
+                throw new PcepParseException("Unknown Object is present in PCEP-ERROR. Object Class: " + yObjClass);
+            }
+
+            this.errList.add(PcepErrorVer1.read(cb));
+        }
+    }
+
+    @Override
+    public void write(ChannelBuffer cb) throws PcepParseException {
+        //write <error>
+        ListIterator<PcepError> listIterator = errList.listIterator();
+        while (listIterator.hasNext()) {
+            PcepError pcepError = listIterator.next();
+
+            //RP Object list is optional
+            LinkedList<PcepRPObject> llRPObjList = pcepError.getRPObjList();
+            if (llRPObjList != null) {
+                ListIterator<PcepRPObject> rpListIterator = llRPObjList.listIterator();
+                while (rpListIterator.hasNext()) {
+                    rpListIterator.next().write(cb);
+                }
+            }
+
+            //TE Object list is optional
+            LinkedList<PcepTEObject> llTEObjList = pcepError.getTEObjList();
+            if (llTEObjList != null) {
+                ListIterator<PcepTEObject> teListIterator = llTEObjList.listIterator();
+                while (teListIterator.hasNext()) {
+                    teListIterator.next().write(cb);
+                }
+            }
+
+            // <error-obj-list> is mandatory
+            boolean bIsErrorObjListFound = false;
+
+            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
+            if (llErrObjList != null) {
+                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
+                while (errObjListIterator.hasNext()) {
+                    errObjListIterator.next().write(cb);
+                    bIsErrorObjListFound = true;
+                }
+            }
+
+            if (!bIsErrorObjListFound) {
+                throw new PcepParseException("<error-obj-list> is mandatory.");
+            }
+        }
+    }
+
+    @Override
+    public LinkedList<Integer> getErrorType() {
+        LinkedList<Integer> errorType = new LinkedList<Integer>();
+        ListIterator<PcepError> listIterator = errList.listIterator();
+        PcepErrorObject errObj;
+        int error;
+        while (listIterator.hasNext()) {
+            PcepError pcepError = listIterator.next();
+            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
+            if (llErrObjList != null) {
+                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
+                while (errObjListIterator.hasNext()) {
+                    errObj = errObjListIterator.next();
+                    error = errObj.getErrorType();
+                    errorType.add(error);
+                }
+            }
+        }
+        return errorType;
+    }
+
+    @Override
+    public LinkedList<Integer> getErrorValue() {
+        LinkedList<Integer> errorValue = new LinkedList<Integer>();
+        ListIterator<PcepError> listIterator = errList.listIterator();
+        PcepErrorObject errObj;
+        int error;
+        while (listIterator.hasNext()) {
+            PcepError pcepError = listIterator.next();
+            LinkedList<PcepErrorObject> llErrObjList = pcepError.getErrorObjList();
+            if (llErrObjList != null) {
+                ListIterator<PcepErrorObject> errObjListIterator = llErrObjList.listIterator();
+                while (errObjListIterator.hasNext()) {
+                    errObj = errObjListIterator.next();
+                    error = errObj.getErrorValue();
+                    errorValue.add(error);
+                }
+            }
+        }
+        return errorValue;
+    }
+
+    /**
+     * Builder class for PCEP error info.
+     */
+    public static class Builder implements PcepErrorInfo.Builder {
+        private LinkedList<PcepError> errll;
+
+        @Override
+        public PcepErrorInfo build() {
+            return new PcepErrorInfoVer1(errll);
+        }
+
+        @Override
+        public LinkedList<PcepError> getPcepErrorList() {
+            return this.errll;
+        }
+
+        @Override
+        public Builder setPcepErrorList(LinkedList<PcepError> errll) {
+            this.errll = errll;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("ErrorList", errList).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java
index af5dc81..2326804 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorMsgVer1.java
@@ -1,368 +1,368 @@
-package org.onosproject.pcepio.protocol.ver1;
-
-import java.util.LinkedList;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepErrorInfo;
-import org.onosproject.pcepio.protocol.PcepErrorMsg;
-import org.onosproject.pcepio.protocol.PcepErrorObject;
-import org.onosproject.pcepio.protocol.PcepMessageReader;
-import org.onosproject.pcepio.protocol.PcepMessageWriter;
-import org.onosproject.pcepio.protocol.PcepOpenObject;
-import org.onosproject.pcepio.protocol.PcepType;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.onosproject.pcepio.types.ErrorObjListWithOpen;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides PCEP Error Message.
- */
-public class PcepErrorMsgVer1 implements PcepErrorMsg {
-
-    /*
-     * PCE Error message format.
-
-       <PCErr Message>                ::= <Common Header>
-                                        ( <error-obj-list> [<Open>] ) | <error>
-                                          [<error-list>]
-
-       <error-obj-list>               ::=<PCEP-ERROR>[<error-obj-list>]
-
-       <error>                        ::=[<request-id-list> | <te-id-list>]
-                                           <error-obj-list>
-
-       <request-id-list>              ::=<RP>[<request-id-list>]
-
-       <te-id-list>                   ::=<TE>[<te-id-list>]
-
-       <error-list>                   ::=<error>[<error-list>]
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class);
-    public static final byte PACKET_VERSION = 1;
-    public static final int PACKET_MINIMUM_LENGTH = 12;
-    public static final PcepType MSG_TYPE = PcepType.ERROR;
-
-    //Below either one should be present.
-    private ErrorObjListWithOpen errObjListWithOpen; //optional   ( <error-obj-list> [<Open>] )
-    private PcepErrorInfo errInfo; //optional     <error> [<error-list>]
-
-    public static final PcepErrorMsgVer1.Reader READER = new Reader();
-
-    /**
-     * constructor to initialize variables.
-     */
-    public PcepErrorMsgVer1() {
-        errObjListWithOpen = null;
-        errInfo = null;
-    }
-
-    /**
-     * Constructor to initialize variables.
-     *
-     * @param errObjListWithOpen error-object-list with open object
-     * @param errInfo error information
-     */
-    public PcepErrorMsgVer1(ErrorObjListWithOpen errObjListWithOpen, PcepErrorInfo errInfo) {
-        this.errObjListWithOpen = errObjListWithOpen;
-        this.errInfo = errInfo;
-    }
-
-    /**
-     * Reader class for reading PCEP error Message from channel buffer.
-     */
-    public static class Reader implements PcepMessageReader<PcepErrorMsg> {
-
-        ErrorObjListWithOpen errObjListWithOpen;
-        PcepErrorInfo errInfo;
-        PcepObjectHeader tempObjHeader;
-
-        @Override
-        public PcepErrorMsg readFrom(ChannelBuffer cb) throws PcepParseException {
-
-            errObjListWithOpen = null;
-            errInfo = null;
-            tempObjHeader = null;
-
-            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
-                throw new PcepParseException("Packet size is less than the minimum length.");
-            }
-
-            byte version = cb.readByte();
-            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
-            if (version != PACKET_VERSION) {
-                throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
-            }
-            // fixed value property type == 1
-            byte type = cb.readByte();
-            if (type != MSG_TYPE.getType()) {
-                throw new PcepParseException("Wrong type: Expected=PcepType.ERROR(6), got=" + type);
-            }
-            int length = cb.readShort();
-            if (length < PACKET_MINIMUM_LENGTH) {
-                throw new PcepParseException(
-                        "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length);
-            }
-
-            //parse <PCErr Message>
-            parsePCErrMsg(cb);
-
-            // If other than RP or TE or PCEP-ERROR present then it is error.
-            if (0 < cb.readableBytes()) {
-                PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-                throw new PcepParseException("Unexpected Object found. Object Class : " + tempObjHeader.getObjClass());
-            }
-
-            return new PcepErrorMsgVer1(errObjListWithOpen, errInfo);
-        }
-
-        /**
-         * Parsing PCErr Message.
-         *
-         * @param cb channel buffer.
-         * @throws PcepParseException if mandatory fields are missing
-         * output: this.errObjListWithOpen, this.errInfo
-         */
-        public void parsePCErrMsg(ChannelBuffer cb) throws PcepParseException {
-            //If PCEP-ERROR list is followed by OPEN Object then store into ErrorObjListWithOpen.
-            //     ( <error-obj-list> [<Open>]
-            //If PCEP-ERROR list is followed by RP or TE Object then store into errInfo. <error> [<error-list>]
-            //If only PCEP-ERROR list is present then store into ErrorObjListWithOpen.
-            PcepObjectHeader tempObjHeader;
-            LinkedList<PcepErrorObject> llErrObjList;
-
-            if (0 >= cb.readableBytes()) {
-                throw new PcepParseException("PCEP-ERROR message came with empty objects.");
-            }
-
-            //parse PCEP-ERROR list
-            llErrObjList = new LinkedList<PcepErrorObject>();
-            tempObjHeader = parseErrorObjectList(llErrObjList, cb);
-
-            //check whether OPEN-OBJECT is present.
-            if ((tempObjHeader instanceof PcepObjectHeader)
-                    && (tempObjHeader.getObjClass() == PcepOpenObjectVer1.OPEN_OBJ_CLASS)) {
-
-                if (llErrObjList.isEmpty()) {
-                    throw new PcepParseException("<error-obj-list> should be present if OPEN-OBJECT exists");
-                }
-
-                PcepOpenObject pcepOpenObj = PcepOpenObjectVer1.read(cb);
-                this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList, pcepOpenObj);
-
-            } else if ((tempObjHeader instanceof PcepObjectHeader) //check whether RP or TE Object is present.
-                    && ((tempObjHeader.getObjClass() == PcepRPObjectVer1.RP_OBJ_CLASS)
-                            || (tempObjHeader.getObjClass() == PcepTEObjectVer1.TE_OBJ_CLASS))) {
-
-                this.errInfo = new PcepErrorInfoVer1(null, null, llErrObjList);
-                this.errInfo.read(cb);
-
-            } else if ((null != llErrObjList) && (!llErrObjList.isEmpty())) {
-                //If only PCEP-ERROR list is present then store it in errObjListWithOpen.
-                this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList);
-            } else {
-                throw new PcepParseException("Empty PCEP-ERROR message.");
-            }
-        }
-
-        /**
-         * Parse error-obj-list.
-         *
-         * @param llErrObjList error object list output
-         * @param cb channel buffer input
-         * @throws PcepParseException if mandatory fields are missing
-         * @return error object header
-         */
-        public PcepObjectHeader parseErrorObjectList(LinkedList<PcepErrorObject> llErrObjList, ChannelBuffer cb)
-                throws PcepParseException {
-            PcepObjectHeader tempObjHeader = null;
-
-            while (0 < cb.readableBytes()) {
-                cb.markReaderIndex();
-                tempObjHeader = PcepObjectHeader.read(cb);
-                cb.resetReaderIndex();
-                if (tempObjHeader.getObjClass() == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
-                    llErrObjList.add(PcepErrorObjectVer1.read(cb));
-                } else {
-                    break;
-                }
-            }
-            return tempObjHeader;
-        }
-    }
-
-    /**
-     * Builder class for PCEP error message.
-     */
-    public static class Builder implements PcepErrorMsg.Builder {
-        // Pcep error message fields
-
-        private ErrorObjListWithOpen errObjListWithOpen = null; //optional   ( <error-obj-list> [<Open>] )
-        private PcepErrorInfo errInfo = null; //optional     <error> [<error-list>]
-
-        @Override
-        public PcepVersion getVersion() {
-            return PcepVersion.PCEP_1;
-        }
-
-        @Override
-        public PcepType getType() {
-            return PcepType.ERROR;
-        }
-
-        @Override
-        public PcepErrorMsg build() {
-            return new PcepErrorMsgVer1(this.errObjListWithOpen, this.errInfo);
-        }
-
-        @Override
-        public ErrorObjListWithOpen getErrorObjListWithOpen() {
-            return this.errObjListWithOpen;
-        }
-
-        @Override
-        public Builder setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
-            this.errObjListWithOpen = errObjListWithOpen;
-            return this;
-        }
-
-        @Override
-        public PcepErrorInfo getPcepErrorInfo() {
-            return this.errInfo;
-        }
-
-        @Override
-        public Builder setPcepErrorInfo(PcepErrorInfo errInfo) {
-            this.errInfo = errInfo;
-            return this;
-        }
-    }
-
-    @Override
-    public void writeTo(ChannelBuffer cb) throws PcepParseException {
-        WRITER.write(cb, this);
-    }
-
-    public static final Writer WRITER = new Writer();
-
-    /**
-     * Writer class for writing PCEP error Message to channel buffer.
-     */
-    static class Writer implements PcepMessageWriter<PcepErrorMsgVer1> {
-        @Override
-        public void write(ChannelBuffer cb, PcepErrorMsgVer1 message) throws PcepParseException {
-            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);
-            ErrorObjListWithOpen errObjListWithOpen = message.getErrorObjListWithOpen();
-            PcepErrorInfo errInfo = message.getPcepErrorInfo();
-
-            // write ( <error-obj-list> [<Open>] ) if exists.
-            // otherwise write <error> [<error-list>]
-
-            if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
-                    && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
-                errObjListWithOpen.write(cb);
-            } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
-                errInfo.write(cb);
-            } else {
-                throw new PcepParseException("Empty PCEP-ERROR message.");
-            }
-            // PcepErrorMessage 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 ErrorObjListWithOpen getErrorObjListWithOpen() {
-        return this.errObjListWithOpen;
-    }
-
-    @Override
-    public void setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
-        this.errObjListWithOpen = errObjListWithOpen;
-    }
-
-    @Override
-    public PcepErrorInfo getPcepErrorInfo() {
-        return this.errInfo;
-    }
-
-    @Override
-    public void setPcepErrorInfo(PcepErrorInfo errInfo) {
-        this.errInfo = errInfo;
-    }
-
-    /**
-     * Return list of Error types.
-     *
-     * @return error types list
-     */
-    public LinkedList<Integer> getErrorType() {
-        LinkedList<Integer> llErrorType = new LinkedList<Integer>();
-        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
-                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
-            llErrorType = errObjListWithOpen.getErrorType();
-        } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
-            llErrorType = errInfo.getErrorType();
-        }
-
-        return llErrorType;
-    }
-
-    /**
-     * Return list of Error values.
-     *
-     * @return error value list
-     */
-    public LinkedList<Integer> getErrorValue() {
-        LinkedList<Integer> llErrorValue = new LinkedList<Integer>();
-        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
-                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
-            llErrorValue = errObjListWithOpen.getErrorValue();
-        } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
-            llErrorValue = errInfo.getErrorValue();
-        }
-
-        return llErrorValue;
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
-                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
-            toStrHelper.add("ErrorObjectListWithOpen", errObjListWithOpen);
-        }
-        if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
-            toStrHelper.add("ErrorInfo", errInfo);
-        }
-
-        return toStrHelper.toString();
-    }
-}
+package org.onosproject.pcepio.protocol.ver1;
+
+import java.util.LinkedList;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepErrorInfo;
+import org.onosproject.pcepio.protocol.PcepErrorMsg;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepMessageReader;
+import org.onosproject.pcepio.protocol.PcepMessageWriter;
+import org.onosproject.pcepio.protocol.PcepOpenObject;
+import org.onosproject.pcepio.protocol.PcepType;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.ErrorObjListWithOpen;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides PCEP Error Message.
+ */
+public class PcepErrorMsgVer1 implements PcepErrorMsg {
+
+    /*
+     * PCE Error message format.
+
+       <PCErr Message>                ::= <Common Header>
+                                        ( <error-obj-list> [<Open>] ) | <error>
+                                          [<error-list>]
+
+       <error-obj-list>               ::=<PCEP-ERROR>[<error-obj-list>]
+
+       <error>                        ::=[<request-id-list> | <te-id-list>]
+                                           <error-obj-list>
+
+       <request-id-list>              ::=<RP>[<request-id-list>]
+
+       <te-id-list>                   ::=<TE>[<te-id-list>]
+
+       <error-list>                   ::=<error>[<error-list>]
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepOpenMsgVer1.class);
+    public static final byte PACKET_VERSION = 1;
+    public static final int PACKET_MINIMUM_LENGTH = 12;
+    public static final PcepType MSG_TYPE = PcepType.ERROR;
+
+    //Below either one should be present.
+    private ErrorObjListWithOpen errObjListWithOpen; //optional   ( <error-obj-list> [<Open>] )
+    private PcepErrorInfo errInfo; //optional     <error> [<error-list>]
+
+    public static final PcepErrorMsgVer1.Reader READER = new Reader();
+
+    /**
+     * constructor to initialize variables.
+     */
+    public PcepErrorMsgVer1() {
+        errObjListWithOpen = null;
+        errInfo = null;
+    }
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param errObjListWithOpen error-object-list with open object
+     * @param errInfo error information
+     */
+    public PcepErrorMsgVer1(ErrorObjListWithOpen errObjListWithOpen, PcepErrorInfo errInfo) {
+        this.errObjListWithOpen = errObjListWithOpen;
+        this.errInfo = errInfo;
+    }
+
+    /**
+     * Reader class for reading PCEP error Message from channel buffer.
+     */
+    public static class Reader implements PcepMessageReader<PcepErrorMsg> {
+
+        ErrorObjListWithOpen errObjListWithOpen;
+        PcepErrorInfo errInfo;
+        PcepObjectHeader tempObjHeader;
+
+        @Override
+        public PcepErrorMsg readFrom(ChannelBuffer cb) throws PcepParseException {
+
+            errObjListWithOpen = null;
+            errInfo = null;
+            tempObjHeader = null;
+
+            if (cb.readableBytes() < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException("Packet size is less than the minimum length.");
+            }
+
+            byte version = cb.readByte();
+            version = (byte) (version >> PcepMessageVer1.SHIFT_FLAG);
+            if (version != PACKET_VERSION) {
+                throw new PcepParseException("Wrong version: Expected=PcepVersion.PCEP_1(1), got=" + version);
+            }
+            // fixed value property type == 1
+            byte type = cb.readByte();
+            if (type != MSG_TYPE.getType()) {
+                throw new PcepParseException("Wrong type: Expected=PcepType.ERROR(6), got=" + type);
+            }
+            int length = cb.readShort();
+            if (length < PACKET_MINIMUM_LENGTH) {
+                throw new PcepParseException(
+                        "Wrong length: Expected to be >= " + PACKET_MINIMUM_LENGTH + ", was: " + length);
+            }
+
+            //parse <PCErr Message>
+            parsePCErrMsg(cb);
+
+            // If other than RP or TE or PCEP-ERROR present then it is error.
+            if (0 < cb.readableBytes()) {
+                PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+                throw new PcepParseException("Unexpected Object found. Object Class : " + tempObjHeader.getObjClass());
+            }
+
+            return new PcepErrorMsgVer1(errObjListWithOpen, errInfo);
+        }
+
+        /**
+         * Parsing PCErr Message.
+         *
+         * @param cb channel buffer.
+         * @throws PcepParseException if mandatory fields are missing
+         * output: this.errObjListWithOpen, this.errInfo
+         */
+        public void parsePCErrMsg(ChannelBuffer cb) throws PcepParseException {
+            //If PCEP-ERROR list is followed by OPEN Object then store into ErrorObjListWithOpen.
+            //     ( <error-obj-list> [<Open>]
+            //If PCEP-ERROR list is followed by RP or TE Object then store into errInfo. <error> [<error-list>]
+            //If only PCEP-ERROR list is present then store into ErrorObjListWithOpen.
+            PcepObjectHeader tempObjHeader;
+            LinkedList<PcepErrorObject> llErrObjList;
+
+            if (0 >= cb.readableBytes()) {
+                throw new PcepParseException("PCEP-ERROR message came with empty objects.");
+            }
+
+            //parse PCEP-ERROR list
+            llErrObjList = new LinkedList<PcepErrorObject>();
+            tempObjHeader = parseErrorObjectList(llErrObjList, cb);
+
+            //check whether OPEN-OBJECT is present.
+            if ((tempObjHeader instanceof PcepObjectHeader)
+                    && (tempObjHeader.getObjClass() == PcepOpenObjectVer1.OPEN_OBJ_CLASS)) {
+
+                if (llErrObjList.isEmpty()) {
+                    throw new PcepParseException("<error-obj-list> should be present if OPEN-OBJECT exists");
+                }
+
+                PcepOpenObject pcepOpenObj = PcepOpenObjectVer1.read(cb);
+                this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList, pcepOpenObj);
+
+            } else if ((tempObjHeader instanceof PcepObjectHeader) //check whether RP or TE Object is present.
+                    && ((tempObjHeader.getObjClass() == PcepRPObjectVer1.RP_OBJ_CLASS)
+                            || (tempObjHeader.getObjClass() == PcepTEObjectVer1.TE_OBJ_CLASS))) {
+
+                this.errInfo = new PcepErrorInfoVer1(null, null, llErrObjList);
+                this.errInfo.read(cb);
+
+            } else if ((null != llErrObjList) && (!llErrObjList.isEmpty())) {
+                //If only PCEP-ERROR list is present then store it in errObjListWithOpen.
+                this.errObjListWithOpen = new ErrorObjListWithOpen(llErrObjList);
+            } else {
+                throw new PcepParseException("Empty PCEP-ERROR message.");
+            }
+        }
+
+        /**
+         * Parse error-obj-list.
+         *
+         * @param llErrObjList error object list output
+         * @param cb channel buffer input
+         * @throws PcepParseException if mandatory fields are missing
+         * @return error object header
+         */
+        public PcepObjectHeader parseErrorObjectList(LinkedList<PcepErrorObject> llErrObjList, ChannelBuffer cb)
+                throws PcepParseException {
+            PcepObjectHeader tempObjHeader = null;
+
+            while (0 < cb.readableBytes()) {
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                if (tempObjHeader.getObjClass() == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
+                    llErrObjList.add(PcepErrorObjectVer1.read(cb));
+                } else {
+                    break;
+                }
+            }
+            return tempObjHeader;
+        }
+    }
+
+    /**
+     * Builder class for PCEP error message.
+     */
+    public static class Builder implements PcepErrorMsg.Builder {
+        // Pcep error message fields
+
+        private ErrorObjListWithOpen errObjListWithOpen = null; //optional   ( <error-obj-list> [<Open>] )
+        private PcepErrorInfo errInfo = null; //optional     <error> [<error-list>]
+
+        @Override
+        public PcepVersion getVersion() {
+            return PcepVersion.PCEP_1;
+        }
+
+        @Override
+        public PcepType getType() {
+            return PcepType.ERROR;
+        }
+
+        @Override
+        public PcepErrorMsg build() {
+            return new PcepErrorMsgVer1(this.errObjListWithOpen, this.errInfo);
+        }
+
+        @Override
+        public ErrorObjListWithOpen getErrorObjListWithOpen() {
+            return this.errObjListWithOpen;
+        }
+
+        @Override
+        public Builder setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
+            this.errObjListWithOpen = errObjListWithOpen;
+            return this;
+        }
+
+        @Override
+        public PcepErrorInfo getPcepErrorInfo() {
+            return this.errInfo;
+        }
+
+        @Override
+        public Builder setPcepErrorInfo(PcepErrorInfo errInfo) {
+            this.errInfo = errInfo;
+            return this;
+        }
+    }
+
+    @Override
+    public void writeTo(ChannelBuffer cb) throws PcepParseException {
+        WRITER.write(cb, this);
+    }
+
+    public static final Writer WRITER = new Writer();
+
+    /**
+     * Writer class for writing PCEP error Message to channel buffer.
+     */
+    static class Writer implements PcepMessageWriter<PcepErrorMsgVer1> {
+        @Override
+        public void write(ChannelBuffer cb, PcepErrorMsgVer1 message) throws PcepParseException {
+            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);
+            ErrorObjListWithOpen errObjListWithOpen = message.getErrorObjListWithOpen();
+            PcepErrorInfo errInfo = message.getPcepErrorInfo();
+
+            // write ( <error-obj-list> [<Open>] ) if exists.
+            // otherwise write <error> [<error-list>]
+
+            if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
+                    && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
+                errObjListWithOpen.write(cb);
+            } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
+                errInfo.write(cb);
+            } else {
+                throw new PcepParseException("Empty PCEP-ERROR message.");
+            }
+            // PcepErrorMessage 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 ErrorObjListWithOpen getErrorObjListWithOpen() {
+        return this.errObjListWithOpen;
+    }
+
+    @Override
+    public void setErrorObjListWithOpen(ErrorObjListWithOpen errObjListWithOpen) {
+        this.errObjListWithOpen = errObjListWithOpen;
+    }
+
+    @Override
+    public PcepErrorInfo getPcepErrorInfo() {
+        return this.errInfo;
+    }
+
+    @Override
+    public void setPcepErrorInfo(PcepErrorInfo errInfo) {
+        this.errInfo = errInfo;
+    }
+
+    /**
+     * Return list of Error types.
+     *
+     * @return error types list
+     */
+    public LinkedList<Integer> getErrorType() {
+        LinkedList<Integer> llErrorType = new LinkedList<Integer>();
+        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
+                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
+            llErrorType = errObjListWithOpen.getErrorType();
+        } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
+            llErrorType = errInfo.getErrorType();
+        }
+
+        return llErrorType;
+    }
+
+    /**
+     * Return list of Error values.
+     *
+     * @return error value list
+     */
+    public LinkedList<Integer> getErrorValue() {
+        LinkedList<Integer> llErrorValue = new LinkedList<Integer>();
+        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
+                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
+            llErrorValue = errObjListWithOpen.getErrorValue();
+        } else if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
+            llErrorValue = errInfo.getErrorValue();
+        }
+
+        return llErrorValue;
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        if ((errObjListWithOpen instanceof ErrorObjListWithOpen)
+                && (errObjListWithOpen.isErrorObjListWithOpenPresent())) {
+            toStrHelper.add("ErrorObjectListWithOpen", errObjListWithOpen);
+        }
+        if ((errInfo instanceof PcepErrorInfo) && (errInfo.isErrorInfoPresent())) {
+            toStrHelper.add("ErrorInfo", errInfo);
+        }
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java
index 9e173c5..9557906 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorObjectVer1.java
@@ -1,325 +1,325 @@
-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.PcepErrorObject;
-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 Error Object.
- */
-public class PcepErrorObjectVer1 implements PcepErrorObject {
-
-    /*
-    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)       |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |   Reserved    |      Flags    |   Error-Type  |  Error-value  |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                                                               |
-    //                         Optional TLVs                       //
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepErrorObjectVer1.class);
-
-    public static final byte ERROR_OBJ_TYPE = 1;
-    public static final byte ERROR_OBJ_CLASS = 13;
-    public static final byte ERROR_OBJECT_VERSION = 1;
-    //ERROR_OBJ_MINIMUM_LENGTH = CommonHeaderLen(4)+ErrorObjectHeaderLen(4)
-    public static final short ERROR_OBJ_MINIMUM_LENGTH = 8;
-    public static final int OBJECT_HEADER_LENGTH = 4;
-
-    public static final PcepObjectHeader DEFAULT_ERROR_OBJECT_HEADER = new PcepObjectHeader(ERROR_OBJ_CLASS,
-            ERROR_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
-            ERROR_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader errorObjHeader;
-    private byte yErrorType;
-    private byte yErrorValue;
-    private LinkedList<PcepValueType> llOptionalTlv; // Optional TLV
-
-    /**
-     * Constructor to initialize variables.
-     *
-     * @param errorObjHeader ERROR Object header
-     * @param yErrorType Error Type
-     * @param yErrorValue Error Value
-     * @param llOptionalTlv list of optional TLV
-     */
-
-    public PcepErrorObjectVer1(PcepObjectHeader errorObjHeader, byte yErrorType, byte yErrorValue,
-            LinkedList<PcepValueType> llOptionalTlv) {
-        this.errorObjHeader = errorObjHeader;
-        this.yErrorType = yErrorType;
-        this.yErrorValue = yErrorValue;
-        this.llOptionalTlv = llOptionalTlv;
-    }
-
-    /**
-     * sets Object Header.
-     *
-     * @param obj Error-Object header
-     */
-    public void setLspObjHeader(PcepObjectHeader obj) {
-        this.errorObjHeader = obj;
-    }
-
-    @Override
-    public void setErrorType(byte yErrorType) {
-        this.yErrorType = yErrorType;
-    }
-
-    @Override
-    public void setErrorValue(byte yErrorValue) {
-        this.yErrorValue = yErrorValue;
-    }
-
-    /**
-     * returns object header.
-     *
-     * @return errorObjHeader Error-Object header
-     */
-    public PcepObjectHeader getErrorObjHeader() {
-        return this.errorObjHeader;
-    }
-
-    @Override
-    public int getErrorType() {
-        return this.yErrorType;
-    }
-
-    @Override
-    public byte getErrorValue() {
-        return this.yErrorValue;
-    }
-
-    @Override
-    public LinkedList<PcepValueType> getOptionalTlv() {
-        return this.llOptionalTlv;
-    }
-
-    @Override
-    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
-        this.llOptionalTlv = llOptionalTlv;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of PcepErrorObject.
-     *
-     * @param cb of channel buffer.
-     * @return object of PCEP-ERROR-OBJECT
-     */
-    public static PcepErrorObject read(ChannelBuffer cb) {
-
-        PcepObjectHeader errorObjHeader;
-        byte yErrorType;
-        byte yErrorValue;
-        LinkedList<PcepValueType> llOptionalTlv;
-
-        errorObjHeader = PcepObjectHeader.read(cb);
-
-        //take only ErrorObject buffer.
-        ChannelBuffer tempCb = cb.readBytes(errorObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
-        tempCb.readByte(); //ignore Reserved
-        tempCb.readByte(); //ignore Flags
-        yErrorType = tempCb.readByte();
-        yErrorValue = tempCb.readByte();
-
-        llOptionalTlv = parseOptionalTlv(tempCb);
-
-        return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv);
-    }
-
-    /**
-     * returns Linked list of optional tlvs.
-     *
-     * @param cb channel buffer.
-     * @return Linked list of optional tlvs
-     */
-    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) {
-
-        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
-
-        byte[] yTemp = new byte[cb.readableBytes()];
-        cb.readBytes(yTemp);
-
-        return llOutOptionalTlv;
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        //write Object header
-        int objStartIndex = cb.writerIndex();
-
-        int objLenIndex = errorObjHeader.write(cb);
-
-        if (objLenIndex <= 0) {
-            throw new PcepParseException("While writing Error Object Header.");
-        }
-
-        //write Reserved
-        cb.writeByte(0);
-        //write Flags
-        cb.writeByte(0);
-        //write ErrorType and ErrorValue
-        cb.writeByte(this.yErrorType);
-        cb.writeByte(this.yErrorValue);
-
-        // Add optional TLV
-        packOptionalTlv(cb);
-
-        //Update object length now
-        int length = cb.writerIndex() - objStartIndex;
-        //will be helpful during print().
-        errorObjHeader.setObjLen((short) length);
-        // As per RFC the length of object should be
-        // multiples of 4
-        int pad = length % 4;
-        if (pad != 0) {
-            pad = 4 - pad;
-            for (int i = 0; i < pad; i++) {
-                cb.writeByte((byte) 0);
-            }
-            length = length + pad;
-        }
-
-        cb.setShort(objLenIndex, (short) length);
-        return length;
-    }
-
-    /**
-     * Pack the Optional tlvs.
-     *
-     * @param cb channel buffer.
-     * @return writer index.
-     */
-    protected int packOptionalTlv(ChannelBuffer cb) {
-
-        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
-        int startIndex = cb.writerIndex();
-        while (listIterator.hasNext()) {
-            PcepValueType tlv = listIterator.next();
-
-            if (null == tlv) {
-                log.debug("TLV is null from OptionalTlv list");
-                continue;
-            }
-            tlv.write(cb);
-        }
-
-        return cb.writerIndex() - startIndex;
-    }
-
-    /**
-     * Builder class for PCEP error object.
-     */
-    public static class Builder implements PcepErrorObject.Builder {
-
-        private boolean bIsHeaderSet = false;
-
-        private PcepObjectHeader errorObjHeader;
-        private byte yErrorType;
-        private byte yErrorValue;
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
-
-        @Override
-        public PcepErrorObject build() {
-
-            PcepObjectHeader errorObjHeader = this.bIsHeaderSet ? this.errorObjHeader : DEFAULT_ERROR_OBJECT_HEADER;
-
-            if (bIsPFlagSet) {
-                errorObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                errorObjHeader.setIFlag(bIFlag);
-            }
-
-            return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv);
-        }
-
-        @Override
-        public PcepObjectHeader getErrorObjHeader() {
-            return this.errorObjHeader;
-        }
-
-        @Override
-        public Builder setErrorObjHeader(PcepObjectHeader obj) {
-            this.errorObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public int getErrorType() {
-            return this.yErrorType;
-        }
-
-        @Override
-        public Builder setErrorType(byte value) {
-            this.yErrorType = value;
-            return this;
-        }
-
-        @Override
-        public byte getErrorValue() {
-            return this.yErrorValue;
-        }
-
-        @Override
-        public Builder setErrorValue(byte value) {
-            this.yErrorValue = value;
-            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("ObjectHeader", errorObjHeader).add("ErrorType", yErrorType)
-                .add("ErrorValue", yErrorValue).add("OptionalTlv", llOptionalTlv).toString();
-    }
-}
+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.PcepErrorObject;
+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 Error Object.
+ */
+public class PcepErrorObjectVer1 implements PcepErrorObject {
+
+    /*
+    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)       |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |   Reserved    |      Flags    |   Error-Type  |  Error-value  |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    //                         Optional TLVs                       //
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepErrorObjectVer1.class);
+
+    public static final byte ERROR_OBJ_TYPE = 1;
+    public static final byte ERROR_OBJ_CLASS = 13;
+    public static final byte ERROR_OBJECT_VERSION = 1;
+    //ERROR_OBJ_MINIMUM_LENGTH = CommonHeaderLen(4)+ErrorObjectHeaderLen(4)
+    public static final short ERROR_OBJ_MINIMUM_LENGTH = 8;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+
+    public static final PcepObjectHeader DEFAULT_ERROR_OBJECT_HEADER = new PcepObjectHeader(ERROR_OBJ_CLASS,
+            ERROR_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
+            ERROR_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader errorObjHeader;
+    private byte yErrorType;
+    private byte yErrorValue;
+    private LinkedList<PcepValueType> llOptionalTlv; // Optional TLV
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param errorObjHeader ERROR Object header
+     * @param yErrorType Error Type
+     * @param yErrorValue Error Value
+     * @param llOptionalTlv list of optional TLV
+     */
+
+    public PcepErrorObjectVer1(PcepObjectHeader errorObjHeader, byte yErrorType, byte yErrorValue,
+            LinkedList<PcepValueType> llOptionalTlv) {
+        this.errorObjHeader = errorObjHeader;
+        this.yErrorType = yErrorType;
+        this.yErrorValue = yErrorValue;
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * sets Object Header.
+     *
+     * @param obj Error-Object header
+     */
+    public void setLspObjHeader(PcepObjectHeader obj) {
+        this.errorObjHeader = obj;
+    }
+
+    @Override
+    public void setErrorType(byte yErrorType) {
+        this.yErrorType = yErrorType;
+    }
+
+    @Override
+    public void setErrorValue(byte yErrorValue) {
+        this.yErrorValue = yErrorValue;
+    }
+
+    /**
+     * returns object header.
+     *
+     * @return errorObjHeader Error-Object header
+     */
+    public PcepObjectHeader getErrorObjHeader() {
+        return this.errorObjHeader;
+    }
+
+    @Override
+    public int getErrorType() {
+        return this.yErrorType;
+    }
+
+    @Override
+    public byte getErrorValue() {
+        return this.yErrorValue;
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getOptionalTlv() {
+        return this.llOptionalTlv;
+    }
+
+    @Override
+    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of PcepErrorObject.
+     *
+     * @param cb of channel buffer.
+     * @return object of PCEP-ERROR-OBJECT
+     */
+    public static PcepErrorObject read(ChannelBuffer cb) {
+
+        PcepObjectHeader errorObjHeader;
+        byte yErrorType;
+        byte yErrorValue;
+        LinkedList<PcepValueType> llOptionalTlv;
+
+        errorObjHeader = PcepObjectHeader.read(cb);
+
+        //take only ErrorObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(errorObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+        tempCb.readByte(); //ignore Reserved
+        tempCb.readByte(); //ignore Flags
+        yErrorType = tempCb.readByte();
+        yErrorValue = tempCb.readByte();
+
+        llOptionalTlv = parseOptionalTlv(tempCb);
+
+        return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv);
+    }
+
+    /**
+     * returns Linked list of optional tlvs.
+     *
+     * @param cb channel buffer.
+     * @return Linked list of optional tlvs
+     */
+    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) {
+
+        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
+
+        byte[] yTemp = new byte[cb.readableBytes()];
+        cb.readBytes(yTemp);
+
+        return llOutOptionalTlv;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        int objLenIndex = errorObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("While writing Error Object Header.");
+        }
+
+        //write Reserved
+        cb.writeByte(0);
+        //write Flags
+        cb.writeByte(0);
+        //write ErrorType and ErrorValue
+        cb.writeByte(this.yErrorType);
+        cb.writeByte(this.yErrorValue);
+
+        // Add optional TLV
+        packOptionalTlv(cb);
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+        //will be helpful during print().
+        errorObjHeader.setObjLen((short) length);
+        // As per RFC the length of object should be
+        // multiples of 4
+        int pad = length % 4;
+        if (pad != 0) {
+            pad = 4 - pad;
+            for (int i = 0; i < pad; i++) {
+                cb.writeByte((byte) 0);
+            }
+            length = length + pad;
+        }
+
+        cb.setShort(objLenIndex, (short) length);
+        return length;
+    }
+
+    /**
+     * Pack the Optional tlvs.
+     *
+     * @param cb channel buffer.
+     * @return writer index.
+     */
+    protected int packOptionalTlv(ChannelBuffer cb) {
+
+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+        int startIndex = cb.writerIndex();
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            if (null == tlv) {
+                log.debug("TLV is null from OptionalTlv list");
+                continue;
+            }
+            tlv.write(cb);
+        }
+
+        return cb.writerIndex() - startIndex;
+    }
+
+    /**
+     * Builder class for PCEP error object.
+     */
+    public static class Builder implements PcepErrorObject.Builder {
+
+        private boolean bIsHeaderSet = false;
+
+        private PcepObjectHeader errorObjHeader;
+        private byte yErrorType;
+        private byte yErrorValue;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        @Override
+        public PcepErrorObject build() {
+
+            PcepObjectHeader errorObjHeader = this.bIsHeaderSet ? this.errorObjHeader : DEFAULT_ERROR_OBJECT_HEADER;
+
+            if (bIsPFlagSet) {
+                errorObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                errorObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepErrorObjectVer1(errorObjHeader, yErrorType, yErrorValue, llOptionalTlv);
+        }
+
+        @Override
+        public PcepObjectHeader getErrorObjHeader() {
+            return this.errorObjHeader;
+        }
+
+        @Override
+        public Builder setErrorObjHeader(PcepObjectHeader obj) {
+            this.errorObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getErrorType() {
+            return this.yErrorType;
+        }
+
+        @Override
+        public Builder setErrorType(byte value) {
+            this.yErrorType = value;
+            return this;
+        }
+
+        @Override
+        public byte getErrorValue() {
+            return this.yErrorValue;
+        }
+
+        @Override
+        public Builder setErrorValue(byte value) {
+            this.yErrorValue = value;
+            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("ObjectHeader", errorObjHeader).add("ErrorType", yErrorType)
+                .add("ErrorValue", yErrorValue).add("OptionalTlv", llOptionalTlv).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java
index 73c4dff..50200d0 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepErrorVer1.java
@@ -1,408 +1,408 @@
-/*
- * 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.PcepError;
-import org.onosproject.pcepio.protocol.PcepErrorObject;
-import org.onosproject.pcepio.protocol.PcepRPObject;
-import org.onosproject.pcepio.protocol.PcepTEObject;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides PcepError list which contains RP or TE objects.
- * Reference:PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
- */
-public class PcepErrorVer1 implements PcepError {
-
-    /*
-           <error>::=[<request-id-list> | <te-id-list>]
-                      <error-obj-list>
-
-           <request-id-list>::=<RP>[<request-id-list>]
-
-           <te-id-list>::=<TE>[<te-id-list>]
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepErrorVer1.class);
-
-    private boolean isErroInfoSet;
-    //PcepErrorObject list
-    private LinkedList<PcepErrorObject> llErrObjList;
-    //PcepRPObject list
-    private LinkedList<PcepRPObject> llRPObjList;
-    //PcepTEObject list
-    private LinkedList<PcepTEObject> llTEObjList;
-    private boolean isTEObjListSet;
-
-    public static final int OBJECT_HEADER_LENGTH = 4;
-
-    /**
-     * Constructor to initialize variable.
-     */
-    public PcepErrorVer1() {
-        this.llRPObjList = null;
-        this.llTEObjList = null;
-        this.llErrObjList = null;
-    }
-
-    /**
-     * Constructor to initialize variable.
-     *
-     * @param llRPObjList list of PcepRPObject
-     * @param llTEObjList list of PcepTEObject
-     * @param llErrObjListObjList list of PcepErrorObject
-     */
-    public PcepErrorVer1(LinkedList<PcepRPObject> llRPObjList, LinkedList<PcepTEObject> llTEObjList,
-            LinkedList<PcepErrorObject> llErrObjListObjList) {
-        this.llRPObjList = llRPObjList;
-        this.llTEObjList = llTEObjList;
-        this.llErrObjList = llErrObjListObjList;
-    }
-
-    /**
-     * Constructor to initialize PcepError.
-     *
-     * @param llErrObjList list of PcepErrorObject
-     */
-    public PcepErrorVer1(LinkedList<PcepErrorObject> llErrObjList) {
-        this.llRPObjList = null;
-        this.llTEObjList = null;
-        this.llErrObjList = llErrObjList;
-    }
-
-    @Override
-    public LinkedList<PcepRPObject> getRPObjList() {
-        return this.llRPObjList;
-    }
-
-    @Override
-    public LinkedList<PcepTEObject> getTEObjList() {
-        return this.llTEObjList;
-    }
-
-    @Override
-    public LinkedList<PcepErrorObject> getErrorObjList() {
-        return this.llErrObjList;
-    }
-
-    /**
-     * Parse RP List from the channel buffer.
-     *
-     * @throws PcepParseException if mandatory fields are missing
-     * @param cb of type channel buffer
-     */
-    public void parseRPList(ChannelBuffer cb) throws PcepParseException {
-        byte yObjClass;
-        byte yObjType;
-
-        llRPObjList = new LinkedList<PcepRPObject>();
-
-        // caller should verify for RP object
-        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
-            log.debug("Unable to find RP Object");
-            return;
-        }
-
-        cb.markReaderIndex();
-        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-        cb.resetReaderIndex();
-        yObjClass = tempObjHeader.getObjClass();
-        yObjType = tempObjHeader.getObjType();
-        PcepRPObject rpObj;
-        while ((yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjType == PcepRPObjectVer1.RP_OBJ_TYPE)) {
-            rpObj = PcepRPObjectVer1.read(cb);
-            llRPObjList.add(rpObj);
-
-            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
-                cb.markReaderIndex();
-                tempObjHeader = PcepObjectHeader.read(cb);
-                cb.resetReaderIndex();
-                yObjClass = tempObjHeader.getObjClass();
-                yObjType = tempObjHeader.getObjType();
-            } else {
-                break;
-            }
-        }
-    }
-
-    /**
-     * Parse TE List from the channel buffer.
-     *
-     * @param cb of type channel buffer
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public void parseTEList(ChannelBuffer cb) throws PcepParseException {
-        byte yObjClass;
-        byte yObjType;
-
-        llTEObjList = new LinkedList<PcepTEObject>();
-
-        // caller should verify for TE object
-        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
-            log.debug("Unable to find TE Object");
-            return;
-        }
-
-        cb.markReaderIndex();
-        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-        cb.resetReaderIndex();
-        yObjClass = tempObjHeader.getObjClass();
-        yObjType = tempObjHeader.getObjType();
-        PcepTEObject teObj;
-        while ((yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) && ((yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_NODE_VALUE)
-                || (yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_LINK_VALUE))) {
-            teObj = PcepTEObjectVer1.read(cb);
-            llTEObjList.add(teObj);
-
-            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
-                cb.markReaderIndex();
-                tempObjHeader = PcepObjectHeader.read(cb);
-                cb.resetReaderIndex();
-                yObjClass = tempObjHeader.getObjClass();
-                yObjType = tempObjHeader.getObjType();
-            } else {
-                break;
-            }
-        }
-    }
-
-    /**
-     * parseErrObjList from the channel buffer.
-     *
-     * @param cb of type channel buffer
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public void parseErrObjList(ChannelBuffer cb) throws PcepParseException {
-        byte yObjClass;
-        byte yObjType;
-        boolean bIsErrorObjFound = false;
-
-        llErrObjList = new LinkedList<PcepErrorObject>();
-
-        // caller should verify for RP object
-        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
-            throw new PcepParseException("Unable to find PCEP-ERROR Object");
-        }
-
-        cb.markReaderIndex();
-        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-        cb.resetReaderIndex();
-        yObjClass = tempObjHeader.getObjClass();
-        yObjType = tempObjHeader.getObjType();
-        PcepErrorObject errorObject;
-        while ((yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) && (yObjType == PcepErrorObjectVer1.ERROR_OBJ_TYPE)) {
-            errorObject = PcepErrorObjectVer1.read(cb);
-            llErrObjList.add(errorObject);
-            bIsErrorObjFound = true;
-
-            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
-                cb.markReaderIndex();
-                tempObjHeader = PcepObjectHeader.read(cb);
-                cb.resetReaderIndex();
-                yObjClass = tempObjHeader.getObjClass();
-                yObjType = tempObjHeader.getObjType();
-            } else {
-                break;
-            }
-        }
-
-        if (!bIsErrorObjFound) {
-            throw new PcepParseException("At least one PCEP-ERROR Object should be present.");
-        }
-    }
-
-    /**
-     * Reads the byte stream of PcepError from channel buffer.
-     *
-     * @param cb of type channel buffer
-     * @return PcepError error part of PCEP-ERROR
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public static PcepErrorVer1 read(ChannelBuffer cb) throws PcepParseException {
-        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
-            throw new PcepParseException("Unknown Object");
-        }
-
-        PcepErrorVer1 pcepError = new PcepErrorVer1();
-        // check whether any PCEP Error Info is present
-        cb.markReaderIndex();
-        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-        cb.resetReaderIndex();
-        byte yObjClass = tempObjHeader.getObjClass();
-
-        //If RPlist present then store it.RPList and TEList are optional
-        if (yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) {
-            log.debug("RP_LIST");
-            pcepError.parseRPList(cb);
-            yObjClass = checkNextObject(cb);
-        } else if (yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) {
-            log.debug("TE_LIST");
-            pcepError.parseTEList(cb);
-            yObjClass = checkNextObject(cb);
-        }
-
-        if (yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
-            log.debug("PCEP-ERROR obj list");
-            pcepError.parseErrObjList(cb);
-            yObjClass = checkNextObject(cb);
-        }
-
-        return pcepError;
-    }
-
-    /**
-     * Checks Next Object.
-     *
-     * @param cb of type channel buffer.
-     * @return object type class.
-     */
-    private static byte checkNextObject(ChannelBuffer cb) {
-        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
-            return 0;
-        }
-        cb.markReaderIndex();
-        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
-        cb.resetReaderIndex();
-        return tempObjHeader.getObjClass();
-    }
-
-    /**
-     * Writes the byte stream of PCEP error to the channel buffer.
-     *
-     * @param cb of type channel buffer
-     * @return object length index
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-        int iLenStartIndex = cb.writerIndex();
-
-        // RPlist is optional
-        if (this.isErroInfoSet) {
-            ListIterator<PcepRPObject> rpObjlistIterator = this.llRPObjList.listIterator();
-            while (rpObjlistIterator.hasNext()) {
-                rpObjlistIterator.next().write(cb);
-            }
-        }
-
-        // TElist is optional
-        if (this.isTEObjListSet) {
-            ListIterator<PcepTEObject> teObjlistIterator = this.llTEObjList.listIterator();
-            while (teObjlistIterator.hasNext()) {
-                teObjlistIterator.next().write(cb);
-            }
-        }
-        //ErrList is mandatory
-        ListIterator<PcepErrorObject> errlistIterator = this.llErrObjList.listIterator();
-        while (errlistIterator.hasNext()) {
-            errlistIterator.next().write(cb);
-        }
-
-        return cb.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Builder for error part of PCEP-ERROR.
-     */
-    public static class Builder implements PcepError.Builder {
-
-        private LinkedList<PcepRPObject> llRPObjList;
-        private LinkedList<PcepTEObject> llTEObjList;
-        private LinkedList<PcepErrorObject> llErrObjList;
-
-        @Override
-        public PcepError build() {
-            return new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList);
-        }
-
-        @Override
-        public LinkedList<PcepRPObject> getRPObjList() {
-            return this.llRPObjList;
-        }
-
-        @Override
-        public Builder setRPObjList(LinkedList<PcepRPObject> llRPObjList) {
-            this.llRPObjList = llRPObjList;
-            return this;
-        }
-
-        @Override
-        public LinkedList<PcepTEObject> getTEObjList() {
-            return this.llTEObjList;
-        }
-
-        @Override
-        public Builder setTEObjList(LinkedList<PcepTEObject> llTEObjList) {
-            this.llTEObjList = llTEObjList;
-            return this;
-        }
-
-        @Override
-        public LinkedList<PcepErrorObject> getErrorObjList() {
-            return this.llErrObjList;
-        }
-
-        @Override
-        public Builder setErrorObjList(LinkedList<PcepErrorObject> llErrObjList) {
-            this.llErrObjList = llErrObjList;
-            return this;
-        }
-
-    }
-
-    @Override
-    public void setRPObjList(LinkedList<PcepRPObject> llRPObjList) {
-        this.llRPObjList = llRPObjList;
-    }
-
-    @Override
-    public void setTEObjList(LinkedList<PcepTEObject> llTEObjList) {
-        this.llTEObjList = llTEObjList;
-    }
-
-    @Override
-    public void setErrorObjList(LinkedList<PcepErrorObject> llErrObjList) {
-        this.llErrObjList = llErrObjList;
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        //RP Object list is optional
-        if (null != llRPObjList) {
-            toStrHelper.add("RpObjectList", llRPObjList);
-        }
-
-        //TE Object list is optional
-        if (null != llTEObjList) {
-            toStrHelper.add("TeObjectList", llTEObjList);
-        }
-
-        //Error Object List is mandatory
-        return toStrHelper.add("ErrorObjectList", llErrObjList).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.PcepError;
+import org.onosproject.pcepio.protocol.PcepErrorObject;
+import org.onosproject.pcepio.protocol.PcepRPObject;
+import org.onosproject.pcepio.protocol.PcepTEObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides PcepError list which contains RP or TE objects.
+ * Reference:PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02.
+ */
+public class PcepErrorVer1 implements PcepError {
+
+    /*
+           <error>::=[<request-id-list> | <te-id-list>]
+                      <error-obj-list>
+
+           <request-id-list>::=<RP>[<request-id-list>]
+
+           <te-id-list>::=<TE>[<te-id-list>]
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepErrorVer1.class);
+
+    private boolean isErroInfoSet;
+    //PcepErrorObject list
+    private LinkedList<PcepErrorObject> llErrObjList;
+    //PcepRPObject list
+    private LinkedList<PcepRPObject> llRPObjList;
+    //PcepTEObject list
+    private LinkedList<PcepTEObject> llTEObjList;
+    private boolean isTEObjListSet;
+
+    public static final int OBJECT_HEADER_LENGTH = 4;
+
+    /**
+     * Constructor to initialize variable.
+     */
+    public PcepErrorVer1() {
+        this.llRPObjList = null;
+        this.llTEObjList = null;
+        this.llErrObjList = null;
+    }
+
+    /**
+     * Constructor to initialize variable.
+     *
+     * @param llRPObjList list of PcepRPObject
+     * @param llTEObjList list of PcepTEObject
+     * @param llErrObjListObjList list of PcepErrorObject
+     */
+    public PcepErrorVer1(LinkedList<PcepRPObject> llRPObjList, LinkedList<PcepTEObject> llTEObjList,
+            LinkedList<PcepErrorObject> llErrObjListObjList) {
+        this.llRPObjList = llRPObjList;
+        this.llTEObjList = llTEObjList;
+        this.llErrObjList = llErrObjListObjList;
+    }
+
+    /**
+     * Constructor to initialize PcepError.
+     *
+     * @param llErrObjList list of PcepErrorObject
+     */
+    public PcepErrorVer1(LinkedList<PcepErrorObject> llErrObjList) {
+        this.llRPObjList = null;
+        this.llTEObjList = null;
+        this.llErrObjList = llErrObjList;
+    }
+
+    @Override
+    public LinkedList<PcepRPObject> getRPObjList() {
+        return this.llRPObjList;
+    }
+
+    @Override
+    public LinkedList<PcepTEObject> getTEObjList() {
+        return this.llTEObjList;
+    }
+
+    @Override
+    public LinkedList<PcepErrorObject> getErrorObjList() {
+        return this.llErrObjList;
+    }
+
+    /**
+     * Parse RP List from the channel buffer.
+     *
+     * @throws PcepParseException if mandatory fields are missing
+     * @param cb of type channel buffer
+     */
+    public void parseRPList(ChannelBuffer cb) throws PcepParseException {
+        byte yObjClass;
+        byte yObjType;
+
+        llRPObjList = new LinkedList<PcepRPObject>();
+
+        // caller should verify for RP object
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            log.debug("Unable to find RP Object");
+            return;
+        }
+
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        yObjClass = tempObjHeader.getObjClass();
+        yObjType = tempObjHeader.getObjType();
+        PcepRPObject rpObj;
+        while ((yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) && (yObjType == PcepRPObjectVer1.RP_OBJ_TYPE)) {
+            rpObj = PcepRPObjectVer1.read(cb);
+            llRPObjList.add(rpObj);
+
+            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                yObjClass = tempObjHeader.getObjClass();
+                yObjType = tempObjHeader.getObjType();
+            } else {
+                break;
+            }
+        }
+    }
+
+    /**
+     * Parse TE List from the channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public void parseTEList(ChannelBuffer cb) throws PcepParseException {
+        byte yObjClass;
+        byte yObjType;
+
+        llTEObjList = new LinkedList<PcepTEObject>();
+
+        // caller should verify for TE object
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            log.debug("Unable to find TE Object");
+            return;
+        }
+
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        yObjClass = tempObjHeader.getObjClass();
+        yObjType = tempObjHeader.getObjType();
+        PcepTEObject teObj;
+        while ((yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) && ((yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_NODE_VALUE)
+                || (yObjType == PcepTEObjectVer1.TE_OBJ_TYPE_LINK_VALUE))) {
+            teObj = PcepTEObjectVer1.read(cb);
+            llTEObjList.add(teObj);
+
+            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                yObjClass = tempObjHeader.getObjClass();
+                yObjType = tempObjHeader.getObjType();
+            } else {
+                break;
+            }
+        }
+    }
+
+    /**
+     * parseErrObjList from the channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public void parseErrObjList(ChannelBuffer cb) throws PcepParseException {
+        byte yObjClass;
+        byte yObjType;
+        boolean bIsErrorObjFound = false;
+
+        llErrObjList = new LinkedList<PcepErrorObject>();
+
+        // caller should verify for RP object
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            throw new PcepParseException("Unable to find PCEP-ERROR Object");
+        }
+
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        yObjClass = tempObjHeader.getObjClass();
+        yObjType = tempObjHeader.getObjType();
+        PcepErrorObject errorObject;
+        while ((yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) && (yObjType == PcepErrorObjectVer1.ERROR_OBJ_TYPE)) {
+            errorObject = PcepErrorObjectVer1.read(cb);
+            llErrObjList.add(errorObject);
+            bIsErrorObjFound = true;
+
+            if (cb.readableBytes() > OBJECT_HEADER_LENGTH) {
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+                yObjClass = tempObjHeader.getObjClass();
+                yObjType = tempObjHeader.getObjType();
+            } else {
+                break;
+            }
+        }
+
+        if (!bIsErrorObjFound) {
+            throw new PcepParseException("At least one PCEP-ERROR Object should be present.");
+        }
+    }
+
+    /**
+     * Reads the byte stream of PcepError from channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @return PcepError error part of PCEP-ERROR
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepErrorVer1 read(ChannelBuffer cb) throws PcepParseException {
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            throw new PcepParseException("Unknown Object");
+        }
+
+        PcepErrorVer1 pcepError = new PcepErrorVer1();
+        // check whether any PCEP Error Info is present
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        byte yObjClass = tempObjHeader.getObjClass();
+
+        //If RPlist present then store it.RPList and TEList are optional
+        if (yObjClass == PcepRPObjectVer1.RP_OBJ_CLASS) {
+            log.debug("RP_LIST");
+            pcepError.parseRPList(cb);
+            yObjClass = checkNextObject(cb);
+        } else if (yObjClass == PcepTEObjectVer1.TE_OBJ_CLASS) {
+            log.debug("TE_LIST");
+            pcepError.parseTEList(cb);
+            yObjClass = checkNextObject(cb);
+        }
+
+        if (yObjClass == PcepErrorObjectVer1.ERROR_OBJ_CLASS) {
+            log.debug("PCEP-ERROR obj list");
+            pcepError.parseErrObjList(cb);
+            yObjClass = checkNextObject(cb);
+        }
+
+        return pcepError;
+    }
+
+    /**
+     * Checks Next Object.
+     *
+     * @param cb of type channel buffer.
+     * @return object type class.
+     */
+    private static byte checkNextObject(ChannelBuffer cb) {
+        if (cb.readableBytes() < OBJECT_HEADER_LENGTH) {
+            return 0;
+        }
+        cb.markReaderIndex();
+        PcepObjectHeader tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+        return tempObjHeader.getObjClass();
+    }
+
+    /**
+     * Writes the byte stream of PCEP error to the channel buffer.
+     *
+     * @param cb of type channel buffer
+     * @return object length index
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+        int iLenStartIndex = cb.writerIndex();
+
+        // RPlist is optional
+        if (this.isErroInfoSet) {
+            ListIterator<PcepRPObject> rpObjlistIterator = this.llRPObjList.listIterator();
+            while (rpObjlistIterator.hasNext()) {
+                rpObjlistIterator.next().write(cb);
+            }
+        }
+
+        // TElist is optional
+        if (this.isTEObjListSet) {
+            ListIterator<PcepTEObject> teObjlistIterator = this.llTEObjList.listIterator();
+            while (teObjlistIterator.hasNext()) {
+                teObjlistIterator.next().write(cb);
+            }
+        }
+        //ErrList is mandatory
+        ListIterator<PcepErrorObject> errlistIterator = this.llErrObjList.listIterator();
+        while (errlistIterator.hasNext()) {
+            errlistIterator.next().write(cb);
+        }
+
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Builder for error part of PCEP-ERROR.
+     */
+    public static class Builder implements PcepError.Builder {
+
+        private LinkedList<PcepRPObject> llRPObjList;
+        private LinkedList<PcepTEObject> llTEObjList;
+        private LinkedList<PcepErrorObject> llErrObjList;
+
+        @Override
+        public PcepError build() {
+            return new PcepErrorVer1(llRPObjList, llTEObjList, llErrObjList);
+        }
+
+        @Override
+        public LinkedList<PcepRPObject> getRPObjList() {
+            return this.llRPObjList;
+        }
+
+        @Override
+        public Builder setRPObjList(LinkedList<PcepRPObject> llRPObjList) {
+            this.llRPObjList = llRPObjList;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepTEObject> getTEObjList() {
+            return this.llTEObjList;
+        }
+
+        @Override
+        public Builder setTEObjList(LinkedList<PcepTEObject> llTEObjList) {
+            this.llTEObjList = llTEObjList;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepErrorObject> getErrorObjList() {
+            return this.llErrObjList;
+        }
+
+        @Override
+        public Builder setErrorObjList(LinkedList<PcepErrorObject> llErrObjList) {
+            this.llErrObjList = llErrObjList;
+            return this;
+        }
+
+    }
+
+    @Override
+    public void setRPObjList(LinkedList<PcepRPObject> llRPObjList) {
+        this.llRPObjList = llRPObjList;
+    }
+
+    @Override
+    public void setTEObjList(LinkedList<PcepTEObject> llTEObjList) {
+        this.llTEObjList = llTEObjList;
+    }
+
+    @Override
+    public void setErrorObjList(LinkedList<PcepErrorObject> llErrObjList) {
+        this.llErrObjList = llErrObjList;
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        //RP Object list is optional
+        if (null != llRPObjList) {
+            toStrHelper.add("RpObjectList", llRPObjList);
+        }
+
+        //TE Object list is optional
+        if (null != llTEObjList) {
+            toStrHelper.add("TeObjectList", llTEObjList);
+        }
+
+        //Error Object List is mandatory
+        return toStrHelper.add("ErrorObjectList", llErrObjList).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4AdjacencyVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4AdjacencyVer1.java
index 0da0646..8e43cbd 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4AdjacencyVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4AdjacencyVer1.java
@@ -1,251 +1,251 @@
-/*
- * 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 org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepFecObjectIPv4Adjacency;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP fec Object IPv4 Adjacency object.
- */
-public class PcepFecObjectIPv4AdjacencyVer1 implements PcepFecObjectIPv4Adjacency {
-
-    /*
-     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
-     *
-            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
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |                    Local IPv4 address                         |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |                    Remote IPv4 address                        |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                      FEC Object-Type is 3 IPv4 Adjacency
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4AdjacencyVer1.class);
-
-    public static final byte FEC_OBJ_TYPE = 3;
-    public static final byte FEC_OBJ_CLASS = 36; //to be defined
-    public static final byte FEC_OBJECT_VERSION = 1;
-    public static final short FEC_OBJ_MINIMUM_LENGTH = 12;
-    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
-
-    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader fecObjHeader;
-    private int localIPv4Address;
-    private int remoteIPv4Address;
-
-    /**
-     * Constructor to initialize parameters for PCEP fec object .
-     *
-     * @param fecObjHeader FEC Object header
-     * @param localIPv4Address Local IPv4 Address
-     * @param remoteIPv4Address Remote IPv4 Address
-     */
-    public PcepFecObjectIPv4AdjacencyVer1(PcepObjectHeader fecObjHeader, int localIPv4Address, int remoteIPv4Address) {
-        this.fecObjHeader = fecObjHeader;
-        this.localIPv4Address = localIPv4Address;
-        this.remoteIPv4Address = remoteIPv4Address;
-    }
-
-    /**
-     * Sets Object header.
-     *
-     * @param obj Pcep fec Object Header
-     */
-    public void setFecIpv4ObjHeader(PcepObjectHeader obj) {
-        this.fecObjHeader = obj;
-    }
-
-    @Override
-    public int getLocalIPv4Address() {
-        return this.localIPv4Address;
-    }
-
-    @Override
-    public void seLocalIPv4Address(int value) {
-        this.localIPv4Address = value;
-    }
-
-    @Override
-    public int getRemoteIPv4Address() {
-        return this.remoteIPv4Address;
-    }
-
-    @Override
-    public void seRemoteIPv4Address(int value) {
-        this.remoteIPv4Address = value;
-    }
-
-    /**
-     * Reads from channel buffer and Returns object of PcepFecObjectIPv4Adjacency.
-     *
-     * @param cb of channel buffer.
-     * @return object of PcepFecObjectIPv4Adjacency
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepFecObjectIPv4Adjacency read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader fecObjHeader;
-        int localIPv4Address;
-        int remoteIPv4Address;
-
-        fecObjHeader = PcepObjectHeader.read(cb);
-
-        //take only FEC IPv4 Adjacency Object buffer.
-        ChannelBuffer tempCb = cb.readBytes(fecObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
-        localIPv4Address = tempCb.readInt();
-        remoteIPv4Address = tempCb.readInt();
-
-        return new PcepFecObjectIPv4AdjacencyVer1(fecObjHeader, localIPv4Address, remoteIPv4Address);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        int objStartIndex = cb.writerIndex();
-
-        //Write common header
-        int objLenIndex = fecObjHeader.write(cb);
-        cb.writeInt(localIPv4Address);
-        cb.writeInt(remoteIPv4Address);
-
-        //Now write FEC IPv4 Adjacency Object Length
-        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
-        return cb.writerIndex();
-    }
-
-    /**
-     * Builder class for PCEP fec object IPv4 Adjacency.
-     */
-    public static class Builder implements PcepFecObjectIPv4Adjacency.Builder {
-        private boolean bIsHeaderSet = false;
-        private boolean bIsLocalIPv4Addressset = false;
-        private boolean bIsRemoteIPv4Addressset = false;
-
-        private PcepObjectHeader fecObjHeader;
-        int localIPv4Address;
-        int remoteIPv4Address;
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepFecObjectIPv4Adjacency build() throws PcepParseException {
-            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
-
-            if (!this.bIsLocalIPv4Addressset) {
-                throw new PcepParseException(
-                        "Local IPv4 Address not set while building PcepFecObjectIPv4Adjacency object.");
-            }
-
-            if (!this.bIsRemoteIPv4Addressset) {
-                throw new PcepParseException(
-                        " Remote IPv4 Address not set while building PcepFecObjectIPv4Adjacency object.");
-            }
-
-            if (bIsPFlagSet) {
-                fecObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                fecObjHeader.setIFlag(bIFlag);
-            }
-            return new PcepFecObjectIPv4AdjacencyVer1(fecObjHeader, this.localIPv4Address, this.remoteIPv4Address);
-        }
-
-        @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 PcepObjectHeader getFecIpv4AdjacencyObjHeader() {
-            return this.fecObjHeader;
-        }
-
-        @Override
-        public Builder setFecIpv4AdjacencyObjHeader(PcepObjectHeader obj) {
-            this.fecObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public int getLocalIPv4Address() {
-            return this.localIPv4Address;
-        }
-
-        @Override
-        public Builder seLocalIPv4Address(int value) {
-            this.localIPv4Address = value;
-            this.bIsLocalIPv4Addressset = true;
-            return this;
-        }
-
-        @Override
-        public int getRemoteIPv4Address() {
-            return this.remoteIPv4Address;
-        }
-
-        @Override
-        public Builder seRemoteIPv4Address(int value) {
-            this.remoteIPv4Address = value;
-            this.bIsRemoteIPv4Addressset = true;
-            return this;
-        }
-
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public int getType() {
-        return FEC_OBJ_TYPE;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("fecObjHeader", fecObjHeader)
-                .add("localIPv4Address", localIPv4Address).add("remoteIPv4Address", remoteIPv4Address).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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv4Adjacency;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP fec Object IPv4 Adjacency object.
+ */
+public class PcepFecObjectIPv4AdjacencyVer1 implements PcepFecObjectIPv4Adjacency {
+
+    /*
+     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
+     *
+            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
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |                    Local IPv4 address                         |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |                    Remote IPv4 address                        |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                      FEC Object-Type is 3 IPv4 Adjacency
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4AdjacencyVer1.class);
+
+    public static final byte FEC_OBJ_TYPE = 3;
+    public static final byte FEC_OBJ_CLASS = 36; //to be defined
+    public static final byte FEC_OBJECT_VERSION = 1;
+    public static final short FEC_OBJ_MINIMUM_LENGTH = 12;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+
+    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader fecObjHeader;
+    private int localIPv4Address;
+    private int remoteIPv4Address;
+
+    /**
+     * Constructor to initialize parameters for PCEP fec object .
+     *
+     * @param fecObjHeader FEC Object header
+     * @param localIPv4Address Local IPv4 Address
+     * @param remoteIPv4Address Remote IPv4 Address
+     */
+    public PcepFecObjectIPv4AdjacencyVer1(PcepObjectHeader fecObjHeader, int localIPv4Address, int remoteIPv4Address) {
+        this.fecObjHeader = fecObjHeader;
+        this.localIPv4Address = localIPv4Address;
+        this.remoteIPv4Address = remoteIPv4Address;
+    }
+
+    /**
+     * Sets Object header.
+     *
+     * @param obj Pcep fec Object Header
+     */
+    public void setFecIpv4ObjHeader(PcepObjectHeader obj) {
+        this.fecObjHeader = obj;
+    }
+
+    @Override
+    public int getLocalIPv4Address() {
+        return this.localIPv4Address;
+    }
+
+    @Override
+    public void seLocalIPv4Address(int value) {
+        this.localIPv4Address = value;
+    }
+
+    @Override
+    public int getRemoteIPv4Address() {
+        return this.remoteIPv4Address;
+    }
+
+    @Override
+    public void seRemoteIPv4Address(int value) {
+        this.remoteIPv4Address = value;
+    }
+
+    /**
+     * Reads from channel buffer and Returns object of PcepFecObjectIPv4Adjacency.
+     *
+     * @param cb of channel buffer.
+     * @return object of PcepFecObjectIPv4Adjacency
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepFecObjectIPv4Adjacency read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader fecObjHeader;
+        int localIPv4Address;
+        int remoteIPv4Address;
+
+        fecObjHeader = PcepObjectHeader.read(cb);
+
+        //take only FEC IPv4 Adjacency Object buffer.
+        ChannelBuffer tempCb = cb.readBytes(fecObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
+        localIPv4Address = tempCb.readInt();
+        remoteIPv4Address = tempCb.readInt();
+
+        return new PcepFecObjectIPv4AdjacencyVer1(fecObjHeader, localIPv4Address, remoteIPv4Address);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+
+        //Write common header
+        int objLenIndex = fecObjHeader.write(cb);
+        cb.writeInt(localIPv4Address);
+        cb.writeInt(remoteIPv4Address);
+
+        //Now write FEC IPv4 Adjacency Object Length
+        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
+        return cb.writerIndex();
+    }
+
+    /**
+     * Builder class for PCEP fec object IPv4 Adjacency.
+     */
+    public static class Builder implements PcepFecObjectIPv4Adjacency.Builder {
+        private boolean bIsHeaderSet = false;
+        private boolean bIsLocalIPv4Addressset = false;
+        private boolean bIsRemoteIPv4Addressset = false;
+
+        private PcepObjectHeader fecObjHeader;
+        int localIPv4Address;
+        int remoteIPv4Address;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepFecObjectIPv4Adjacency build() throws PcepParseException {
+            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
+
+            if (!this.bIsLocalIPv4Addressset) {
+                throw new PcepParseException(
+                        "Local IPv4 Address not set while building PcepFecObjectIPv4Adjacency object.");
+            }
+
+            if (!this.bIsRemoteIPv4Addressset) {
+                throw new PcepParseException(
+                        " Remote IPv4 Address not set while building PcepFecObjectIPv4Adjacency object.");
+            }
+
+            if (bIsPFlagSet) {
+                fecObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                fecObjHeader.setIFlag(bIFlag);
+            }
+            return new PcepFecObjectIPv4AdjacencyVer1(fecObjHeader, this.localIPv4Address, this.remoteIPv4Address);
+        }
+
+        @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 PcepObjectHeader getFecIpv4AdjacencyObjHeader() {
+            return this.fecObjHeader;
+        }
+
+        @Override
+        public Builder setFecIpv4AdjacencyObjHeader(PcepObjectHeader obj) {
+            this.fecObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getLocalIPv4Address() {
+            return this.localIPv4Address;
+        }
+
+        @Override
+        public Builder seLocalIPv4Address(int value) {
+            this.localIPv4Address = value;
+            this.bIsLocalIPv4Addressset = true;
+            return this;
+        }
+
+        @Override
+        public int getRemoteIPv4Address() {
+            return this.remoteIPv4Address;
+        }
+
+        @Override
+        public Builder seRemoteIPv4Address(int value) {
+            this.remoteIPv4Address = value;
+            this.bIsRemoteIPv4Addressset = true;
+            return this;
+        }
+
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public int getType() {
+        return FEC_OBJ_TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("fecObjHeader", fecObjHeader)
+                .add("localIPv4Address", localIPv4Address).add("remoteIPv4Address", remoteIPv4Address).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4UnnumberedAdjacencyVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4UnnumberedAdjacencyVer1.java
index 8fb5c9d..021e37d 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4UnnumberedAdjacencyVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4UnnumberedAdjacencyVer1.java
@@ -1,333 +1,333 @@
-/*
- * 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 org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepFecObjectIPv4UnnumberedAdjacency;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Fec Object IPv4 Unnumbered Adjacency object.
- */
-public class PcepFecObjectIPv4UnnumberedAdjacencyVer1 implements PcepFecObjectIPv4UnnumberedAdjacency {
-
-    /*
-     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
-     *
-        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
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                       Local Node-ID                           |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                       Local Interface ID                      |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                       Remote Node-ID                          |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                       Remote Interface ID                     |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-             FEC Object-Type is 5, Unnumbered Adjacency with IPv4 NodeIDs
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4UnnumberedAdjacencyVer1.class);
-
-    public static final byte FEC_OBJ_TYPE = 5;
-    public static final byte FEC_OBJ_CLASS = 63; //to be defined
-    public static final byte FEC_OBJECT_VERSION = 1;
-    public static final short FEC_OBJ_MINIMUM_LENGTH = 20;
-    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
-
-    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader fecObjHeader;
-    private int localNodeID;
-    private int localInterfaceID;
-    private int remoteNodeID;
-    private int remoteInterfaceID;
-
-    /**
-     * Constructor to initialize parameter for PCEP fec object.
-     *
-     * @param fecObjHeader fec object header
-     * @param localNodeID local node ID
-     * @param localInterfaceID local interface ID
-     * @param remoteNodeID remote node ID
-     * @param remoteInterfaceID remote interface ID
-     */
-    public PcepFecObjectIPv4UnnumberedAdjacencyVer1(PcepObjectHeader fecObjHeader, int localNodeID,
-            int localInterfaceID, int remoteNodeID, int remoteInterfaceID) {
-        this.fecObjHeader = fecObjHeader;
-        this.localNodeID = localNodeID;
-        this.localInterfaceID = localInterfaceID;
-        this.remoteNodeID = remoteNodeID;
-        this.remoteInterfaceID = remoteInterfaceID;
-    }
-
-    /**
-     * Sets Object Header.
-     *
-     * @param obj object header
-     */
-    public void setFecIpv4UnnumberedAdjacencyObjHeader(PcepObjectHeader obj) {
-        this.fecObjHeader = obj;
-    }
-
-    @Override
-    public void setLocalNodeID(int localNodeID) {
-        this.localNodeID = localNodeID;
-    }
-
-    /**
-     * Returns Object Header.
-     *
-     * @return fecObjHeader fec object header
-     */
-    public PcepObjectHeader getFecIpv4UnnumberedAdjacencyObjHeader() {
-        return this.fecObjHeader;
-    }
-
-    @Override
-    public int getLocalNodeID() {
-        return this.localNodeID;
-    }
-
-    @Override
-    public int getLocalInterfaceID() {
-        return this.localInterfaceID;
-    }
-
-    @Override
-    public void setLocalInterfaceID(int localInterfaceID) {
-        this.localInterfaceID = localInterfaceID;
-    }
-
-    @Override
-    public int getRemoteNodeID() {
-        return this.remoteNodeID;
-    }
-
-    @Override
-    public void setRemoteNodeID(int remoteNodeID) {
-        this.remoteNodeID = remoteNodeID;
-    }
-
-    @Override
-    public int getRemoteInterfaceID() {
-        return this.remoteInterfaceID;
-    }
-
-    @Override
-    public void setRemoteInterfaceID(int remoteInterfaceID) {
-        this.remoteInterfaceID = remoteInterfaceID;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of PcepFecObjectIPv4UnnumberedAdjacency.
-     *
-     * @param cb of channel buffer
-     * @return object of PcepFecObjectIPv4UnnumberedAdjacency
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepFecObjectIPv4UnnumberedAdjacency read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader fecObjHeader;
-        int localNodeID;
-        int localInterfaceID;
-        int remoteNodeID;
-        int remoteInterfaceID;
-
-        fecObjHeader = PcepObjectHeader.read(cb);
-
-        //take only FEC IPv4 Unnumbered Adjacency Object buffer.
-        ChannelBuffer tempCb = cb.readBytes(fecObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
-        localNodeID = tempCb.readInt();
-        localInterfaceID = tempCb.readInt();
-        remoteNodeID = tempCb.readInt();
-        remoteInterfaceID = tempCb.readInt();
-
-        return new PcepFecObjectIPv4UnnumberedAdjacencyVer1(fecObjHeader, localNodeID, localInterfaceID, remoteNodeID,
-                remoteInterfaceID);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        int objStartIndex = cb.writerIndex();
-
-        //Write common header
-        int objLenIndex = fecObjHeader.write(cb);
-        cb.writeInt(localNodeID);
-        cb.writeInt(localInterfaceID);
-        cb.writeInt(remoteNodeID);
-        cb.writeInt(remoteInterfaceID);
-
-        //Now write FEC IPv4 Unnumbered Adjacency Object Length
-        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
-
-        return cb.writerIndex();
-    }
-
-    /**
-     * Builder class for PCEP Fec object IPv4 unnumbered Adjacency.
-     */
-    public static class Builder implements PcepFecObjectIPv4UnnumberedAdjacency.Builder {
-        private boolean bIsHeaderSet = false;
-        private boolean bIsLocalNodeIDset = false;
-        private boolean bIsLocalInterfaceIDset = false;
-        private boolean bIsRemoteNodeIDset = false;
-        private boolean bIsRemoteInterfaceIDset = false;
-
-        private PcepObjectHeader fecObjHeader;
-        private int localNodeID;
-        private int localInterfaceID;
-        private int remoteNodeID;
-        private int remoteInterfaceID;
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepFecObjectIPv4UnnumberedAdjacency build() throws PcepParseException {
-            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
-
-            if (!this.bIsLocalNodeIDset) {
-                throw new PcepParseException(
-                        " Local Node ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object.");
-            }
-            if (!this.bIsLocalInterfaceIDset) {
-                throw new PcepParseException(
-                        " Local Interface ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object.");
-            }
-            if (!this.bIsRemoteNodeIDset) {
-                throw new PcepParseException(
-                        " Remote Node ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object.");
-            }
-            if (!this.bIsRemoteInterfaceIDset) {
-                throw new PcepParseException(
-                        " Remote Interface ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object.");
-            }
-            if (bIsPFlagSet) {
-                fecObjHeader.setPFlag(bPFlag);
-            }
-            if (bIsIFlagSet) {
-                fecObjHeader.setIFlag(bIFlag);
-            }
-            return new PcepFecObjectIPv4UnnumberedAdjacencyVer1(fecObjHeader, this.localNodeID, this.localInterfaceID,
-                    this.remoteNodeID, this.remoteInterfaceID);
-        }
-
-        @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 PcepObjectHeader getFecIpv4UnnumberedAdjacencyObjHeader() {
-            return this.fecObjHeader;
-        }
-
-        @Override
-        public Builder setFecIpv4UnnumberedAdjacencyObjHeader(PcepObjectHeader obj) {
-            this.fecObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public int getLocalNodeID() {
-            return this.localNodeID;
-        }
-
-        @Override
-        public Builder setLocalNodeID(int value) {
-            this.localNodeID = value;
-            this.bIsLocalNodeIDset = true;
-            return this;
-        }
-
-        @Override
-        public int getLocalInterfaceID() {
-            return this.localInterfaceID;
-        }
-
-        @Override
-        public Builder setLocalInterfaceID(int value) {
-            this.localInterfaceID = value;
-            this.bIsLocalInterfaceIDset = true;
-            return this;
-        }
-
-        @Override
-        public int getRemoteNodeID() {
-            return this.remoteNodeID;
-        }
-
-        @Override
-        public Builder setRemoteNodeID(int value) {
-            this.remoteNodeID = value;
-            this.bIsRemoteNodeIDset = true;
-            return this;
-        }
-
-        @Override
-        public int getRemoteInterfaceID() {
-            return this.remoteInterfaceID;
-        }
-
-        @Override
-        public Builder setRemoteInterfaceID(int value) {
-            this.remoteInterfaceID = value;
-            this.bIsRemoteInterfaceIDset = true;
-            return this;
-        }
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public int getType() {
-        return FEC_OBJ_TYPE;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("LocalNodeID: ", localNodeID)
-                .add("LocalInterfaceID: ", localInterfaceID).add("RemoteNodeID: ", remoteNodeID)
-                .add("RemoteInterfaceID: ", remoteInterfaceID).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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv4UnnumberedAdjacency;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Fec Object IPv4 Unnumbered Adjacency object.
+ */
+public class PcepFecObjectIPv4UnnumberedAdjacencyVer1 implements PcepFecObjectIPv4UnnumberedAdjacency {
+
+    /*
+     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
+     *
+        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
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Local Node-ID                           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Local Interface ID                      |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Remote Node-ID                          |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                       Remote Interface ID                     |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+             FEC Object-Type is 5, Unnumbered Adjacency with IPv4 NodeIDs
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4UnnumberedAdjacencyVer1.class);
+
+    public static final byte FEC_OBJ_TYPE = 5;
+    public static final byte FEC_OBJ_CLASS = 63; //to be defined
+    public static final byte FEC_OBJECT_VERSION = 1;
+    public static final short FEC_OBJ_MINIMUM_LENGTH = 20;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+
+    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader fecObjHeader;
+    private int localNodeID;
+    private int localInterfaceID;
+    private int remoteNodeID;
+    private int remoteInterfaceID;
+
+    /**
+     * Constructor to initialize parameter for PCEP fec object.
+     *
+     * @param fecObjHeader fec object header
+     * @param localNodeID local node ID
+     * @param localInterfaceID local interface ID
+     * @param remoteNodeID remote node ID
+     * @param remoteInterfaceID remote interface ID
+     */
+    public PcepFecObjectIPv4UnnumberedAdjacencyVer1(PcepObjectHeader fecObjHeader, int localNodeID,
+            int localInterfaceID, int remoteNodeID, int remoteInterfaceID) {
+        this.fecObjHeader = fecObjHeader;
+        this.localNodeID = localNodeID;
+        this.localInterfaceID = localInterfaceID;
+        this.remoteNodeID = remoteNodeID;
+        this.remoteInterfaceID = remoteInterfaceID;
+    }
+
+    /**
+     * Sets Object Header.
+     *
+     * @param obj object header
+     */
+    public void setFecIpv4UnnumberedAdjacencyObjHeader(PcepObjectHeader obj) {
+        this.fecObjHeader = obj;
+    }
+
+    @Override
+    public void setLocalNodeID(int localNodeID) {
+        this.localNodeID = localNodeID;
+    }
+
+    /**
+     * Returns Object Header.
+     *
+     * @return fecObjHeader fec object header
+     */
+    public PcepObjectHeader getFecIpv4UnnumberedAdjacencyObjHeader() {
+        return this.fecObjHeader;
+    }
+
+    @Override
+    public int getLocalNodeID() {
+        return this.localNodeID;
+    }
+
+    @Override
+    public int getLocalInterfaceID() {
+        return this.localInterfaceID;
+    }
+
+    @Override
+    public void setLocalInterfaceID(int localInterfaceID) {
+        this.localInterfaceID = localInterfaceID;
+    }
+
+    @Override
+    public int getRemoteNodeID() {
+        return this.remoteNodeID;
+    }
+
+    @Override
+    public void setRemoteNodeID(int remoteNodeID) {
+        this.remoteNodeID = remoteNodeID;
+    }
+
+    @Override
+    public int getRemoteInterfaceID() {
+        return this.remoteInterfaceID;
+    }
+
+    @Override
+    public void setRemoteInterfaceID(int remoteInterfaceID) {
+        this.remoteInterfaceID = remoteInterfaceID;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of PcepFecObjectIPv4UnnumberedAdjacency.
+     *
+     * @param cb of channel buffer
+     * @return object of PcepFecObjectIPv4UnnumberedAdjacency
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepFecObjectIPv4UnnumberedAdjacency read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader fecObjHeader;
+        int localNodeID;
+        int localInterfaceID;
+        int remoteNodeID;
+        int remoteInterfaceID;
+
+        fecObjHeader = PcepObjectHeader.read(cb);
+
+        //take only FEC IPv4 Unnumbered Adjacency Object buffer.
+        ChannelBuffer tempCb = cb.readBytes(fecObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
+        localNodeID = tempCb.readInt();
+        localInterfaceID = tempCb.readInt();
+        remoteNodeID = tempCb.readInt();
+        remoteInterfaceID = tempCb.readInt();
+
+        return new PcepFecObjectIPv4UnnumberedAdjacencyVer1(fecObjHeader, localNodeID, localInterfaceID, remoteNodeID,
+                remoteInterfaceID);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+
+        //Write common header
+        int objLenIndex = fecObjHeader.write(cb);
+        cb.writeInt(localNodeID);
+        cb.writeInt(localInterfaceID);
+        cb.writeInt(remoteNodeID);
+        cb.writeInt(remoteInterfaceID);
+
+        //Now write FEC IPv4 Unnumbered Adjacency Object Length
+        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
+
+        return cb.writerIndex();
+    }
+
+    /**
+     * Builder class for PCEP Fec object IPv4 unnumbered Adjacency.
+     */
+    public static class Builder implements PcepFecObjectIPv4UnnumberedAdjacency.Builder {
+        private boolean bIsHeaderSet = false;
+        private boolean bIsLocalNodeIDset = false;
+        private boolean bIsLocalInterfaceIDset = false;
+        private boolean bIsRemoteNodeIDset = false;
+        private boolean bIsRemoteInterfaceIDset = false;
+
+        private PcepObjectHeader fecObjHeader;
+        private int localNodeID;
+        private int localInterfaceID;
+        private int remoteNodeID;
+        private int remoteInterfaceID;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepFecObjectIPv4UnnumberedAdjacency build() throws PcepParseException {
+            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
+
+            if (!this.bIsLocalNodeIDset) {
+                throw new PcepParseException(
+                        " Local Node ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object.");
+            }
+            if (!this.bIsLocalInterfaceIDset) {
+                throw new PcepParseException(
+                        " Local Interface ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object.");
+            }
+            if (!this.bIsRemoteNodeIDset) {
+                throw new PcepParseException(
+                        " Remote Node ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object.");
+            }
+            if (!this.bIsRemoteInterfaceIDset) {
+                throw new PcepParseException(
+                        " Remote Interface ID not set while building PcepFecObjectIPv4UnnumberedAdjacency object.");
+            }
+            if (bIsPFlagSet) {
+                fecObjHeader.setPFlag(bPFlag);
+            }
+            if (bIsIFlagSet) {
+                fecObjHeader.setIFlag(bIFlag);
+            }
+            return new PcepFecObjectIPv4UnnumberedAdjacencyVer1(fecObjHeader, this.localNodeID, this.localInterfaceID,
+                    this.remoteNodeID, this.remoteInterfaceID);
+        }
+
+        @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 PcepObjectHeader getFecIpv4UnnumberedAdjacencyObjHeader() {
+            return this.fecObjHeader;
+        }
+
+        @Override
+        public Builder setFecIpv4UnnumberedAdjacencyObjHeader(PcepObjectHeader obj) {
+            this.fecObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getLocalNodeID() {
+            return this.localNodeID;
+        }
+
+        @Override
+        public Builder setLocalNodeID(int value) {
+            this.localNodeID = value;
+            this.bIsLocalNodeIDset = true;
+            return this;
+        }
+
+        @Override
+        public int getLocalInterfaceID() {
+            return this.localInterfaceID;
+        }
+
+        @Override
+        public Builder setLocalInterfaceID(int value) {
+            this.localInterfaceID = value;
+            this.bIsLocalInterfaceIDset = true;
+            return this;
+        }
+
+        @Override
+        public int getRemoteNodeID() {
+            return this.remoteNodeID;
+        }
+
+        @Override
+        public Builder setRemoteNodeID(int value) {
+            this.remoteNodeID = value;
+            this.bIsRemoteNodeIDset = true;
+            return this;
+        }
+
+        @Override
+        public int getRemoteInterfaceID() {
+            return this.remoteInterfaceID;
+        }
+
+        @Override
+        public Builder setRemoteInterfaceID(int value) {
+            this.remoteInterfaceID = value;
+            this.bIsRemoteInterfaceIDset = true;
+            return this;
+        }
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public int getType() {
+        return FEC_OBJ_TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("LocalNodeID: ", localNodeID)
+                .add("LocalInterfaceID: ", localInterfaceID).add("RemoteNodeID: ", remoteNodeID)
+                .add("RemoteInterfaceID: ", remoteInterfaceID).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4Ver1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4Ver1.java
index 6c25157..953a5d6 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4Ver1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv4Ver1.java
@@ -1,215 +1,215 @@
-/*
- * 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 org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepFecObjectIPv4;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Fec Object IPv4 object.
- */
-public class PcepFecObjectIPv4Ver1 implements PcepFecObjectIPv4 {
-
-    /*
-     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
-     *
-        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
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                        IPv4 Node ID                           |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                       FEC Object-Type is 1 IPv4 Node ID
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4Ver1.class);
-
-    public static final byte FEC_OBJ_TYPE = 1;
-    public static final byte FEC_OBJ_CLASS = 63; //to be defined
-    public static final byte FEC_OBJECT_VERSION = 1;
-    public static final short FEC_OBJ_MINIMUM_LENGTH = 8;
-    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
-
-    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader fecObjHeader;
-    private int nodeID;
-
-    /**
-     * Constructor to initialize parameters for PCEP fec object.
-     *
-     * @param fecObjHeader fec object header
-     * @param nodeID node id
-     */
-    public PcepFecObjectIPv4Ver1(PcepObjectHeader fecObjHeader, int nodeID) {
-        this.fecObjHeader = fecObjHeader;
-        this.nodeID = nodeID;
-    }
-
-    /**
-     * Sets the Object Header.
-     *
-     * @param obj object header
-     */
-    public void setFecIpv4ObjHeader(PcepObjectHeader obj) {
-        this.fecObjHeader = obj;
-    }
-
-    @Override
-    public void setNodeID(int nodeID) {
-        this.nodeID = nodeID;
-    }
-
-    /**
-     * Returns Object Header.
-     *
-     * @return fecObjHeader fec object header
-     */
-    public PcepObjectHeader getFecIpv4ObjHeader() {
-        return this.fecObjHeader;
-    }
-
-    @Override
-    public int getNodeID() {
-        return this.nodeID;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of PcepFecObjectIPv4.
-     *
-     * @param cb of channel buffer
-     * @return object of PcepFecObjectIPv4
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepFecObjectIPv4 read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader fecObjHeader;
-        int nodeID;
-        fecObjHeader = PcepObjectHeader.read(cb);
-        nodeID = cb.readInt();
-        return new PcepFecObjectIPv4Ver1(fecObjHeader, nodeID);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        int objStartIndex = cb.writerIndex();
-
-        //write common header
-        int objLenIndex = fecObjHeader.write(cb);
-        cb.writeInt(nodeID);
-
-        //now write FEC IPv4 Object Length
-        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
-        return cb.writerIndex();
-    }
-
-    /**
-     * Builder class for PCEP fec pobject IPv4.
-     */
-    public static class Builder implements PcepFecObjectIPv4.Builder {
-        private boolean bIsHeaderSet = false;
-        private boolean bIsNodeIdset = false;
-
-        private PcepObjectHeader fecObjHeader;
-        private int nodeID;
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepFecObjectIPv4 build() throws PcepParseException {
-            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
-
-            if (!this.bIsNodeIdset) {
-                throw new PcepParseException("NodeID not set while building PcepFecObjectIPv4 object.");
-            }
-            if (bIsPFlagSet) {
-                fecObjHeader.setPFlag(bPFlag);
-            }
-            if (bIsIFlagSet) {
-                fecObjHeader.setIFlag(bIFlag);
-            }
-            return new PcepFecObjectIPv4Ver1(fecObjHeader, this.nodeID);
-        }
-
-        @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 PcepObjectHeader getFecIpv4ObjHeader() {
-            return this.fecObjHeader;
-        }
-
-        @Override
-        public Builder setFecIpv4ObjHeader(PcepObjectHeader obj) {
-            this.fecObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public int getNodeID() {
-            return this.nodeID;
-        }
-
-        @Override
-        public Builder setNodeID(int value) {
-            this.nodeID = value;
-            this.bIsNodeIdset = true;
-            return this;
-        }
-
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public int getType() {
-        return FEC_OBJ_TYPE;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("fecObjHeader", fecObjHeader).add("nodeID: ", nodeID)
-                .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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv4;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Fec Object IPv4 object.
+ */
+public class PcepFecObjectIPv4Ver1 implements PcepFecObjectIPv4 {
+
+    /*
+     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
+     *
+        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
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                        IPv4 Node ID                           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                       FEC Object-Type is 1 IPv4 Node ID
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv4Ver1.class);
+
+    public static final byte FEC_OBJ_TYPE = 1;
+    public static final byte FEC_OBJ_CLASS = 63; //to be defined
+    public static final byte FEC_OBJECT_VERSION = 1;
+    public static final short FEC_OBJ_MINIMUM_LENGTH = 8;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+
+    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader fecObjHeader;
+    private int nodeID;
+
+    /**
+     * Constructor to initialize parameters for PCEP fec object.
+     *
+     * @param fecObjHeader fec object header
+     * @param nodeID node id
+     */
+    public PcepFecObjectIPv4Ver1(PcepObjectHeader fecObjHeader, int nodeID) {
+        this.fecObjHeader = fecObjHeader;
+        this.nodeID = nodeID;
+    }
+
+    /**
+     * Sets the Object Header.
+     *
+     * @param obj object header
+     */
+    public void setFecIpv4ObjHeader(PcepObjectHeader obj) {
+        this.fecObjHeader = obj;
+    }
+
+    @Override
+    public void setNodeID(int nodeID) {
+        this.nodeID = nodeID;
+    }
+
+    /**
+     * Returns Object Header.
+     *
+     * @return fecObjHeader fec object header
+     */
+    public PcepObjectHeader getFecIpv4ObjHeader() {
+        return this.fecObjHeader;
+    }
+
+    @Override
+    public int getNodeID() {
+        return this.nodeID;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of PcepFecObjectIPv4.
+     *
+     * @param cb of channel buffer
+     * @return object of PcepFecObjectIPv4
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepFecObjectIPv4 read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader fecObjHeader;
+        int nodeID;
+        fecObjHeader = PcepObjectHeader.read(cb);
+        nodeID = cb.readInt();
+        return new PcepFecObjectIPv4Ver1(fecObjHeader, nodeID);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+
+        //write common header
+        int objLenIndex = fecObjHeader.write(cb);
+        cb.writeInt(nodeID);
+
+        //now write FEC IPv4 Object Length
+        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
+        return cb.writerIndex();
+    }
+
+    /**
+     * Builder class for PCEP fec pobject IPv4.
+     */
+    public static class Builder implements PcepFecObjectIPv4.Builder {
+        private boolean bIsHeaderSet = false;
+        private boolean bIsNodeIdset = false;
+
+        private PcepObjectHeader fecObjHeader;
+        private int nodeID;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepFecObjectIPv4 build() throws PcepParseException {
+            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
+
+            if (!this.bIsNodeIdset) {
+                throw new PcepParseException("NodeID not set while building PcepFecObjectIPv4 object.");
+            }
+            if (bIsPFlagSet) {
+                fecObjHeader.setPFlag(bPFlag);
+            }
+            if (bIsIFlagSet) {
+                fecObjHeader.setIFlag(bIFlag);
+            }
+            return new PcepFecObjectIPv4Ver1(fecObjHeader, this.nodeID);
+        }
+
+        @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 PcepObjectHeader getFecIpv4ObjHeader() {
+            return this.fecObjHeader;
+        }
+
+        @Override
+        public Builder setFecIpv4ObjHeader(PcepObjectHeader obj) {
+            this.fecObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getNodeID() {
+            return this.nodeID;
+        }
+
+        @Override
+        public Builder setNodeID(int value) {
+            this.nodeID = value;
+            this.bIsNodeIdset = true;
+            return this;
+        }
+
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public int getType() {
+        return FEC_OBJ_TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("fecObjHeader", fecObjHeader).add("nodeID: ", nodeID)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6AdjacencyVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6AdjacencyVer1.java
index b50dbed..5205961 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6AdjacencyVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6AdjacencyVer1.java
@@ -1,247 +1,247 @@
-/*
- * 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 org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepFecObjectIPv6Adjacency;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Fec Object IPv6 Adjacency object.
- */
-public class PcepFecObjectIPv6AdjacencyVer1 implements PcepFecObjectIPv6Adjacency {
-
-    /*
-     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
-     *
-            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
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |                                                               |
-           //              Local IPv6 address (16 bytes)                   //
-           |                                                               |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |                                                               |
-           //              Remote IPv6 address (16 bytes)                  //
-           |                                                               |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                      FEC Object-Type is 4 IPv6 Adjacency
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv6AdjacencyVer1.class);
-
-    public static final byte FEC_OBJ_TYPE = 4;
-    public static final byte FEC_OBJ_CLASS = 63; //to be defined
-    public static final byte FEC_OBJECT_VERSION = 1;
-    public static final short FEC_OBJ_MINIMUM_LENGTH = 36;
-    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
-    public static final int IPV6_ADDRESS_LENGTH = 16;
-
-    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader fecObjHeader;
-    private byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
-    private byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
-
-    /**
-     * Constructor to initialize parameters for PCEP fec object.
-     *
-     * @param fecObjHeader fec object header
-     * @param localIPv6Address local IPv6 address
-     * @param remoteIPv6Address remote IPv6 address
-     */
-    public PcepFecObjectIPv6AdjacencyVer1(PcepObjectHeader fecObjHeader, byte[] localIPv6Address,
-            byte[] remoteIPv6Address) {
-        this.fecObjHeader = fecObjHeader;
-        this.localIPv6Address = localIPv6Address;
-        this.remoteIPv6Address = remoteIPv6Address;
-    }
-
-    /**
-     * Sets Object Header.
-     *
-     * @param obj object header
-     */
-    public void setFecIpv4ObjHeader(PcepObjectHeader obj) {
-        this.fecObjHeader = obj;
-    }
-
-    @Override
-    public byte[] getLocalIPv6Address() {
-        return this.localIPv6Address;
-    }
-
-    @Override
-    public void seLocalIPv6Address(byte[] value) {
-        this.localIPv6Address = value;
-    }
-
-    @Override
-    public byte[] getRemoteIPv6Address() {
-        return this.remoteIPv6Address;
-    }
-
-    @Override
-    public void seRemoteIPv6Address(byte[] value) {
-        this.remoteIPv6Address = value;
-    }
-
-    /**
-     * Reads channel buffer and Returns object of PcepFecObjectIPv6Adjacency.
-     *
-     * @param cb of channel buffer
-     * @return object of PcepFecObjectIPv6Adjacency
-     * @throws PcepParseException when fails tp read from channel buffer
-     */
-    public static PcepFecObjectIPv6Adjacency read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader fecObjHeader;
-        byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
-        byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
-        fecObjHeader = PcepObjectHeader.read(cb);
-        cb.readBytes(localIPv6Address, 0, IPV6_ADDRESS_LENGTH);
-        cb.readBytes(remoteIPv6Address, 0, IPV6_ADDRESS_LENGTH);
-        return new PcepFecObjectIPv6AdjacencyVer1(fecObjHeader, localIPv6Address, remoteIPv6Address);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        int objStartIndex = cb.writerIndex();
-
-        //write common header
-        int objLenIndex = fecObjHeader.write(cb);
-        cb.writeBytes(localIPv6Address);
-        cb.writeBytes(remoteIPv6Address);
-        //now write FEC IPv6 Adjacency Object Length
-        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
-        return cb.writerIndex();
-    }
-
-    /**
-     * Builder class for PCEP fec object IPv6 Adjacency.
-     */
-    public static class Builder implements PcepFecObjectIPv6Adjacency.Builder {
-        private boolean bIsHeaderSet = false;
-        private boolean bIsLocalIPv6Addressset = false;
-        private boolean bIsRemoteIPv6Addressset = false;
-
-        private PcepObjectHeader fecObjHeader;
-        byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
-        byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepFecObjectIPv6Adjacency build() throws PcepParseException {
-            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
-
-            if (!this.bIsLocalIPv6Addressset) {
-                throw new PcepParseException(
-                        "Local IPv6 Address not set while building PcepFecObjectIPv6Adjacency object.");
-            }
-            if (!this.bIsRemoteIPv6Addressset) {
-                throw new PcepParseException(
-                        "Remote IPv6 Address not set while building PcepFecObjectIPv6Adjacency object.");
-            }
-            if (bIsPFlagSet) {
-                fecObjHeader.setPFlag(bPFlag);
-            }
-            if (bIsIFlagSet) {
-                fecObjHeader.setIFlag(bIFlag);
-            }
-            return new PcepFecObjectIPv6AdjacencyVer1(fecObjHeader, this.localIPv6Address, this.remoteIPv6Address);
-        }
-
-        @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 PcepObjectHeader getFecIpv6AdjacencyObjHeader() {
-            return this.fecObjHeader;
-        }
-
-        @Override
-        public Builder setFecIpv6AdjacencyObjHeader(PcepObjectHeader obj) {
-            this.fecObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public byte[] getLocalIPv6Address() {
-            return this.localIPv6Address;
-        }
-
-        @Override
-        public Builder setLocalIPv6Address(byte[] value) {
-            this.localIPv6Address = value;
-            this.bIsLocalIPv6Addressset = true;
-            return this;
-        }
-
-        @Override
-        public byte[] getRemoteIPv6Address() {
-            return this.remoteIPv6Address;
-        }
-
-        @Override
-        public Builder setRemoteIPv6Address(byte[] value) {
-            this.remoteIPv6Address = value;
-            this.bIsRemoteIPv6Addressset = true;
-            return this;
-        }
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public int getType() {
-        return FEC_OBJ_TYPE;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("localIPv6Address", localIPv6Address)
-                .add("remoteIPv6Address: ", remoteIPv6Address).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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv6Adjacency;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Fec Object IPv6 Adjacency object.
+ */
+public class PcepFecObjectIPv6AdjacencyVer1 implements PcepFecObjectIPv6Adjacency {
+
+    /*
+     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
+     *
+            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
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |                                                               |
+           //              Local IPv6 address (16 bytes)                   //
+           |                                                               |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |                                                               |
+           //              Remote IPv6 address (16 bytes)                  //
+           |                                                               |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                      FEC Object-Type is 4 IPv6 Adjacency
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv6AdjacencyVer1.class);
+
+    public static final byte FEC_OBJ_TYPE = 4;
+    public static final byte FEC_OBJ_CLASS = 63; //to be defined
+    public static final byte FEC_OBJECT_VERSION = 1;
+    public static final short FEC_OBJ_MINIMUM_LENGTH = 36;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+    public static final int IPV6_ADDRESS_LENGTH = 16;
+
+    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader fecObjHeader;
+    private byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
+    private byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
+
+    /**
+     * Constructor to initialize parameters for PCEP fec object.
+     *
+     * @param fecObjHeader fec object header
+     * @param localIPv6Address local IPv6 address
+     * @param remoteIPv6Address remote IPv6 address
+     */
+    public PcepFecObjectIPv6AdjacencyVer1(PcepObjectHeader fecObjHeader, byte[] localIPv6Address,
+            byte[] remoteIPv6Address) {
+        this.fecObjHeader = fecObjHeader;
+        this.localIPv6Address = localIPv6Address;
+        this.remoteIPv6Address = remoteIPv6Address;
+    }
+
+    /**
+     * Sets Object Header.
+     *
+     * @param obj object header
+     */
+    public void setFecIpv4ObjHeader(PcepObjectHeader obj) {
+        this.fecObjHeader = obj;
+    }
+
+    @Override
+    public byte[] getLocalIPv6Address() {
+        return this.localIPv6Address;
+    }
+
+    @Override
+    public void seLocalIPv6Address(byte[] value) {
+        this.localIPv6Address = value;
+    }
+
+    @Override
+    public byte[] getRemoteIPv6Address() {
+        return this.remoteIPv6Address;
+    }
+
+    @Override
+    public void seRemoteIPv6Address(byte[] value) {
+        this.remoteIPv6Address = value;
+    }
+
+    /**
+     * Reads channel buffer and Returns object of PcepFecObjectIPv6Adjacency.
+     *
+     * @param cb of channel buffer
+     * @return object of PcepFecObjectIPv6Adjacency
+     * @throws PcepParseException when fails tp read from channel buffer
+     */
+    public static PcepFecObjectIPv6Adjacency read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader fecObjHeader;
+        byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
+        byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
+        fecObjHeader = PcepObjectHeader.read(cb);
+        cb.readBytes(localIPv6Address, 0, IPV6_ADDRESS_LENGTH);
+        cb.readBytes(remoteIPv6Address, 0, IPV6_ADDRESS_LENGTH);
+        return new PcepFecObjectIPv6AdjacencyVer1(fecObjHeader, localIPv6Address, remoteIPv6Address);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+
+        //write common header
+        int objLenIndex = fecObjHeader.write(cb);
+        cb.writeBytes(localIPv6Address);
+        cb.writeBytes(remoteIPv6Address);
+        //now write FEC IPv6 Adjacency Object Length
+        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
+        return cb.writerIndex();
+    }
+
+    /**
+     * Builder class for PCEP fec object IPv6 Adjacency.
+     */
+    public static class Builder implements PcepFecObjectIPv6Adjacency.Builder {
+        private boolean bIsHeaderSet = false;
+        private boolean bIsLocalIPv6Addressset = false;
+        private boolean bIsRemoteIPv6Addressset = false;
+
+        private PcepObjectHeader fecObjHeader;
+        byte[] localIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
+        byte[] remoteIPv6Address = new byte[IPV6_ADDRESS_LENGTH];
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepFecObjectIPv6Adjacency build() throws PcepParseException {
+            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
+
+            if (!this.bIsLocalIPv6Addressset) {
+                throw new PcepParseException(
+                        "Local IPv6 Address not set while building PcepFecObjectIPv6Adjacency object.");
+            }
+            if (!this.bIsRemoteIPv6Addressset) {
+                throw new PcepParseException(
+                        "Remote IPv6 Address not set while building PcepFecObjectIPv6Adjacency object.");
+            }
+            if (bIsPFlagSet) {
+                fecObjHeader.setPFlag(bPFlag);
+            }
+            if (bIsIFlagSet) {
+                fecObjHeader.setIFlag(bIFlag);
+            }
+            return new PcepFecObjectIPv6AdjacencyVer1(fecObjHeader, this.localIPv6Address, this.remoteIPv6Address);
+        }
+
+        @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 PcepObjectHeader getFecIpv6AdjacencyObjHeader() {
+            return this.fecObjHeader;
+        }
+
+        @Override
+        public Builder setFecIpv6AdjacencyObjHeader(PcepObjectHeader obj) {
+            this.fecObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public byte[] getLocalIPv6Address() {
+            return this.localIPv6Address;
+        }
+
+        @Override
+        public Builder setLocalIPv6Address(byte[] value) {
+            this.localIPv6Address = value;
+            this.bIsLocalIPv6Addressset = true;
+            return this;
+        }
+
+        @Override
+        public byte[] getRemoteIPv6Address() {
+            return this.remoteIPv6Address;
+        }
+
+        @Override
+        public Builder setRemoteIPv6Address(byte[] value) {
+            this.remoteIPv6Address = value;
+            this.bIsRemoteIPv6Addressset = true;
+            return this;
+        }
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public int getType() {
+        return FEC_OBJ_TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("localIPv6Address", localIPv6Address)
+                .add("remoteIPv6Address: ", remoteIPv6Address).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6Ver1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6Ver1.java
index 4d9422e..35e99b9 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6Ver1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepFecObjectIPv6Ver1.java
@@ -1,218 +1,218 @@
-/*
- * 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 org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepFecObjectIPv6;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Fec Object IPv6 object.
- */
-public class PcepFecObjectIPv6Ver1 implements PcepFecObjectIPv6 {
-
-    /*
-     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
-     *
-        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
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                                                               |
-       //                     IPv6 Node ID (16 bytes)                  //
-       |                                                               |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                       FEC Object-Type is 2 IPv6 Node ID
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv6Ver1.class);
-
-    public static final byte FEC_OBJ_TYPE = 2;
-    public static final byte FEC_OBJ_CLASS = 63; //to be defined
-    public static final byte FEC_OBJECT_VERSION = 1;
-    public static final short FEC_OBJ_MINIMUM_LENGTH = 20;
-    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
-    public static final int IPV6_ADDRESS_LENGTH = 16;
-
-    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader fecObjHeader;
-    private byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];
-
-    /**
-     * Constructor to initialize parameters for PCEP fec object.
-     *
-     * @param fecObjHeader Fec object header
-     * @param nodeID node ID
-     */
-    public PcepFecObjectIPv6Ver1(PcepObjectHeader fecObjHeader, byte[] nodeID) {
-        this.fecObjHeader = fecObjHeader;
-        this.nodeID = nodeID;
-    }
-
-    /**
-     * Sets the Object header.
-     *
-     * @param obj object header
-     */
-    public void setFecIpv6ObjHeader(PcepObjectHeader obj) {
-        this.fecObjHeader = obj;
-    }
-
-    @Override
-    public void setNodeID(byte[] nodeID) {
-        this.nodeID = nodeID;
-    }
-
-    /**
-     * Returns object header.
-     *
-     * @return fec Object Header
-     */
-    public PcepObjectHeader getFecIpv6ObjHeader() {
-        return this.fecObjHeader;
-    }
-
-    @Override
-    public byte[] getNodeID() {
-        return this.nodeID;
-    }
-
-    /**
-     * reads the channel buffer and returns object of PcepFecObjectIPv6.
-     *
-     * @param cb of channel buffer.
-     * @return object of PcepFecObjectIPv6
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepFecObjectIPv6 read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader fecObjHeader;
-        byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];
-        fecObjHeader = PcepObjectHeader.read(cb);
-        cb.readBytes(nodeID, 0, IPV6_ADDRESS_LENGTH);
-        return new PcepFecObjectIPv6Ver1(fecObjHeader, nodeID);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        int objStartIndex = cb.writerIndex();
-
-        //write common header
-        int objLenIndex = fecObjHeader.write(cb);
-        cb.writeBytes(nodeID);
-
-        //now write FEC IPv4 Object Length
-        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
-        return cb.writerIndex();
-    }
-
-    /**
-     * Builder class for PCEP fec object IPv6.
-     */
-    public static class Builder implements PcepFecObjectIPv6.Builder {
-        private boolean bIsHeaderSet = false;
-        private boolean bIsNodeIdset = false;
-
-        private PcepObjectHeader fecObjHeader;
-        private byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepFecObjectIPv6 build() throws PcepParseException {
-            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
-
-            if (!this.bIsNodeIdset) {
-                throw new PcepParseException(" NodeID not set while building PcepFecObjectIPv6 object.");
-            }
-            if (bIsPFlagSet) {
-                fecObjHeader.setPFlag(bPFlag);
-            }
-            if (bIsIFlagSet) {
-                fecObjHeader.setIFlag(bIFlag);
-            }
-            return new PcepFecObjectIPv6Ver1(fecObjHeader, this.nodeID);
-        }
-
-        @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 PcepObjectHeader getFecIpv6ObjHeader() {
-            return this.fecObjHeader;
-        }
-
-        @Override
-        public Builder setFecIpv6ObjHeader(PcepObjectHeader obj) {
-            this.fecObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public byte[] getNodeID() {
-            return this.nodeID;
-        }
-
-        @Override
-        public Builder setNodeID(byte[] value) {
-            this.nodeID = value;
-            this.bIsNodeIdset = true;
-            return this;
-        }
-
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public int getType() {
-        return FEC_OBJ_TYPE;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("fecObjHeader", fecObjHeader).add("NodeID: ", nodeID)
-                .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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepFecObjectIPv6;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Fec Object IPv6 object.
+ */
+public class PcepFecObjectIPv6Ver1 implements PcepFecObjectIPv6 {
+
+    /*
+     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01 , section : 7.5
+     *
+        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
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                                                               |
+       //                     IPv6 Node ID (16 bytes)                  //
+       |                                                               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                       FEC Object-Type is 2 IPv6 Node ID
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepFecObjectIPv6Ver1.class);
+
+    public static final byte FEC_OBJ_TYPE = 2;
+    public static final byte FEC_OBJ_CLASS = 63; //to be defined
+    public static final byte FEC_OBJECT_VERSION = 1;
+    public static final short FEC_OBJ_MINIMUM_LENGTH = 20;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+    public static final int IPV6_ADDRESS_LENGTH = 16;
+
+    static final PcepObjectHeader DEFAULT_FEC_OBJECT_HEADER = new PcepObjectHeader(FEC_OBJ_CLASS, FEC_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, FEC_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader fecObjHeader;
+    private byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];
+
+    /**
+     * Constructor to initialize parameters for PCEP fec object.
+     *
+     * @param fecObjHeader Fec object header
+     * @param nodeID node ID
+     */
+    public PcepFecObjectIPv6Ver1(PcepObjectHeader fecObjHeader, byte[] nodeID) {
+        this.fecObjHeader = fecObjHeader;
+        this.nodeID = nodeID;
+    }
+
+    /**
+     * Sets the Object header.
+     *
+     * @param obj object header
+     */
+    public void setFecIpv6ObjHeader(PcepObjectHeader obj) {
+        this.fecObjHeader = obj;
+    }
+
+    @Override
+    public void setNodeID(byte[] nodeID) {
+        this.nodeID = nodeID;
+    }
+
+    /**
+     * Returns object header.
+     *
+     * @return fec Object Header
+     */
+    public PcepObjectHeader getFecIpv6ObjHeader() {
+        return this.fecObjHeader;
+    }
+
+    @Override
+    public byte[] getNodeID() {
+        return this.nodeID;
+    }
+
+    /**
+     * reads the channel buffer and returns object of PcepFecObjectIPv6.
+     *
+     * @param cb of channel buffer.
+     * @return object of PcepFecObjectIPv6
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepFecObjectIPv6 read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader fecObjHeader;
+        byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];
+        fecObjHeader = PcepObjectHeader.read(cb);
+        cb.readBytes(nodeID, 0, IPV6_ADDRESS_LENGTH);
+        return new PcepFecObjectIPv6Ver1(fecObjHeader, nodeID);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+
+        //write common header
+        int objLenIndex = fecObjHeader.write(cb);
+        cb.writeBytes(nodeID);
+
+        //now write FEC IPv4 Object Length
+        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
+        return cb.writerIndex();
+    }
+
+    /**
+     * Builder class for PCEP fec object IPv6.
+     */
+    public static class Builder implements PcepFecObjectIPv6.Builder {
+        private boolean bIsHeaderSet = false;
+        private boolean bIsNodeIdset = false;
+
+        private PcepObjectHeader fecObjHeader;
+        private byte[] nodeID = new byte[IPV6_ADDRESS_LENGTH];
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepFecObjectIPv6 build() throws PcepParseException {
+            PcepObjectHeader fecObjHeader = this.bIsHeaderSet ? this.fecObjHeader : DEFAULT_FEC_OBJECT_HEADER;
+
+            if (!this.bIsNodeIdset) {
+                throw new PcepParseException(" NodeID not set while building PcepFecObjectIPv6 object.");
+            }
+            if (bIsPFlagSet) {
+                fecObjHeader.setPFlag(bPFlag);
+            }
+            if (bIsIFlagSet) {
+                fecObjHeader.setIFlag(bIFlag);
+            }
+            return new PcepFecObjectIPv6Ver1(fecObjHeader, this.nodeID);
+        }
+
+        @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 PcepObjectHeader getFecIpv6ObjHeader() {
+            return this.fecObjHeader;
+        }
+
+        @Override
+        public Builder setFecIpv6ObjHeader(PcepObjectHeader obj) {
+            this.fecObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public byte[] getNodeID() {
+            return this.nodeID;
+        }
+
+        @Override
+        public Builder setNodeID(byte[] value) {
+            this.nodeID = value;
+            this.bIsNodeIdset = true;
+            return this;
+        }
+
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public int getType() {
+        return FEC_OBJ_TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("fecObjHeader", fecObjHeader).add("NodeID: ", nodeID)
+                .toString();
+    }
+}
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();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java
index d09eb28..c26a3c4 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepInterLayerObjectVer1.java
@@ -1,262 +1,262 @@
-/*
- * 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 org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepInterLayerObject;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP inter layer object.
- */
-public class PcepInterLayerObjectVer1 implements PcepInterLayerObject {
-
-    /*
-     *      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
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        |    Reserved                                               |N|I|
-        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepInterLayerObjectVer1.class);
-
-    public static final byte INTER_LAYER_OBJ_TYPE = 1;
-    public static final byte INTER_LAYER_OBJ_CLASS = 18;
-    public static final byte INTER_LAYER_OBJECT_VERSION = 1;
-    public static final short INTER_LAYER_OBJ_MINIMUM_LENGTH = 8;
-    public static final boolean DEFAULT_IFLAG = false;
-    public static final boolean DEFAULT_NFLAG = false;
-    public static final int OBJECT_HEADER_LENGTH = 4;
-    public static final int NFLAG_SHIFT_VALUE = 0x02;
-    public static final int IFLAG_SHIFT_VALUE = 0x01;
-    public static final int FLAGS_SET_VALUE = 1;
-
-    static final PcepObjectHeader DEFAULT_INTER_LAYER_OBJECT_HEADER = new PcepObjectHeader(INTER_LAYER_OBJ_CLASS,
-            INTER_LAYER_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
-            INTER_LAYER_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader interLayerObjHeader;
-    private boolean bNFlag;
-    private boolean bIFlag;
-
-    /**
-     * Constructor to initialize all parameters for Pcep Inter Layer Object.
-     *
-     * @param interLayerObjHeader inter layer object header
-     * @param bNFlag N flag
-     * @param bIFlag I flag
-     */
-    public PcepInterLayerObjectVer1(PcepObjectHeader interLayerObjHeader, boolean bNFlag, boolean bIFlag) {
-
-        this.interLayerObjHeader = interLayerObjHeader;
-        this.bNFlag = bNFlag;
-        this.bIFlag = bIFlag;
-    }
-
-    /**
-     * Sets Object Header.
-     *
-     * @param obj object header
-     */
-    public void setInterLayerObjHeader(PcepObjectHeader obj) {
-        this.interLayerObjHeader = obj;
-    }
-
-    @Override
-    public void setbNFlag(boolean bNFlag) {
-        this.bNFlag = bNFlag;
-    }
-
-    @Override
-    public void setbIFlag(boolean bIFlag) {
-        this.bIFlag = bIFlag;
-    }
-
-    /**
-     * Returns object header.
-     *
-     * @return inter Layer Object Header
-     */
-    public PcepObjectHeader getInterLayerObjHeader() {
-        return this.interLayerObjHeader;
-    }
-
-    @Override
-    public boolean getbNFlag() {
-        return this.bNFlag;
-    }
-
-    @Override
-    public boolean getbIFlag() {
-        return this.bIFlag;
-    }
-
-    /**
-     * Reads channel buffer and returns object of PcepInterLayerObject.
-     *
-     * @param cb of type channel buffer
-     * @return object of PcepInterLayerObject
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepInterLayerObject read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader interLayerObjHeader;
-        boolean bNFlag;
-        boolean bIFlag;
-
-        interLayerObjHeader = PcepObjectHeader.read(cb);
-
-        //take only InterLayerObject buffer.
-        ChannelBuffer tempCb = cb.readBytes(interLayerObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
-
-        int iTemp = tempCb.readInt();
-        bIFlag = ((iTemp & (byte) IFLAG_SHIFT_VALUE) == FLAGS_SET_VALUE) ? true : false;
-        bNFlag = ((iTemp & (byte) NFLAG_SHIFT_VALUE) == FLAGS_SET_VALUE) ? true : false;
-
-        return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        //write Object header
-        int objStartIndex = cb.writerIndex();
-
-        int objLenIndex = interLayerObjHeader.write(cb);
-
-        if (objLenIndex <= 0) {
-            throw new PcepParseException(" ObjectLength Index is " + objLenIndex);
-        }
-
-        int iTemp = 0;
-
-        if (bIFlag) {
-            iTemp = iTemp | (byte) IFLAG_SHIFT_VALUE;
-        }
-        if (bNFlag) {
-            iTemp = iTemp | (byte) NFLAG_SHIFT_VALUE;
-        }
-
-        cb.writeInt(iTemp);
-
-        //Update object length now
-        int length = cb.writerIndex() - objStartIndex;
-        //will be helpful during print().
-        interLayerObjHeader.setObjLen((short) length);
-        cb.setShort(objLenIndex, (short) length);
-
-        objLenIndex = cb.writerIndex();
-        return objLenIndex;
-    }
-
-    /**
-     * Builder class for PCEP inter layer object.
-     */
-    public static class Builder implements PcepInterLayerObject.Builder {
-
-        private boolean bIsHeaderSet = false;
-        private boolean bIsNFlagset = false;
-        private boolean bIsIFlagset = false;
-
-        private PcepObjectHeader interLayerObjHeader;
-        private boolean bNFlag;
-        private boolean bIFlag;
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFalg;
-
-        private boolean bIsIFlagSet = false;
-        private boolean iFlag;
-
-        @Override
-        public PcepInterLayerObject build() {
-            PcepObjectHeader interLayerObjHeader = this.bIsHeaderSet ? this.interLayerObjHeader
-                    : DEFAULT_INTER_LAYER_OBJECT_HEADER;
-
-            boolean bNFlag = this.bIsNFlagset ? this.bNFlag : DEFAULT_NFLAG;
-            boolean bIFlag = this.bIsIFlagset ? this.bIFlag : DEFAULT_IFLAG;
-
-            if (bIsPFlagSet) {
-                interLayerObjHeader.setPFlag(bPFalg);
-            }
-
-            if (bIsIFlagSet) {
-                interLayerObjHeader.setIFlag(iFlag);
-            }
-            return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag);
-        }
-
-        @Override
-        public PcepObjectHeader getInterLayerObjHeader() {
-            return this.interLayerObjHeader;
-        }
-
-        @Override
-        public Builder setInterLayerObjHeader(PcepObjectHeader obj) {
-            this.interLayerObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public boolean getbNFlag() {
-            return this.bNFlag;
-        }
-
-        @Override
-        public Builder setbNFlag(boolean value) {
-            this.bNFlag = value;
-            this.bIsNFlagset = true;
-            return this;
-        }
-
-        @Override
-        public boolean getbIFlag() {
-            return this.bIFlag;
-        }
-
-        @Override
-        public Builder setbIFlag(boolean value) {
-            this.bIFlag = value;
-            this.bIsIFlagset = true;
-            return this;
-        }
-
-        @Override
-        public Builder setPFlag(boolean value) {
-            this.bPFalg = value;
-            this.bIsPFlagSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setIFlag(boolean value) {
-            this.iFlag = value;
-            this.bIsIFlagSet = true;
-            return this;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("IFlag", bIFlag).add("NFlag", bNFlag).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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepInterLayerObject;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP inter layer object.
+ */
+public class PcepInterLayerObjectVer1 implements PcepInterLayerObject {
+
+    /*
+     *      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
+        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        |    Reserved                                               |N|I|
+        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepInterLayerObjectVer1.class);
+
+    public static final byte INTER_LAYER_OBJ_TYPE = 1;
+    public static final byte INTER_LAYER_OBJ_CLASS = 18;
+    public static final byte INTER_LAYER_OBJECT_VERSION = 1;
+    public static final short INTER_LAYER_OBJ_MINIMUM_LENGTH = 8;
+    public static final boolean DEFAULT_IFLAG = false;
+    public static final boolean DEFAULT_NFLAG = false;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+    public static final int NFLAG_SHIFT_VALUE = 0x02;
+    public static final int IFLAG_SHIFT_VALUE = 0x01;
+    public static final int FLAGS_SET_VALUE = 1;
+
+    static final PcepObjectHeader DEFAULT_INTER_LAYER_OBJECT_HEADER = new PcepObjectHeader(INTER_LAYER_OBJ_CLASS,
+            INTER_LAYER_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
+            INTER_LAYER_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader interLayerObjHeader;
+    private boolean bNFlag;
+    private boolean bIFlag;
+
+    /**
+     * Constructor to initialize all parameters for Pcep Inter Layer Object.
+     *
+     * @param interLayerObjHeader inter layer object header
+     * @param bNFlag N flag
+     * @param bIFlag I flag
+     */
+    public PcepInterLayerObjectVer1(PcepObjectHeader interLayerObjHeader, boolean bNFlag, boolean bIFlag) {
+
+        this.interLayerObjHeader = interLayerObjHeader;
+        this.bNFlag = bNFlag;
+        this.bIFlag = bIFlag;
+    }
+
+    /**
+     * Sets Object Header.
+     *
+     * @param obj object header
+     */
+    public void setInterLayerObjHeader(PcepObjectHeader obj) {
+        this.interLayerObjHeader = obj;
+    }
+
+    @Override
+    public void setbNFlag(boolean bNFlag) {
+        this.bNFlag = bNFlag;
+    }
+
+    @Override
+    public void setbIFlag(boolean bIFlag) {
+        this.bIFlag = bIFlag;
+    }
+
+    /**
+     * Returns object header.
+     *
+     * @return inter Layer Object Header
+     */
+    public PcepObjectHeader getInterLayerObjHeader() {
+        return this.interLayerObjHeader;
+    }
+
+    @Override
+    public boolean getbNFlag() {
+        return this.bNFlag;
+    }
+
+    @Override
+    public boolean getbIFlag() {
+        return this.bIFlag;
+    }
+
+    /**
+     * Reads channel buffer and returns object of PcepInterLayerObject.
+     *
+     * @param cb of type channel buffer
+     * @return object of PcepInterLayerObject
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepInterLayerObject read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader interLayerObjHeader;
+        boolean bNFlag;
+        boolean bIFlag;
+
+        interLayerObjHeader = PcepObjectHeader.read(cb);
+
+        //take only InterLayerObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(interLayerObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+
+        int iTemp = tempCb.readInt();
+        bIFlag = ((iTemp & (byte) IFLAG_SHIFT_VALUE) == FLAGS_SET_VALUE) ? true : false;
+        bNFlag = ((iTemp & (byte) NFLAG_SHIFT_VALUE) == FLAGS_SET_VALUE) ? true : false;
+
+        return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        int objLenIndex = interLayerObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException(" ObjectLength Index is " + objLenIndex);
+        }
+
+        int iTemp = 0;
+
+        if (bIFlag) {
+            iTemp = iTemp | (byte) IFLAG_SHIFT_VALUE;
+        }
+        if (bNFlag) {
+            iTemp = iTemp | (byte) NFLAG_SHIFT_VALUE;
+        }
+
+        cb.writeInt(iTemp);
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+        //will be helpful during print().
+        interLayerObjHeader.setObjLen((short) length);
+        cb.setShort(objLenIndex, (short) length);
+
+        objLenIndex = cb.writerIndex();
+        return objLenIndex;
+    }
+
+    /**
+     * Builder class for PCEP inter layer object.
+     */
+    public static class Builder implements PcepInterLayerObject.Builder {
+
+        private boolean bIsHeaderSet = false;
+        private boolean bIsNFlagset = false;
+        private boolean bIsIFlagset = false;
+
+        private PcepObjectHeader interLayerObjHeader;
+        private boolean bNFlag;
+        private boolean bIFlag;
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFalg;
+
+        private boolean bIsIFlagSet = false;
+        private boolean iFlag;
+
+        @Override
+        public PcepInterLayerObject build() {
+            PcepObjectHeader interLayerObjHeader = this.bIsHeaderSet ? this.interLayerObjHeader
+                    : DEFAULT_INTER_LAYER_OBJECT_HEADER;
+
+            boolean bNFlag = this.bIsNFlagset ? this.bNFlag : DEFAULT_NFLAG;
+            boolean bIFlag = this.bIsIFlagset ? this.bIFlag : DEFAULT_IFLAG;
+
+            if (bIsPFlagSet) {
+                interLayerObjHeader.setPFlag(bPFalg);
+            }
+
+            if (bIsIFlagSet) {
+                interLayerObjHeader.setIFlag(iFlag);
+            }
+            return new PcepInterLayerObjectVer1(interLayerObjHeader, bNFlag, bIFlag);
+        }
+
+        @Override
+        public PcepObjectHeader getInterLayerObjHeader() {
+            return this.interLayerObjHeader;
+        }
+
+        @Override
+        public Builder setInterLayerObjHeader(PcepObjectHeader obj) {
+            this.interLayerObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getbNFlag() {
+            return this.bNFlag;
+        }
+
+        @Override
+        public Builder setbNFlag(boolean value) {
+            this.bNFlag = value;
+            this.bIsNFlagset = true;
+            return this;
+        }
+
+        @Override
+        public boolean getbIFlag() {
+            return this.bIFlag;
+        }
+
+        @Override
+        public Builder setbIFlag(boolean value) {
+            this.bIFlag = value;
+            this.bIsIFlagset = true;
+            return this;
+        }
+
+        @Override
+        public Builder setPFlag(boolean value) {
+            this.bPFalg = value;
+            this.bIsPFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setIFlag(boolean value) {
+            this.iFlag = value;
+            this.bIsIFlagSet = true;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("IFlag", bIFlag).add("NFlag", bNFlag).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java
index a9cbee6..776d3f1 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeObjectVer1.java
@@ -1,373 +1,373 @@
-/*
- * 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.PcepLabelRangeObject;
-import org.onosproject.pcepio.types.PathSetupTypeTlv;
-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 range object.
- */
-public class PcepLabelRangeObjectVer1 implements PcepLabelRangeObject {
-
-    /*
-     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01, 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
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           | label type    | range size                                    |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |                        label base                             |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |                                                               |
-           //                      Optional TLVs                           //
-           |                                                               |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                               LABEL-RANGE Object
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeObjectVer1.class);
-
-    public static final byte LABEL_RANGE_OBJ_TYPE = 1;
-    public static final byte LABEL_RANGE_OBJ_CLASS = 60; //to be defined
-    public static final byte LABEL_RANGE_OBJECT_VERSION = 1;
-    public static final short LABEL_RANGE_OBJ_MINIMUM_LENGTH = 12;
-    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
-    //P flag and I flag must be set to 0
-    static final PcepObjectHeader DEFAULT_LABELRANGE_OBJECT_HEADER = new PcepObjectHeader(LABEL_RANGE_OBJ_CLASS,
-            LABEL_RANGE_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
-            LABEL_RANGE_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader labelRangeObjHeader;
-    private byte labelType;
-    private int rangeSize;
-    private int labelBase;
-    //Optional TLV
-    private LinkedList<PcepValueType> llOptionalTlv;
-
-    /**
-     * Constructor to initialize parameters for PCEP label range object.
-     *
-     * @param labelRangeObjHeader label range object header
-     * @param labelType label type
-     * @param rangeSize range size
-     * @param labelBase label base
-     * @param llOptionalTlv list of optional tlvs
-     */
-    public PcepLabelRangeObjectVer1(PcepObjectHeader labelRangeObjHeader, byte labelType, int rangeSize, int labelBase,
-            LinkedList<PcepValueType> llOptionalTlv) {
-        this.labelRangeObjHeader = labelRangeObjHeader;
-        this.labelType = labelType;
-        this.rangeSize = rangeSize;
-        this.llOptionalTlv = llOptionalTlv;
-        this.labelBase = labelBase;
-    }
-
-    @Override
-    public void setLabelRangeObjHeader(PcepObjectHeader obj) {
-        this.labelRangeObjHeader = obj;
-    }
-
-    @Override
-    public void setLabelType(byte labelType) {
-        this.labelType = labelType;
-    }
-
-    @Override
-    public void setRangeSize(int rangeSize) {
-        this.rangeSize = rangeSize;
-    }
-
-    @Override
-    public void setLabelBase(int labelBase) {
-        this.labelBase = labelBase;
-    }
-
-    @Override
-    public PcepObjectHeader getLabelRangeObjHeader() {
-        return this.labelRangeObjHeader;
-    }
-
-    @Override
-    public byte getLabelType() {
-        return this.labelType;
-    }
-
-    @Override
-    public int getRangeSize() {
-        return this.rangeSize;
-    }
-
-    @Override
-    public int getLabelBase() {
-        return this.labelBase;
-    }
-
-    /**
-     * Reads from the channel buffer and returns object of  PcepLabelRangeObject.
-     *
-     * @param cb of type channel buffer
-     * @return object of  PcepLabelRangeObject
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepLabelRangeObject read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader labelRangeObjHeader;
-        byte labelType;
-        int rangeSize;
-        int labelBase;
-
-        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
-
-        labelRangeObjHeader = PcepObjectHeader.read(cb);
-
-        //take only LabelRangeObject buffer.
-        ChannelBuffer tempCb = cb.readBytes(labelRangeObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
-        int temp = 0;
-        temp = tempCb.readInt();
-        rangeSize = temp & 0x00FFFFFF;
-        labelType = (byte) (temp >> 24);
-        labelBase = tempCb.readInt();
-        llOptionalTlv = parseOptionalTlv(tempCb);
-        return new PcepLabelRangeObjectVer1(labelRangeObjHeader, labelType, rangeSize, labelBase, llOptionalTlv);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        int objStartIndex = cb.writerIndex();
-
-        //write common header
-        int objLenIndex = labelRangeObjHeader.write(cb);
-        int temp = 0;
-        temp = labelType;
-        temp = temp << 24;
-        temp = temp | rangeSize;
-        cb.writeInt(temp);
-
-        // Add optional TLV
-        if (!packOptionalTlv(cb)) {
-            throw new PcepParseException("Error while writing Optional tlv.");
-        }
-
-        //now write LabelRange Object Length
-        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
-        return cb.writerIndex() - objStartIndex;
-    }
-
-    /**
-     * Returns list of optional tlvs.
-     *
-     * @param cb of type channle buffer
-     * @return list of optional tlvs
-     * @throws PcepParseException whne fails to parse list of optional tlvs
-     */
-    public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
-
-        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
-
-        while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {
-
-            PcepValueType tlv;
-            int iValue;
-            short hType = cb.readShort();
-            short hLength = cb.readShort();
-
-            switch (hType) {
-
-            case PathSetupTypeTlv.TYPE:
-                iValue = cb.readInt();
-                tlv = new PathSetupTypeTlv(iValue);
-                break;
-
-            default:
-                throw new PcepParseException("Unsupported TLV in LabelRange 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;
-    }
-
-    /**
-     * Pack optional tlvs.
-     *
-     * @param cb of channel buffer
-     * @return true
-     */
-    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 label range object.
-     */
-    public static class Builder implements PcepLabelRangeObject.Builder {
-        private boolean bIsHeaderSet = false;
-        private boolean bIsLabelType = false;
-        private boolean bIsRangeSize = false;
-        private boolean bIsLabelBase = false;
-
-        byte labelType;
-        int rangeSize;
-        int labelBase;
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-        private PcepObjectHeader labelRangeObjHeader;
-
-        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
-
-        @Override
-        public PcepLabelRangeObject build() throws PcepParseException {
-            PcepObjectHeader labelRangeObjHeader = this.bIsHeaderSet ? this.labelRangeObjHeader
-                    : DEFAULT_LABELRANGE_OBJECT_HEADER;
-
-            if (!this.bIsLabelType) {
-                throw new PcepParseException("LabelType NOT Set while building label range object.");
-            }
-
-            if (!this.bIsRangeSize) {
-                throw new PcepParseException("RangeSize NOT Set while building label range object.");
-            }
-
-            if (!this.bIsLabelBase) {
-                throw new PcepParseException("LabelBase NOT Set while building label range object.");
-            }
-
-            if (bIsPFlagSet) {
-                labelRangeObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                labelRangeObjHeader.setIFlag(bIFlag);
-            }
-            return new PcepLabelRangeObjectVer1(labelRangeObjHeader, this.labelType, this.rangeSize, this.labelBase,
-                    this.llOptionalTlv);
-        }
-
-        @Override
-        public PcepObjectHeader getLabelRangeObjHeader() {
-            return this.labelRangeObjHeader;
-        }
-
-        @Override
-        public Builder setLabelRangeObjHeader(PcepObjectHeader obj) {
-            this.labelRangeObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public byte getLabelType() {
-            return this.labelType;
-        }
-
-        @Override
-        public Builder setLabelType(byte labelType) {
-            this.labelType = labelType;
-            this.bIsLabelType = true;
-            return this;
-        }
-
-        @Override
-        public int getRangeSize() {
-            return this.rangeSize;
-        }
-
-        @Override
-        public Builder setRangeSize(int rangeSize) {
-            this.rangeSize = rangeSize;
-            this.bIsRangeSize = true;
-            return this;
-        }
-
-        @Override
-        public int getLabelBase() {
-            return this.labelBase;
-        }
-
-        @Override
-        public Builder setLabelBase(int labelBase) {
-            this.labelBase = labelBase;
-            this.bIsLabelBase = true;
-            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("LabelType", labelType).add("rangeSize", rangeSize)
-                .add("labelBase", labelBase).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.PcepLabelRangeObject;
+import org.onosproject.pcepio.types.PathSetupTypeTlv;
+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 range object.
+ */
+public class PcepLabelRangeObjectVer1 implements PcepLabelRangeObject {
+
+    /*
+     * ref : draft-zhao-pce-pcep-extension-for-pce-controller-01, 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
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | label type    | range size                                    |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |                        label base                             |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |                                                               |
+           //                      Optional TLVs                           //
+           |                                                               |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                               LABEL-RANGE Object
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeObjectVer1.class);
+
+    public static final byte LABEL_RANGE_OBJ_TYPE = 1;
+    public static final byte LABEL_RANGE_OBJ_CLASS = 60; //to be defined
+    public static final byte LABEL_RANGE_OBJECT_VERSION = 1;
+    public static final short LABEL_RANGE_OBJ_MINIMUM_LENGTH = 12;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+    //P flag and I flag must be set to 0
+    static final PcepObjectHeader DEFAULT_LABELRANGE_OBJECT_HEADER = new PcepObjectHeader(LABEL_RANGE_OBJ_CLASS,
+            LABEL_RANGE_OBJ_TYPE, PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED,
+            LABEL_RANGE_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader labelRangeObjHeader;
+    private byte labelType;
+    private int rangeSize;
+    private int labelBase;
+    //Optional TLV
+    private LinkedList<PcepValueType> llOptionalTlv;
+
+    /**
+     * Constructor to initialize parameters for PCEP label range object.
+     *
+     * @param labelRangeObjHeader label range object header
+     * @param labelType label type
+     * @param rangeSize range size
+     * @param labelBase label base
+     * @param llOptionalTlv list of optional tlvs
+     */
+    public PcepLabelRangeObjectVer1(PcepObjectHeader labelRangeObjHeader, byte labelType, int rangeSize, int labelBase,
+            LinkedList<PcepValueType> llOptionalTlv) {
+        this.labelRangeObjHeader = labelRangeObjHeader;
+        this.labelType = labelType;
+        this.rangeSize = rangeSize;
+        this.llOptionalTlv = llOptionalTlv;
+        this.labelBase = labelBase;
+    }
+
+    @Override
+    public void setLabelRangeObjHeader(PcepObjectHeader obj) {
+        this.labelRangeObjHeader = obj;
+    }
+
+    @Override
+    public void setLabelType(byte labelType) {
+        this.labelType = labelType;
+    }
+
+    @Override
+    public void setRangeSize(int rangeSize) {
+        this.rangeSize = rangeSize;
+    }
+
+    @Override
+    public void setLabelBase(int labelBase) {
+        this.labelBase = labelBase;
+    }
+
+    @Override
+    public PcepObjectHeader getLabelRangeObjHeader() {
+        return this.labelRangeObjHeader;
+    }
+
+    @Override
+    public byte getLabelType() {
+        return this.labelType;
+    }
+
+    @Override
+    public int getRangeSize() {
+        return this.rangeSize;
+    }
+
+    @Override
+    public int getLabelBase() {
+        return this.labelBase;
+    }
+
+    /**
+     * Reads from the channel buffer and returns object of  PcepLabelRangeObject.
+     *
+     * @param cb of type channel buffer
+     * @return object of  PcepLabelRangeObject
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepLabelRangeObject read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader labelRangeObjHeader;
+        byte labelType;
+        int rangeSize;
+        int labelBase;
+
+        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        labelRangeObjHeader = PcepObjectHeader.read(cb);
+
+        //take only LabelRangeObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(labelRangeObjHeader.getObjLen() - MINIMUM_COMMON_HEADER_LENGTH);
+        int temp = 0;
+        temp = tempCb.readInt();
+        rangeSize = temp & 0x00FFFFFF;
+        labelType = (byte) (temp >> 24);
+        labelBase = tempCb.readInt();
+        llOptionalTlv = parseOptionalTlv(tempCb);
+        return new PcepLabelRangeObjectVer1(labelRangeObjHeader, labelType, rangeSize, labelBase, llOptionalTlv);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        int objStartIndex = cb.writerIndex();
+
+        //write common header
+        int objLenIndex = labelRangeObjHeader.write(cb);
+        int temp = 0;
+        temp = labelType;
+        temp = temp << 24;
+        temp = temp | rangeSize;
+        cb.writeInt(temp);
+
+        // Add optional TLV
+        if (!packOptionalTlv(cb)) {
+            throw new PcepParseException("Error while writing Optional tlv.");
+        }
+
+        //now write LabelRange Object Length
+        cb.setShort(objLenIndex, (short) (cb.writerIndex() - objStartIndex));
+        return cb.writerIndex() - objStartIndex;
+    }
+
+    /**
+     * Returns list of optional tlvs.
+     *
+     * @param cb of type channle buffer
+     * @return list of optional tlvs
+     * @throws PcepParseException whne fails to parse list of optional tlvs
+     */
+    public static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
+
+        while (MINIMUM_COMMON_HEADER_LENGTH <= cb.readableBytes()) {
+
+            PcepValueType tlv;
+            int iValue;
+            short hType = cb.readShort();
+            short hLength = cb.readShort();
+
+            switch (hType) {
+
+            case PathSetupTypeTlv.TYPE:
+                iValue = cb.readInt();
+                tlv = new PathSetupTypeTlv(iValue);
+                break;
+
+            default:
+                throw new PcepParseException("Unsupported TLV in LabelRange 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;
+    }
+
+    /**
+     * Pack optional tlvs.
+     *
+     * @param cb of channel buffer
+     * @return true
+     */
+    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 label range object.
+     */
+    public static class Builder implements PcepLabelRangeObject.Builder {
+        private boolean bIsHeaderSet = false;
+        private boolean bIsLabelType = false;
+        private boolean bIsRangeSize = false;
+        private boolean bIsLabelBase = false;
+
+        byte labelType;
+        int rangeSize;
+        int labelBase;
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+        private PcepObjectHeader labelRangeObjHeader;
+
+        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        @Override
+        public PcepLabelRangeObject build() throws PcepParseException {
+            PcepObjectHeader labelRangeObjHeader = this.bIsHeaderSet ? this.labelRangeObjHeader
+                    : DEFAULT_LABELRANGE_OBJECT_HEADER;
+
+            if (!this.bIsLabelType) {
+                throw new PcepParseException("LabelType NOT Set while building label range object.");
+            }
+
+            if (!this.bIsRangeSize) {
+                throw new PcepParseException("RangeSize NOT Set while building label range object.");
+            }
+
+            if (!this.bIsLabelBase) {
+                throw new PcepParseException("LabelBase NOT Set while building label range object.");
+            }
+
+            if (bIsPFlagSet) {
+                labelRangeObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                labelRangeObjHeader.setIFlag(bIFlag);
+            }
+            return new PcepLabelRangeObjectVer1(labelRangeObjHeader, this.labelType, this.rangeSize, this.labelBase,
+                    this.llOptionalTlv);
+        }
+
+        @Override
+        public PcepObjectHeader getLabelRangeObjHeader() {
+            return this.labelRangeObjHeader;
+        }
+
+        @Override
+        public Builder setLabelRangeObjHeader(PcepObjectHeader obj) {
+            this.labelRangeObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public byte getLabelType() {
+            return this.labelType;
+        }
+
+        @Override
+        public Builder setLabelType(byte labelType) {
+            this.labelType = labelType;
+            this.bIsLabelType = true;
+            return this;
+        }
+
+        @Override
+        public int getRangeSize() {
+            return this.rangeSize;
+        }
+
+        @Override
+        public Builder setRangeSize(int rangeSize) {
+            this.rangeSize = rangeSize;
+            this.bIsRangeSize = true;
+            return this;
+        }
+
+        @Override
+        public int getLabelBase() {
+            return this.labelBase;
+        }
+
+        @Override
+        public Builder setLabelBase(int labelBase) {
+            this.labelBase = labelBase;
+            this.bIsLabelBase = true;
+            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("LabelType", labelType).add("rangeSize", rangeSize)
+                .add("labelBase", labelBase).add("optionalTlvList", llOptionalTlv).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java
index f2498ae..0bcee5a 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelRangeVer1.java
@@ -1,166 +1,166 @@
-/*
- * 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.PcepLabelRange;
-import org.onosproject.pcepio.protocol.PcepLabelRangeObject;
-import org.onosproject.pcepio.protocol.PcepSrpObject;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP Label Range.
- */
-public class PcepLabelRangeVer1 implements PcepLabelRange {
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeVer1.class);
-
-    /*
-        <label-range> ::= <SRP>
-                          <labelrange-list>
-        Where
-                <labelrange-list>::=<LABEL-RANGE>[<labelrange-list>]
-     */
-
-    // PCEP SRP Object
-    private PcepSrpObject srpObject;
-    //<labelrange-list> of type PcepLabelRangeObject.
-    private LinkedList<PcepLabelRangeObject> llLabelRangeList;
-
-    /**
-     * Default Constructor.
-     */
-    public PcepLabelRangeVer1() {
-        srpObject = null;
-        llLabelRangeList = null;
-    }
-
-    /**
-     * Constructor to initialize objects.
-     *
-     * @param srpObj PCEP Srp object.
-     * @param llLabelRangeList list of PcepLabelRangeObject.
-     */
-    PcepLabelRangeVer1(PcepSrpObject srpObj, LinkedList<PcepLabelRangeObject> llLabelRangeList) {
-        this.srpObject = srpObj;
-        this.llLabelRangeList = llLabelRangeList;
-    }
-
-    @Override
-    public PcepSrpObject getSrpObject() {
-        return srpObject;
-    }
-
-    @Override
-    public void setSrpObject(PcepSrpObject srpObject) {
-        this.srpObject = srpObject;
-
-    }
-
-    @Override
-    public LinkedList<PcepLabelRangeObject> getLabelRangeList() {
-        return llLabelRangeList;
-    }
-
-    @Override
-    public void setLabelRangeList(LinkedList<PcepLabelRangeObject> ll) {
-        this.llLabelRangeList = ll;
-    }
-
-    /**
-     * Reads channel buffer and returns object of PcepLabelRange.
-     *
-     * @param cb of type channel buffer.
-     * @return object of PcepLabelRange
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepLabelRange read(ChannelBuffer cb) throws PcepParseException {
-
-        //parse and store SRP mandatory object
-        PcepSrpObject srpObj = null;
-        srpObj = PcepSrpObjectVer1.read(cb);
-        if (srpObj == null) {
-            throw new PcepParseException("Exception while parsing srp object");
-        }
-
-        LinkedList<PcepLabelRangeObject> llLabelRangeList = new LinkedList<PcepLabelRangeObject>();
-        boolean bFoundLabelRangeObj = false;
-        while (0 < cb.readableBytes()) {
-            //parse and store <labelrange-list>
-            PcepLabelRangeObject lrObj;
-            lrObj = PcepLabelRangeObjectVer1.read(cb);
-            if (lrObj == null) {
-                throw new PcepParseException("Exception while parsing label range object");
-            } else {
-                llLabelRangeList.add(lrObj);
-                bFoundLabelRangeObj = true;
-            }
-        }
-
-        if (!bFoundLabelRangeObj) {
-            throw new PcepParseException("At least one LABEL-RANGE MUST be present.");
-        }
-        return new PcepLabelRangeVer1(srpObj, llLabelRangeList);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-        //write Object header
-        int objStartIndex = cb.writerIndex();
-
-        //write <SRP>
-        int objLenIndex = srpObject.write(cb);
-
-        if (objLenIndex <= 0) {
-            throw new PcepParseException("bjectLength is " + objLenIndex);
-        }
-
-        //write <labelrange-list>
-        ListIterator<PcepLabelRangeObject> listIterator = llLabelRangeList.listIterator();
-        while (listIterator.hasNext()) {
-            listIterator.next().write(cb);
-        }
-
-        //Update object length now
-        int length = cb.writerIndex() - objStartIndex;
-        // As per RFC the length of object should be
-        // multiples of 4
-        int pad = length % 4;
-        if (pad != 0) {
-            pad = 4 - pad;
-            for (int i = 0; i < pad; i++) {
-                cb.writeByte((byte) 0);
-            }
-            length = length + pad;
-        }
-        cb.setShort(objLenIndex, (short) length);
-        return length;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("srpObject", srpObject)
-                .add("LabelRangeList", llLabelRangeList).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.PcepLabelRange;
+import org.onosproject.pcepio.protocol.PcepLabelRangeObject;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP Label Range.
+ */
+public class PcepLabelRangeVer1 implements PcepLabelRange {
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepLabelRangeVer1.class);
+
+    /*
+        <label-range> ::= <SRP>
+                          <labelrange-list>
+        Where
+                <labelrange-list>::=<LABEL-RANGE>[<labelrange-list>]
+     */
+
+    // PCEP SRP Object
+    private PcepSrpObject srpObject;
+    //<labelrange-list> of type PcepLabelRangeObject.
+    private LinkedList<PcepLabelRangeObject> llLabelRangeList;
+
+    /**
+     * Default Constructor.
+     */
+    public PcepLabelRangeVer1() {
+        srpObject = null;
+        llLabelRangeList = null;
+    }
+
+    /**
+     * Constructor to initialize objects.
+     *
+     * @param srpObj PCEP Srp object.
+     * @param llLabelRangeList list of PcepLabelRangeObject.
+     */
+    PcepLabelRangeVer1(PcepSrpObject srpObj, LinkedList<PcepLabelRangeObject> llLabelRangeList) {
+        this.srpObject = srpObj;
+        this.llLabelRangeList = llLabelRangeList;
+    }
+
+    @Override
+    public PcepSrpObject getSrpObject() {
+        return srpObject;
+    }
+
+    @Override
+    public void setSrpObject(PcepSrpObject srpObject) {
+        this.srpObject = srpObject;
+
+    }
+
+    @Override
+    public LinkedList<PcepLabelRangeObject> getLabelRangeList() {
+        return llLabelRangeList;
+    }
+
+    @Override
+    public void setLabelRangeList(LinkedList<PcepLabelRangeObject> ll) {
+        this.llLabelRangeList = ll;
+    }
+
+    /**
+     * Reads channel buffer and returns object of PcepLabelRange.
+     *
+     * @param cb of type channel buffer.
+     * @return object of PcepLabelRange
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepLabelRange read(ChannelBuffer cb) throws PcepParseException {
+
+        //parse and store SRP mandatory object
+        PcepSrpObject srpObj = null;
+        srpObj = PcepSrpObjectVer1.read(cb);
+        if (srpObj == null) {
+            throw new PcepParseException("Exception while parsing srp object");
+        }
+
+        LinkedList<PcepLabelRangeObject> llLabelRangeList = new LinkedList<PcepLabelRangeObject>();
+        boolean bFoundLabelRangeObj = false;
+        while (0 < cb.readableBytes()) {
+            //parse and store <labelrange-list>
+            PcepLabelRangeObject lrObj;
+            lrObj = PcepLabelRangeObjectVer1.read(cb);
+            if (lrObj == null) {
+                throw new PcepParseException("Exception while parsing label range object");
+            } else {
+                llLabelRangeList.add(lrObj);
+                bFoundLabelRangeObj = true;
+            }
+        }
+
+        if (!bFoundLabelRangeObj) {
+            throw new PcepParseException("At least one LABEL-RANGE MUST be present.");
+        }
+        return new PcepLabelRangeVer1(srpObj, llLabelRangeList);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        //write <SRP>
+        int objLenIndex = srpObject.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("bjectLength is " + objLenIndex);
+        }
+
+        //write <labelrange-list>
+        ListIterator<PcepLabelRangeObject> listIterator = llLabelRangeList.listIterator();
+        while (listIterator.hasNext()) {
+            listIterator.next().write(cb);
+        }
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+        // As per RFC the length of object should be
+        // multiples of 4
+        int pad = length % 4;
+        if (pad != 0) {
+            pad = 4 - pad;
+            for (int i = 0; i < pad; i++) {
+                cb.writeByte((byte) 0);
+            }
+            length = length + pad;
+        }
+        cb.setShort(objLenIndex, (short) length);
+        return length;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("srpObject", srpObject)
+                .add("LabelRangeList", llLabelRangeList).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateVer1.java
index 7c7b3de..a13045d 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepLabelUpdateVer1.java
@@ -1,361 +1,361 @@
-/*
- * 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.PcepFecObject;
-import org.onosproject.pcepio.protocol.PcepLabelObject;
-import org.onosproject.pcepio.protocol.PcepLabelUpdate;
-import org.onosproject.pcepio.protocol.PcepLspObject;
-import org.onosproject.pcepio.protocol.PcepSrpObject;
-import org.onosproject.pcepio.types.PcepLabelDownload;
-import org.onosproject.pcepio.types.PcepLabelMap;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides PCEP LABEL update .
- * Reference :draft-zhao-pce-pcep-extension-for-pce-controller-01.
- */
-public class PcepLabelUpdateVer1 implements PcepLabelUpdate {
-
-    /*
-     *       <pce-label-update>      ::= (<pce-label-download>|<pce-label-map>)
-
-            Where:
-             <pce-label-download>    ::= <SRP>
-                                         <LSP>
-                                         <label-list>
-
-             <pce-label-map>         ::= <SRP>
-                                         <LABEL>
-                                         <FEC>
-
-             <label-list >           ::= <LABEL>
-                                         [<label-list>]
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepLabelUpdateVer1.class);
-
-    //Either PceLabelDownload or PceLabelMap is mandatory.
-    //label Download
-    private PcepLabelDownload labelDownload;
-    private boolean isLabelDownloadSet;
-    //label Map
-    private PcepLabelMap labelMap;
-    private boolean isLabelMapSet;
-
-    /**
-     * Constructor to reset parameters.
-     */
-    public PcepLabelUpdateVer1() {
-        this.labelDownload = null;
-        this.isLabelDownloadSet = false;
-        this.labelMap = null;
-        this.isLabelMapSet = false;
-    }
-
-    /**
-     * Constructor to initialize PCEP label download.
-     *
-     * @param labelDownload PCEP label download
-     */
-    public PcepLabelUpdateVer1(PcepLabelDownload labelDownload) {
-        this.labelDownload = labelDownload;
-        this.isLabelDownloadSet = true;
-        this.labelMap = null;
-        this.isLabelMapSet = false;
-    }
-
-    /**
-     * Constructor to initialize PCEP label map.
-     *
-     * @param labelMap PCEP label map
-     */
-    public PcepLabelUpdateVer1(PcepLabelMap labelMap) {
-        this.labelDownload = null;
-        this.isLabelDownloadSet = false;
-        this.labelMap = labelMap;
-        this.isLabelMapSet = true;
-    }
-
-    /**
-     * builder class for PCEP label update.
-     */
-    static class Builder implements PcepLabelUpdate.Builder {
-
-        private PcepLabelDownload labelDownload;
-        private boolean isLabelDownloadSet;
-        private PcepLabelMap labelMap;
-        private boolean isLabelMapSet;
-
-        @Override
-        public PcepLabelUpdate build() throws PcepParseException {
-
-            if (isLabelDownloadSet) {
-                return new PcepLabelUpdateVer1(labelDownload);
-            }
-            if (isLabelMapSet) {
-                return new PcepLabelUpdateVer1(labelMap);
-            }
-            if (!isLabelDownloadSet && !isLabelMapSet) {
-                throw new PcepParseException(
-                        "Label Download or Label Map is not set while building PcepLabelUpdate Message");
-            }
-            return new PcepLabelUpdateVer1();
-        }
-
-        @Override
-        public Builder setLabelDownload(PcepLabelDownload labelDownload) {
-            this.labelDownload = labelDownload;
-            this.isLabelDownloadSet = true;
-            return this;
-        }
-
-        @Override
-        public PcepLabelDownload getLabelDownload() {
-            return labelDownload;
-        }
-
-        @Override
-        public Builder setLabelMap(PcepLabelMap labelMap) {
-            this.labelMap = labelMap;
-            this.isLabelMapSet = true;
-            return this;
-        }
-
-        @Override
-        public PcepLabelMap getLabelMap() {
-            return labelMap;
-        }
-    }
-
-    /**
-     * Reads PcepLabels from the byte stream received from channel buffer.
-     *
-     * @param cb of type channel buffer.
-     * @return PcepLabelUpdate object.
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepLabelUpdate read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepLabelUpdateVer1 pceLabelUpdate = new PcepLabelUpdateVer1();
-
-        PcepSrpObject srpObject;
-        PcepObjectHeader tempObjHeader;
-
-        //read SRP mandatory Object
-        srpObject = PcepSrpObjectVer1.read(cb);
-
-        //checking next object
-        cb.markReaderIndex();
-
-        tempObjHeader = PcepObjectHeader.read(cb);
-        cb.resetReaderIndex();
-
-        if (tempObjHeader.getObjClass() == PcepLspObjectVer1.LSP_OBJ_CLASS) {
-
-            //now it is belong to <pce-label-download>
-            PcepLabelDownload labelDownload = new PcepLabelDownload();
-
-            //set SRP
-            labelDownload.setSrpObject(srpObject);
-
-            //read and set LSP
-            labelDownload.setLspObject(PcepLspObjectVer1.read(cb));
-
-            //<label-list>
-            LinkedList<PcepLabelObject> llLabelList = new LinkedList<PcepLabelObject>();
-            PcepLabelObject labelObject;
-
-            while (0 < cb.readableBytes()) {
-
-                cb.markReaderIndex();
-                tempObjHeader = PcepObjectHeader.read(cb);
-                cb.resetReaderIndex();
-
-                if (tempObjHeader.getObjClass() != PcepLabelObjectVer1.LABEL_OBJ_CLASS) {
-                    break;
-                }
-                labelObject = PcepLabelObjectVer1.read(cb);
-                llLabelList.add(labelObject);
-            }
-            labelDownload.setLabelList(llLabelList);
-            pceLabelUpdate.setLabelDownload(labelDownload);
-        } else if (tempObjHeader.getObjClass() == PcepLabelObjectVer1.LABEL_OBJ_CLASS) {
-            //belong to <pce-label-map>
-            PcepLabelMap labelMap = new PcepLabelMap();
-
-            //set SRP Object
-            labelMap.setSrpObject(srpObject);
-
-            //read and set Label Object
-            labelMap.setLabelObject(PcepLabelObjectVer1.read(cb));
-
-            cb.markReaderIndex();
-            tempObjHeader = PcepObjectHeader.read(cb);
-            cb.resetReaderIndex();
-
-            PcepFecObject fecObject = null;
-            switch (tempObjHeader.getObjType()) {
-            case PcepFecObjectIPv4Ver1.FEC_OBJ_TYPE:
-                fecObject = PcepFecObjectIPv4Ver1.read(cb);
-                break;
-            case PcepFecObjectIPv6Ver1.FEC_OBJ_TYPE:
-                fecObject = PcepFecObjectIPv6Ver1.read(cb);
-                break;
-            case PcepFecObjectIPv4AdjacencyVer1.FEC_OBJ_TYPE:
-                fecObject = PcepFecObjectIPv4AdjacencyVer1.read(cb);
-                break;
-            case PcepFecObjectIPv6AdjacencyVer1.FEC_OBJ_TYPE:
-                fecObject = PcepFecObjectIPv6AdjacencyVer1.read(cb);
-                break;
-            case PcepFecObjectIPv4UnnumberedAdjacencyVer1.FEC_OBJ_TYPE:
-                fecObject = PcepFecObjectIPv4UnnumberedAdjacencyVer1.read(cb);
-                break;
-            default:
-                throw new PcepParseException("Unkown FEC object type " + tempObjHeader.getObjType());
-            }
-            labelMap.setFECObject(fecObject);
-            pceLabelUpdate.setLabelMap(labelMap);
-        } else {
-            throw new PcepParseException(
-                    "Either <pce-label-download> or <pce-label-map> should be present. Received Class: "
-                            + tempObjHeader.getObjClass());
-        }
-        return pceLabelUpdate;
-    }
-
-    @Override
-    public void write(ChannelBuffer cb) throws PcepParseException {
-
-        if ((labelDownload != null) && (labelMap != null)) {
-            throw new PcepParseException("Label Download and Label Map both can't be present.");
-        }
-
-        if ((labelDownload == null) && (labelMap == null)) {
-            throw new PcepParseException("Either Label Download or Label Map should be present.");
-        }
-
-        if (labelDownload != null) {
-
-            PcepLspObject lspObject;
-            PcepSrpObject srpObject;
-            PcepLabelObject labelObject;
-            LinkedList<PcepLabelObject> llLabelList;
-
-            srpObject = labelDownload.getSrpObject();
-            if (srpObject == null) {
-                throw new PcepParseException("SRP Object is mandatory object for Label Download.");
-            } else {
-                srpObject.write(cb);
-            }
-
-            lspObject = labelDownload.getLspObject();
-            if (lspObject == null) {
-                throw new PcepParseException("LSP Object is mandatory object for Label Download.");
-            } else {
-                lspObject.write(cb);
-            }
-
-            llLabelList = labelDownload.getLabelList();
-            if (llLabelList == null) {
-                throw new PcepParseException("Label list is mandatory object for Label Download.");
-            } else {
-                ListIterator<PcepLabelObject> listIterator = llLabelList.listIterator();
-                while (listIterator.hasNext()) {
-                    labelObject = listIterator.next();
-                    labelObject.write(cb);
-                }
-            }
-        }
-
-        if (labelMap != null) {
-
-            PcepSrpObject srpObject;
-            PcepLabelObject labelObject;
-            PcepFecObject fecObject;
-
-            srpObject = labelMap.getSrpObject();
-            if (srpObject == null) {
-                throw new PcepParseException("SRP Object is mandatory object for Label map.");
-            } else {
-                srpObject.write(cb);
-            }
-            labelObject = labelMap.getLabelObject();
-            if (labelObject == null) {
-                throw new PcepParseException("label Object is mandatory object for Label map.");
-            } else {
-                labelObject.write(cb);
-            }
-            fecObject = labelMap.getFECObject();
-            if (fecObject == null) {
-                throw new PcepParseException("fec Object is mandatory object for Label map.");
-            } else {
-                fecObject.write(cb);
-            }
-        }
-    }
-
-    @Override
-    public void setLabelDownload(PcepLabelDownload labelDownload) {
-        if (this.isLabelMapSet) {
-            return;
-        }
-        this.labelDownload = labelDownload;
-        this.isLabelDownloadSet = true;
-    }
-
-    @Override
-    public PcepLabelDownload getLabelDownload() {
-        return this.labelDownload;
-    }
-
-    @Override
-    public void setLabelMap(PcepLabelMap labelMap) {
-        if (this.isLabelDownloadSet) {
-            return;
-        }
-        this.labelMap = labelMap;
-        this.isLabelMapSet = true;
-    }
-
-    @Override
-    public PcepLabelMap getLabelMap() {
-        return this.labelMap;
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        if (labelDownload instanceof PcepLabelDownload) {
-            toStrHelper.add("LabelDownload", labelDownload);
-        }
-        if (labelMap instanceof PcepLabelMap) {
-            toStrHelper.add("LabelMap", labelMap);
-        }
-        return toStrHelper.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.PcepFecObject;
+import org.onosproject.pcepio.protocol.PcepLabelObject;
+import org.onosproject.pcepio.protocol.PcepLabelUpdate;
+import org.onosproject.pcepio.protocol.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.types.PcepLabelDownload;
+import org.onosproject.pcepio.types.PcepLabelMap;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides PCEP LABEL update .
+ * Reference :draft-zhao-pce-pcep-extension-for-pce-controller-01.
+ */
+public class PcepLabelUpdateVer1 implements PcepLabelUpdate {
+
+    /*
+     *       <pce-label-update>      ::= (<pce-label-download>|<pce-label-map>)
+
+            Where:
+             <pce-label-download>    ::= <SRP>
+                                         <LSP>
+                                         <label-list>
+
+             <pce-label-map>         ::= <SRP>
+                                         <LABEL>
+                                         <FEC>
+
+             <label-list >           ::= <LABEL>
+                                         [<label-list>]
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepLabelUpdateVer1.class);
+
+    //Either PceLabelDownload or PceLabelMap is mandatory.
+    //label Download
+    private PcepLabelDownload labelDownload;
+    private boolean isLabelDownloadSet;
+    //label Map
+    private PcepLabelMap labelMap;
+    private boolean isLabelMapSet;
+
+    /**
+     * Constructor to reset parameters.
+     */
+    public PcepLabelUpdateVer1() {
+        this.labelDownload = null;
+        this.isLabelDownloadSet = false;
+        this.labelMap = null;
+        this.isLabelMapSet = false;
+    }
+
+    /**
+     * Constructor to initialize PCEP label download.
+     *
+     * @param labelDownload PCEP label download
+     */
+    public PcepLabelUpdateVer1(PcepLabelDownload labelDownload) {
+        this.labelDownload = labelDownload;
+        this.isLabelDownloadSet = true;
+        this.labelMap = null;
+        this.isLabelMapSet = false;
+    }
+
+    /**
+     * Constructor to initialize PCEP label map.
+     *
+     * @param labelMap PCEP label map
+     */
+    public PcepLabelUpdateVer1(PcepLabelMap labelMap) {
+        this.labelDownload = null;
+        this.isLabelDownloadSet = false;
+        this.labelMap = labelMap;
+        this.isLabelMapSet = true;
+    }
+
+    /**
+     * builder class for PCEP label update.
+     */
+    static class Builder implements PcepLabelUpdate.Builder {
+
+        private PcepLabelDownload labelDownload;
+        private boolean isLabelDownloadSet;
+        private PcepLabelMap labelMap;
+        private boolean isLabelMapSet;
+
+        @Override
+        public PcepLabelUpdate build() throws PcepParseException {
+
+            if (isLabelDownloadSet) {
+                return new PcepLabelUpdateVer1(labelDownload);
+            }
+            if (isLabelMapSet) {
+                return new PcepLabelUpdateVer1(labelMap);
+            }
+            if (!isLabelDownloadSet && !isLabelMapSet) {
+                throw new PcepParseException(
+                        "Label Download or Label Map is not set while building PcepLabelUpdate Message");
+            }
+            return new PcepLabelUpdateVer1();
+        }
+
+        @Override
+        public Builder setLabelDownload(PcepLabelDownload labelDownload) {
+            this.labelDownload = labelDownload;
+            this.isLabelDownloadSet = true;
+            return this;
+        }
+
+        @Override
+        public PcepLabelDownload getLabelDownload() {
+            return labelDownload;
+        }
+
+        @Override
+        public Builder setLabelMap(PcepLabelMap labelMap) {
+            this.labelMap = labelMap;
+            this.isLabelMapSet = true;
+            return this;
+        }
+
+        @Override
+        public PcepLabelMap getLabelMap() {
+            return labelMap;
+        }
+    }
+
+    /**
+     * Reads PcepLabels from the byte stream received from channel buffer.
+     *
+     * @param cb of type channel buffer.
+     * @return PcepLabelUpdate object.
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepLabelUpdate read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepLabelUpdateVer1 pceLabelUpdate = new PcepLabelUpdateVer1();
+
+        PcepSrpObject srpObject;
+        PcepObjectHeader tempObjHeader;
+
+        //read SRP mandatory Object
+        srpObject = PcepSrpObjectVer1.read(cb);
+
+        //checking next object
+        cb.markReaderIndex();
+
+        tempObjHeader = PcepObjectHeader.read(cb);
+        cb.resetReaderIndex();
+
+        if (tempObjHeader.getObjClass() == PcepLspObjectVer1.LSP_OBJ_CLASS) {
+
+            //now it is belong to <pce-label-download>
+            PcepLabelDownload labelDownload = new PcepLabelDownload();
+
+            //set SRP
+            labelDownload.setSrpObject(srpObject);
+
+            //read and set LSP
+            labelDownload.setLspObject(PcepLspObjectVer1.read(cb));
+
+            //<label-list>
+            LinkedList<PcepLabelObject> llLabelList = new LinkedList<PcepLabelObject>();
+            PcepLabelObject labelObject;
+
+            while (0 < cb.readableBytes()) {
+
+                cb.markReaderIndex();
+                tempObjHeader = PcepObjectHeader.read(cb);
+                cb.resetReaderIndex();
+
+                if (tempObjHeader.getObjClass() != PcepLabelObjectVer1.LABEL_OBJ_CLASS) {
+                    break;
+                }
+                labelObject = PcepLabelObjectVer1.read(cb);
+                llLabelList.add(labelObject);
+            }
+            labelDownload.setLabelList(llLabelList);
+            pceLabelUpdate.setLabelDownload(labelDownload);
+        } else if (tempObjHeader.getObjClass() == PcepLabelObjectVer1.LABEL_OBJ_CLASS) {
+            //belong to <pce-label-map>
+            PcepLabelMap labelMap = new PcepLabelMap();
+
+            //set SRP Object
+            labelMap.setSrpObject(srpObject);
+
+            //read and set Label Object
+            labelMap.setLabelObject(PcepLabelObjectVer1.read(cb));
+
+            cb.markReaderIndex();
+            tempObjHeader = PcepObjectHeader.read(cb);
+            cb.resetReaderIndex();
+
+            PcepFecObject fecObject = null;
+            switch (tempObjHeader.getObjType()) {
+            case PcepFecObjectIPv4Ver1.FEC_OBJ_TYPE:
+                fecObject = PcepFecObjectIPv4Ver1.read(cb);
+                break;
+            case PcepFecObjectIPv6Ver1.FEC_OBJ_TYPE:
+                fecObject = PcepFecObjectIPv6Ver1.read(cb);
+                break;
+            case PcepFecObjectIPv4AdjacencyVer1.FEC_OBJ_TYPE:
+                fecObject = PcepFecObjectIPv4AdjacencyVer1.read(cb);
+                break;
+            case PcepFecObjectIPv6AdjacencyVer1.FEC_OBJ_TYPE:
+                fecObject = PcepFecObjectIPv6AdjacencyVer1.read(cb);
+                break;
+            case PcepFecObjectIPv4UnnumberedAdjacencyVer1.FEC_OBJ_TYPE:
+                fecObject = PcepFecObjectIPv4UnnumberedAdjacencyVer1.read(cb);
+                break;
+            default:
+                throw new PcepParseException("Unkown FEC object type " + tempObjHeader.getObjType());
+            }
+            labelMap.setFECObject(fecObject);
+            pceLabelUpdate.setLabelMap(labelMap);
+        } else {
+            throw new PcepParseException(
+                    "Either <pce-label-download> or <pce-label-map> should be present. Received Class: "
+                            + tempObjHeader.getObjClass());
+        }
+        return pceLabelUpdate;
+    }
+
+    @Override
+    public void write(ChannelBuffer cb) throws PcepParseException {
+
+        if ((labelDownload != null) && (labelMap != null)) {
+            throw new PcepParseException("Label Download and Label Map both can't be present.");
+        }
+
+        if ((labelDownload == null) && (labelMap == null)) {
+            throw new PcepParseException("Either Label Download or Label Map should be present.");
+        }
+
+        if (labelDownload != null) {
+
+            PcepLspObject lspObject;
+            PcepSrpObject srpObject;
+            PcepLabelObject labelObject;
+            LinkedList<PcepLabelObject> llLabelList;
+
+            srpObject = labelDownload.getSrpObject();
+            if (srpObject == null) {
+                throw new PcepParseException("SRP Object is mandatory object for Label Download.");
+            } else {
+                srpObject.write(cb);
+            }
+
+            lspObject = labelDownload.getLspObject();
+            if (lspObject == null) {
+                throw new PcepParseException("LSP Object is mandatory object for Label Download.");
+            } else {
+                lspObject.write(cb);
+            }
+
+            llLabelList = labelDownload.getLabelList();
+            if (llLabelList == null) {
+                throw new PcepParseException("Label list is mandatory object for Label Download.");
+            } else {
+                ListIterator<PcepLabelObject> listIterator = llLabelList.listIterator();
+                while (listIterator.hasNext()) {
+                    labelObject = listIterator.next();
+                    labelObject.write(cb);
+                }
+            }
+        }
+
+        if (labelMap != null) {
+
+            PcepSrpObject srpObject;
+            PcepLabelObject labelObject;
+            PcepFecObject fecObject;
+
+            srpObject = labelMap.getSrpObject();
+            if (srpObject == null) {
+                throw new PcepParseException("SRP Object is mandatory object for Label map.");
+            } else {
+                srpObject.write(cb);
+            }
+            labelObject = labelMap.getLabelObject();
+            if (labelObject == null) {
+                throw new PcepParseException("label Object is mandatory object for Label map.");
+            } else {
+                labelObject.write(cb);
+            }
+            fecObject = labelMap.getFECObject();
+            if (fecObject == null) {
+                throw new PcepParseException("fec Object is mandatory object for Label map.");
+            } else {
+                fecObject.write(cb);
+            }
+        }
+    }
+
+    @Override
+    public void setLabelDownload(PcepLabelDownload labelDownload) {
+        if (this.isLabelMapSet) {
+            return;
+        }
+        this.labelDownload = labelDownload;
+        this.isLabelDownloadSet = true;
+    }
+
+    @Override
+    public PcepLabelDownload getLabelDownload() {
+        return this.labelDownload;
+    }
+
+    @Override
+    public void setLabelMap(PcepLabelMap labelMap) {
+        if (this.isLabelDownloadSet) {
+            return;
+        }
+        this.labelMap = labelMap;
+        this.isLabelMapSet = true;
+    }
+
+    @Override
+    public PcepLabelMap getLabelMap() {
+        return this.labelMap;
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        if (labelDownload instanceof PcepLabelDownload) {
+            toStrHelper.add("LabelDownload", labelDownload);
+        }
+        if (labelMap instanceof PcepLabelMap) {
+            toStrHelper.add("LabelMap", labelMap);
+        }
+        return toStrHelper.toString();
+    }
+}
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();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMsgPathVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMsgPathVer1.java
index 30cd3d6..2967b47 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMsgPathVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepMsgPathVer1.java
@@ -1,170 +1,170 @@
-package org.onosproject.pcepio.protocol.ver1;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepAttribute;
-import org.onosproject.pcepio.protocol.PcepEroObject;
-import org.onosproject.pcepio.protocol.PcepMsgPath;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP Message PAth for update message.
- * Reference :PCE extensions for stateful draft-ietf-pce-stateful-pce-10.
- */
-public class PcepMsgPathVer1 implements PcepMsgPath {
-
-    /*
-     *  <path>         ::= <ERO><attribute-list>
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepMsgPathVer1.class);
-    //PcepEroObject
-    private PcepEroObject eroObj;
-    private boolean isEroObjectSet;
-    // PcepAttribute
-    private PcepAttribute attrList;
-    private boolean isAttributeListSet;
-
-    /**
-     * constructor to initialize objects.
-     */
-    public PcepMsgPathVer1() {
-        eroObj = null;
-        attrList = null;
-        isEroObjectSet = false;
-        isAttributeListSet = false;
-    }
-
-    @Override
-    public PcepEroObject getEroObject() {
-        return eroObj;
-    }
-
-    @Override
-    public PcepAttribute getPcepAttribute() {
-        return attrList;
-    }
-
-    @Override
-    public void setEroObject(PcepEroObject eroObj) {
-        this.eroObj = eroObj;
-    }
-
-    @Override
-    public void setPcepAttribute(PcepAttribute attrList) {
-        this.attrList = attrList;
-    }
-
-    /**
-     * constructor to initialize member variables.
-     *
-     * @param eroObj pcep ero object
-     * @param attrList pcep attribute
-     */
-    public PcepMsgPathVer1(PcepEroObject eroObj, PcepAttribute attrList) {
-        this.eroObj = eroObj;
-        isEroObjectSet = true;
-        this.attrList = attrList;
-        if (attrList == null) {
-            isAttributeListSet = false;
-        } else {
-            isAttributeListSet = true;
-        }
-    }
-
-    @Override
-    public PcepMsgPath read(ChannelBuffer cb) throws PcepParseException {
-        PcepEroObject eroObj;
-        PcepAttribute attrList;
-
-        eroObj = PcepEroObjectVer1.read(cb);
-        attrList = PcepAttributeVer1.read(cb);
-
-        return new PcepMsgPathVer1(eroObj, attrList);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-        int iLenStartIndex = cb.writerIndex();
-
-        //write Object header
-        if (this.isEroObjectSet) {
-            this.eroObj.write(cb);
-        }
-        if (this.isAttributeListSet) {
-            attrList.write(cb);
-        }
-
-        return cb.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Builder class for PCEP Message path.
-     */
-    public static class Builder implements PcepMsgPath.Builder {
-
-        private boolean bIsEROObjectSet = false;
-        private boolean bIsPcepAttributeSet = false;
-
-        //PCEP ERO Object
-        private PcepEroObject eroObject;
-        //PCEP Attribute list
-        private PcepAttribute pcepAttribute;
-
-        @Override
-        public PcepMsgPath build() throws PcepParseException {
-
-            //PCEP ERO Object
-            PcepEroObject eroObject = null;
-            //PCEP Attribute list
-            PcepAttribute pcepAttribute = null;
-
-            if (!this.bIsEROObjectSet) {
-                throw new PcepParseException("ERO Object NOT Set while building PcepMsgPath.");
-            } else {
-                eroObject = this.eroObject;
-            }
-            if (!this.bIsPcepAttributeSet) {
-                throw new PcepParseException("Pcep Attributes NOT Set while building PcepMsgPath.");
-            } else {
-                pcepAttribute = this.pcepAttribute;
-            }
-
-            return new PcepMsgPathVer1(eroObject, pcepAttribute);
-        }
-
-        @Override
-        public PcepEroObject getEroObject() {
-            return this.eroObject;
-        }
-
-        @Override
-        public PcepAttribute getPcepAttribute() {
-            return this.pcepAttribute;
-        }
-
-        @Override
-        public Builder setEroObject(PcepEroObject eroObject) {
-            this.eroObject = eroObject;
-            this.bIsEROObjectSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setPcepAttribute(PcepAttribute pcepAttribute) {
-            this.pcepAttribute = pcepAttribute;
-            this.bIsPcepAttributeSet = true;
-            return this;
-        }
-
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("EroObject", eroObj).add("AttributeList", attrList)
-                .toString();
-    }
+package org.onosproject.pcepio.protocol.ver1;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepAttribute;
+import org.onosproject.pcepio.protocol.PcepEroObject;
+import org.onosproject.pcepio.protocol.PcepMsgPath;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP Message PAth for update message.
+ * Reference :PCE extensions for stateful draft-ietf-pce-stateful-pce-10.
+ */
+public class PcepMsgPathVer1 implements PcepMsgPath {
+
+    /*
+     *  <path>         ::= <ERO><attribute-list>
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepMsgPathVer1.class);
+    //PcepEroObject
+    private PcepEroObject eroObj;
+    private boolean isEroObjectSet;
+    // PcepAttribute
+    private PcepAttribute attrList;
+    private boolean isAttributeListSet;
+
+    /**
+     * constructor to initialize objects.
+     */
+    public PcepMsgPathVer1() {
+        eroObj = null;
+        attrList = null;
+        isEroObjectSet = false;
+        isAttributeListSet = false;
+    }
+
+    @Override
+    public PcepEroObject getEroObject() {
+        return eroObj;
+    }
+
+    @Override
+    public PcepAttribute getPcepAttribute() {
+        return attrList;
+    }
+
+    @Override
+    public void setEroObject(PcepEroObject eroObj) {
+        this.eroObj = eroObj;
+    }
+
+    @Override
+    public void setPcepAttribute(PcepAttribute attrList) {
+        this.attrList = attrList;
+    }
+
+    /**
+     * constructor to initialize member variables.
+     *
+     * @param eroObj pcep ero object
+     * @param attrList pcep attribute
+     */
+    public PcepMsgPathVer1(PcepEroObject eroObj, PcepAttribute attrList) {
+        this.eroObj = eroObj;
+        isEroObjectSet = true;
+        this.attrList = attrList;
+        if (attrList == null) {
+            isAttributeListSet = false;
+        } else {
+            isAttributeListSet = true;
+        }
+    }
+
+    @Override
+    public PcepMsgPath read(ChannelBuffer cb) throws PcepParseException {
+        PcepEroObject eroObj;
+        PcepAttribute attrList;
+
+        eroObj = PcepEroObjectVer1.read(cb);
+        attrList = PcepAttributeVer1.read(cb);
+
+        return new PcepMsgPathVer1(eroObj, attrList);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+        int iLenStartIndex = cb.writerIndex();
+
+        //write Object header
+        if (this.isEroObjectSet) {
+            this.eroObj.write(cb);
+        }
+        if (this.isAttributeListSet) {
+            attrList.write(cb);
+        }
+
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Builder class for PCEP Message path.
+     */
+    public static class Builder implements PcepMsgPath.Builder {
+
+        private boolean bIsEROObjectSet = false;
+        private boolean bIsPcepAttributeSet = false;
+
+        //PCEP ERO Object
+        private PcepEroObject eroObject;
+        //PCEP Attribute list
+        private PcepAttribute pcepAttribute;
+
+        @Override
+        public PcepMsgPath build() throws PcepParseException {
+
+            //PCEP ERO Object
+            PcepEroObject eroObject = null;
+            //PCEP Attribute list
+            PcepAttribute pcepAttribute = null;
+
+            if (!this.bIsEROObjectSet) {
+                throw new PcepParseException("ERO Object NOT Set while building PcepMsgPath.");
+            } else {
+                eroObject = this.eroObject;
+            }
+            if (!this.bIsPcepAttributeSet) {
+                throw new PcepParseException("Pcep Attributes NOT Set while building PcepMsgPath.");
+            } else {
+                pcepAttribute = this.pcepAttribute;
+            }
+
+            return new PcepMsgPathVer1(eroObject, pcepAttribute);
+        }
+
+        @Override
+        public PcepEroObject getEroObject() {
+            return this.eroObject;
+        }
+
+        @Override
+        public PcepAttribute getPcepAttribute() {
+            return this.pcepAttribute;
+        }
+
+        @Override
+        public Builder setEroObject(PcepEroObject eroObject) {
+            this.eroObject = eroObject;
+            this.bIsEROObjectSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setPcepAttribute(PcepAttribute pcepAttribute) {
+            this.pcepAttribute = pcepAttribute;
+            this.bIsPcepAttributeSet = true;
+            return this;
+        }
+
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("EroObject", eroObj).add("AttributeList", attrList)
+                .toString();
+    }
 }
\ No newline at end of file
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRPObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRPObjectVer1.java
index afb85bf..3a4890d 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRPObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRPObjectVer1.java
@@ -1,439 +1,439 @@
-/*
- * 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.PcepRPObject;
-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 RP object.
- */
-public class PcepRPObjectVer1 implements PcepRPObject {
-
-    /*
-     *  RP Object.
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                          Flags                    |O|B|R| Pri |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                        Request-ID-number                      |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                                                               |
-    //                      Optional TLVs                          //
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepRPObjectVer1.class);
-
-    public static final byte RP_OBJ_TYPE = 1;
-    public static final byte RP_OBJ_CLASS = 2;
-    public static final byte RP_OBJECT_VERSION = 1;
-    public static final short RP_OBJ_MINIMUM_LENGTH = 12;
-
-    public static final int DEFAULT_REQUEST_ID_NUM = 0;
-    //Signalled , all default values to be checked.
-    public static final boolean DEFAULT_OFLAG = false;
-    public static final boolean DEFAULT_BFLAG = false;
-    public static final boolean DEFAULT_RFLAG = false;
-    public static final byte DEFAULT_PRIFLAG = 0;
-    public static final int OBJECT_HEADER_LENGTH = 4;
-    public static final int OFLAG_SHIFT_VALUE = 5;
-    public static final int BFLAG_SHIFT_VALUE = 4;
-    public static final int RFLAG_SHIFT_VALUE = 3;
-    public static final int OFLAG_TEMP_SHIFT_VALUE = 0x20;
-    public static final int BFLAG_TEMP_SHIFT_VALUE = 0x10;
-    public static final int RFLAG_TEMP_SHIFT_VALUE = 0x08;
-    public static final int PRIFLAG_TEMP_SHIFT_VALUE = 0x07;
-    public static final int BIT_SET = 1;
-    public static final int BIT_RESET = 0;
-    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
-
-    public static final PcepObjectHeader DEFAULT_RP_OBJECT_HEADER = new PcepObjectHeader(RP_OBJ_CLASS, RP_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RP_OBJ_MINIMUM_LENGTH);
-
-    private PcepObjectHeader rpObjHeader;
-    private int iRequestIdNum;
-    private boolean bOFlag;
-    private boolean bBFlag;
-    private boolean bRFlag;
-    private byte yPriFlag; // 3bytes
-    private LinkedList<PcepValueType> llOptionalTlv;
-
-    /**
-     * Constructor to initialize variables.
-     *
-     * @param rpObjHeader RP-OBJECT header
-     * @param iRequestIdNum Request-ID-number
-     * @param bOFlag O-flag
-     * @param bBFlag B-flag
-     * @param bRFlag R-flag
-     * @param yPriFlag Pri-flag
-     * @param llOptionalTlv linked list of Optional TLV
-     */
-    public PcepRPObjectVer1(PcepObjectHeader rpObjHeader, int iRequestIdNum, boolean bOFlag, boolean bBFlag,
-            boolean bRFlag, byte yPriFlag, LinkedList<PcepValueType> llOptionalTlv) {
-        this.rpObjHeader = rpObjHeader;
-        this.iRequestIdNum = iRequestIdNum;
-        this.bOFlag = bOFlag;
-        this.bBFlag = bBFlag;
-        this.bRFlag = bRFlag;
-        this.yPriFlag = yPriFlag;
-        this.llOptionalTlv = llOptionalTlv;
-    }
-
-    /**
-     * Sets RP Object header.
-     *
-     * @param obj RP Object header
-     */
-    public void setRPObjHeader(PcepObjectHeader obj) {
-        this.rpObjHeader = obj;
-    }
-
-    @Override
-    public void setRequestIdNum(int iRequestIdNum) {
-        this.iRequestIdNum = iRequestIdNum;
-    }
-
-    @Override
-    public void setOFlag(boolean bOFlag) {
-        this.bOFlag = bOFlag;
-    }
-
-    @Override
-    public void setBFlag(boolean bBFlag) {
-        this.bBFlag = bBFlag;
-    }
-
-    @Override
-    public void setRFlag(boolean bRFlag) {
-        this.bRFlag = bRFlag;
-    }
-
-    @Override
-    public void setPriFlag(byte yPriFlag) {
-        this.yPriFlag = yPriFlag;
-    }
-
-    /**
-     * Returns RP Object header.
-     *
-     * @return rpObjHeader
-     */
-    public PcepObjectHeader getRPObjHeader() {
-        return this.rpObjHeader;
-    }
-
-    @Override
-    public int getRequestIdNum() {
-        return this.iRequestIdNum;
-    }
-
-    @Override
-    public boolean getOFlag() {
-        return this.bOFlag;
-    }
-
-    @Override
-    public boolean getBFlag() {
-        return this.bBFlag;
-    }
-
-    @Override
-    public boolean getRFlag() {
-        return this.bRFlag;
-    }
-
-    @Override
-    public byte getPriFlag() {
-        return this.yPriFlag;
-    }
-
-    /**
-     * Reads the channel buffer and returns the object of PcepRPObject.
-     *
-     * @param cb of type channel buffer
-     * @return the object of PcepRPObject
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public static PcepRPObject read(ChannelBuffer cb) throws PcepParseException {
-        log.debug("read");
-        PcepObjectHeader rpObjHeader;
-        int iRequestIdNum;
-        boolean bOFlag;
-        boolean bBFlag;
-        boolean bRFlag;
-        byte yPriFlag; // 3bytes
-        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
-
-        rpObjHeader = PcepObjectHeader.read(cb);
-
-        //take only LspObject buffer.
-        ChannelBuffer tempCb = cb.readBytes(rpObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
-
-        int iTemp = tempCb.readInt();
-        yPriFlag = (byte) (iTemp & PRIFLAG_TEMP_SHIFT_VALUE);
-        bOFlag = (iTemp & OFLAG_TEMP_SHIFT_VALUE) == OFLAG_TEMP_SHIFT_VALUE ? true : false;
-        bBFlag = (iTemp & BFLAG_TEMP_SHIFT_VALUE) == BFLAG_TEMP_SHIFT_VALUE ? true : false;
-        bRFlag = (iTemp & RFLAG_TEMP_SHIFT_VALUE) == RFLAG_TEMP_SHIFT_VALUE ? true : false;
-
-        iRequestIdNum = tempCb.readInt();
-
-        // parse optional TLV
-        llOptionalTlv = parseOptionalTlv(tempCb);
-
-        return new PcepRPObjectVer1(rpObjHeader, iRequestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-
-        //write Object header
-        int objStartIndex = cb.writerIndex();
-
-        int objLenIndex = rpObjHeader.write(cb);
-
-        if (objLenIndex <= 0) {
-            throw new PcepParseException("ObjectLength Index is " + objLenIndex);
-        }
-        int iTemp;
-        iTemp = (yPriFlag);
-
-        iTemp = (bOFlag) ? (iTemp | OFLAG_SHIFT_VALUE) : iTemp;
-        iTemp = (bBFlag) ? (iTemp | BFLAG_SHIFT_VALUE) : iTemp;
-        iTemp = (bRFlag) ? (iTemp | RFLAG_SHIFT_VALUE) : iTemp;
-
-        cb.writeInt(iTemp);
-        cb.writeInt(iRequestIdNum);
-
-        // Add optional TLV
-        packOptionalTlv(cb);
-
-        //Update object length now
-        int length = cb.writerIndex() - objStartIndex;
-
-        //will be helpful during print().
-        rpObjHeader.setObjLen((short) length);
-
-        cb.setShort(objLenIndex, (short) length);
-        return cb.writerIndex();
-    }
-
-    /**
-     * Returns list of optional tlvs.
-     *
-     * @param cb of type channel buffer.
-     * @return llOutOptionalTlv linked list of Optional TLV
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
-
-        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
-        //Currently no optional TLvs, will be added based on requirements.
-        return llOutOptionalTlv;
-    }
-
-    /**
-     * Returns optional tlvs.
-     *
-     * @param cb of type channel buffer
-     * @return llOptionalTlv linked list of Optional TLV
-     */
-    protected int packOptionalTlv(ChannelBuffer cb) {
-
-        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
-        while (listIterator.hasNext()) {
-            listIterator.next().write(cb);
-        }
-
-        return cb.writerIndex();
-    }
-
-    /**
-     * Builder class for PCEP rp object.
-     */
-    public static class Builder implements PcepRPObject.Builder {
-
-        private boolean bIsHeaderSet = false;
-        private boolean bIsRequestIdNumSet = false;
-        private boolean bIsOFlagSet = false;
-        private boolean bIsRFlagset = false;
-        private boolean bIsBFlagSet = false;
-        private boolean bIsPriFlagSet = false;
-
-        private PcepObjectHeader rpObjHeader;
-        private int requestIdNum;
-        private boolean bOFlag;
-        private boolean bBFlag;
-        private boolean bRFlag;
-        private byte yPriFlag;
-        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepRPObject build() {
-            PcepObjectHeader lspObjHeader = this.bIsHeaderSet ? this.rpObjHeader : DEFAULT_RP_OBJECT_HEADER;
-
-            int requestIdNum = this.bIsRequestIdNumSet ? this.requestIdNum : DEFAULT_REQUEST_ID_NUM;
-            boolean bOFlag = this.bIsOFlagSet ? this.bOFlag : DEFAULT_OFLAG;
-            boolean bBFlag = this.bIsBFlagSet ? this.bBFlag : DEFAULT_BFLAG;
-            boolean bRFlag = this.bIsRFlagset ? this.bRFlag : DEFAULT_RFLAG;
-            byte yPriFlag = this.bIsPriFlagSet ? this.yPriFlag : DEFAULT_PRIFLAG;
-
-            if (bIsPFlagSet) {
-                lspObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                lspObjHeader.setIFlag(bIFlag);
-            }
-
-            return new PcepRPObjectVer1(lspObjHeader, requestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
-        }
-
-        @Override
-        public PcepObjectHeader getRPObjHeader() {
-            return this.rpObjHeader;
-        }
-
-        @Override
-        public Builder setRPObjHeader(PcepObjectHeader obj) {
-            this.rpObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public int getRequestIdNum() {
-            return this.requestIdNum;
-        }
-
-        @Override
-        public Builder setRequestIdNum(int value) {
-            this.requestIdNum = value;
-            this.bIsRequestIdNumSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setOFlag(boolean value) {
-            this.bOFlag = value;
-            this.bIsOFlagSet = true;
-            return this;
-        }
-
-        @Override
-        public boolean getBFlag() {
-            return this.bBFlag;
-        }
-
-        @Override
-        public Builder setBFlag(boolean value) {
-            this.bBFlag = value;
-            this.bIsBFlagSet = true;
-            return this;
-        }
-
-        @Override
-        public boolean getRFlag() {
-            return this.bRFlag;
-        }
-
-        @Override
-        public Builder setRFlag(boolean value) {
-            this.bRFlag = value;
-            this.bIsRFlagset = true;
-            return this;
-        }
-
-        @Override
-        public byte getPriFlag() {
-            return this.yPriFlag;
-        }
-
-        @Override
-        public Builder setPriFlag(byte value) {
-            this.yPriFlag = value;
-            this.bIsPriFlagSet = 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 boolean getOFlag() {
-            return this.bOFlag;
-        }
-
-    }
-
-    @Override
-    public LinkedList<PcepValueType> getOptionalTlv() {
-        return this.llOptionalTlv;
-    }
-
-    @Override
-    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
-        this.llOptionalTlv = llOptionalTlv;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("ObjectHeader", rpObjHeader).add("OFlag", (bOFlag) ? 1 : 0)
-                .add("BFlag", (bBFlag) ? 1 : 0).add("RFlag", (bRFlag) ? 1 : 0).add("PriFlag", yPriFlag)
-                .add("RequestIdNumber", iRequestIdNum).add("OptionalTlv", 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.PcepRPObject;
+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 RP object.
+ */
+public class PcepRPObjectVer1 implements PcepRPObject {
+
+    /*
+     *  RP Object.
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                          Flags                    |O|B|R| Pri |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                        Request-ID-number                      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    //                      Optional TLVs                          //
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepRPObjectVer1.class);
+
+    public static final byte RP_OBJ_TYPE = 1;
+    public static final byte RP_OBJ_CLASS = 2;
+    public static final byte RP_OBJECT_VERSION = 1;
+    public static final short RP_OBJ_MINIMUM_LENGTH = 12;
+
+    public static final int DEFAULT_REQUEST_ID_NUM = 0;
+    //Signalled , all default values to be checked.
+    public static final boolean DEFAULT_OFLAG = false;
+    public static final boolean DEFAULT_BFLAG = false;
+    public static final boolean DEFAULT_RFLAG = false;
+    public static final byte DEFAULT_PRIFLAG = 0;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+    public static final int OFLAG_SHIFT_VALUE = 5;
+    public static final int BFLAG_SHIFT_VALUE = 4;
+    public static final int RFLAG_SHIFT_VALUE = 3;
+    public static final int OFLAG_TEMP_SHIFT_VALUE = 0x20;
+    public static final int BFLAG_TEMP_SHIFT_VALUE = 0x10;
+    public static final int RFLAG_TEMP_SHIFT_VALUE = 0x08;
+    public static final int PRIFLAG_TEMP_SHIFT_VALUE = 0x07;
+    public static final int BIT_SET = 1;
+    public static final int BIT_RESET = 0;
+    public static final int MINIMUM_COMMON_HEADER_LENGTH = 4;
+
+    public static final PcepObjectHeader DEFAULT_RP_OBJECT_HEADER = new PcepObjectHeader(RP_OBJ_CLASS, RP_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RP_OBJ_MINIMUM_LENGTH);
+
+    private PcepObjectHeader rpObjHeader;
+    private int iRequestIdNum;
+    private boolean bOFlag;
+    private boolean bBFlag;
+    private boolean bRFlag;
+    private byte yPriFlag; // 3bytes
+    private LinkedList<PcepValueType> llOptionalTlv;
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param rpObjHeader RP-OBJECT header
+     * @param iRequestIdNum Request-ID-number
+     * @param bOFlag O-flag
+     * @param bBFlag B-flag
+     * @param bRFlag R-flag
+     * @param yPriFlag Pri-flag
+     * @param llOptionalTlv linked list of Optional TLV
+     */
+    public PcepRPObjectVer1(PcepObjectHeader rpObjHeader, int iRequestIdNum, boolean bOFlag, boolean bBFlag,
+            boolean bRFlag, byte yPriFlag, LinkedList<PcepValueType> llOptionalTlv) {
+        this.rpObjHeader = rpObjHeader;
+        this.iRequestIdNum = iRequestIdNum;
+        this.bOFlag = bOFlag;
+        this.bBFlag = bBFlag;
+        this.bRFlag = bRFlag;
+        this.yPriFlag = yPriFlag;
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    /**
+     * Sets RP Object header.
+     *
+     * @param obj RP Object header
+     */
+    public void setRPObjHeader(PcepObjectHeader obj) {
+        this.rpObjHeader = obj;
+    }
+
+    @Override
+    public void setRequestIdNum(int iRequestIdNum) {
+        this.iRequestIdNum = iRequestIdNum;
+    }
+
+    @Override
+    public void setOFlag(boolean bOFlag) {
+        this.bOFlag = bOFlag;
+    }
+
+    @Override
+    public void setBFlag(boolean bBFlag) {
+        this.bBFlag = bBFlag;
+    }
+
+    @Override
+    public void setRFlag(boolean bRFlag) {
+        this.bRFlag = bRFlag;
+    }
+
+    @Override
+    public void setPriFlag(byte yPriFlag) {
+        this.yPriFlag = yPriFlag;
+    }
+
+    /**
+     * Returns RP Object header.
+     *
+     * @return rpObjHeader
+     */
+    public PcepObjectHeader getRPObjHeader() {
+        return this.rpObjHeader;
+    }
+
+    @Override
+    public int getRequestIdNum() {
+        return this.iRequestIdNum;
+    }
+
+    @Override
+    public boolean getOFlag() {
+        return this.bOFlag;
+    }
+
+    @Override
+    public boolean getBFlag() {
+        return this.bBFlag;
+    }
+
+    @Override
+    public boolean getRFlag() {
+        return this.bRFlag;
+    }
+
+    @Override
+    public byte getPriFlag() {
+        return this.yPriFlag;
+    }
+
+    /**
+     * Reads the channel buffer and returns the object of PcepRPObject.
+     *
+     * @param cb of type channel buffer
+     * @return the object of PcepRPObject
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepRPObject read(ChannelBuffer cb) throws PcepParseException {
+        log.debug("read");
+        PcepObjectHeader rpObjHeader;
+        int iRequestIdNum;
+        boolean bOFlag;
+        boolean bBFlag;
+        boolean bRFlag;
+        byte yPriFlag; // 3bytes
+        LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        rpObjHeader = PcepObjectHeader.read(cb);
+
+        //take only LspObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(rpObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+
+        int iTemp = tempCb.readInt();
+        yPriFlag = (byte) (iTemp & PRIFLAG_TEMP_SHIFT_VALUE);
+        bOFlag = (iTemp & OFLAG_TEMP_SHIFT_VALUE) == OFLAG_TEMP_SHIFT_VALUE ? true : false;
+        bBFlag = (iTemp & BFLAG_TEMP_SHIFT_VALUE) == BFLAG_TEMP_SHIFT_VALUE ? true : false;
+        bRFlag = (iTemp & RFLAG_TEMP_SHIFT_VALUE) == RFLAG_TEMP_SHIFT_VALUE ? true : false;
+
+        iRequestIdNum = tempCb.readInt();
+
+        // parse optional TLV
+        llOptionalTlv = parseOptionalTlv(tempCb);
+
+        return new PcepRPObjectVer1(rpObjHeader, iRequestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        int objLenIndex = rpObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException("ObjectLength Index is " + objLenIndex);
+        }
+        int iTemp;
+        iTemp = (yPriFlag);
+
+        iTemp = (bOFlag) ? (iTemp | OFLAG_SHIFT_VALUE) : iTemp;
+        iTemp = (bBFlag) ? (iTemp | BFLAG_SHIFT_VALUE) : iTemp;
+        iTemp = (bRFlag) ? (iTemp | RFLAG_SHIFT_VALUE) : iTemp;
+
+        cb.writeInt(iTemp);
+        cb.writeInt(iRequestIdNum);
+
+        // Add optional TLV
+        packOptionalTlv(cb);
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+
+        //will be helpful during print().
+        rpObjHeader.setObjLen((short) length);
+
+        cb.setShort(objLenIndex, (short) length);
+        return cb.writerIndex();
+    }
+
+    /**
+     * Returns list of optional tlvs.
+     *
+     * @param cb of type channel buffer.
+     * @return llOutOptionalTlv linked list of Optional TLV
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    protected static LinkedList<PcepValueType> parseOptionalTlv(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llOutOptionalTlv = new LinkedList<PcepValueType>();
+        //Currently no optional TLvs, will be added based on requirements.
+        return llOutOptionalTlv;
+    }
+
+    /**
+     * Returns optional tlvs.
+     *
+     * @param cb of type channel buffer
+     * @return llOptionalTlv linked list of Optional TLV
+     */
+    protected int packOptionalTlv(ChannelBuffer cb) {
+
+        ListIterator<PcepValueType> listIterator = llOptionalTlv.listIterator();
+        while (listIterator.hasNext()) {
+            listIterator.next().write(cb);
+        }
+
+        return cb.writerIndex();
+    }
+
+    /**
+     * Builder class for PCEP rp object.
+     */
+    public static class Builder implements PcepRPObject.Builder {
+
+        private boolean bIsHeaderSet = false;
+        private boolean bIsRequestIdNumSet = false;
+        private boolean bIsOFlagSet = false;
+        private boolean bIsRFlagset = false;
+        private boolean bIsBFlagSet = false;
+        private boolean bIsPriFlagSet = false;
+
+        private PcepObjectHeader rpObjHeader;
+        private int requestIdNum;
+        private boolean bOFlag;
+        private boolean bBFlag;
+        private boolean bRFlag;
+        private byte yPriFlag;
+        private LinkedList<PcepValueType> llOptionalTlv = new LinkedList<PcepValueType>();
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepRPObject build() {
+            PcepObjectHeader lspObjHeader = this.bIsHeaderSet ? this.rpObjHeader : DEFAULT_RP_OBJECT_HEADER;
+
+            int requestIdNum = this.bIsRequestIdNumSet ? this.requestIdNum : DEFAULT_REQUEST_ID_NUM;
+            boolean bOFlag = this.bIsOFlagSet ? this.bOFlag : DEFAULT_OFLAG;
+            boolean bBFlag = this.bIsBFlagSet ? this.bBFlag : DEFAULT_BFLAG;
+            boolean bRFlag = this.bIsRFlagset ? this.bRFlag : DEFAULT_RFLAG;
+            byte yPriFlag = this.bIsPriFlagSet ? this.yPriFlag : DEFAULT_PRIFLAG;
+
+            if (bIsPFlagSet) {
+                lspObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                lspObjHeader.setIFlag(bIFlag);
+            }
+
+            return new PcepRPObjectVer1(lspObjHeader, requestIdNum, bOFlag, bBFlag, bRFlag, yPriFlag, llOptionalTlv);
+        }
+
+        @Override
+        public PcepObjectHeader getRPObjHeader() {
+            return this.rpObjHeader;
+        }
+
+        @Override
+        public Builder setRPObjHeader(PcepObjectHeader obj) {
+            this.rpObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public int getRequestIdNum() {
+            return this.requestIdNum;
+        }
+
+        @Override
+        public Builder setRequestIdNum(int value) {
+            this.requestIdNum = value;
+            this.bIsRequestIdNumSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setOFlag(boolean value) {
+            this.bOFlag = value;
+            this.bIsOFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getBFlag() {
+            return this.bBFlag;
+        }
+
+        @Override
+        public Builder setBFlag(boolean value) {
+            this.bBFlag = value;
+            this.bIsBFlagSet = true;
+            return this;
+        }
+
+        @Override
+        public boolean getRFlag() {
+            return this.bRFlag;
+        }
+
+        @Override
+        public Builder setRFlag(boolean value) {
+            this.bRFlag = value;
+            this.bIsRFlagset = true;
+            return this;
+        }
+
+        @Override
+        public byte getPriFlag() {
+            return this.yPriFlag;
+        }
+
+        @Override
+        public Builder setPriFlag(byte value) {
+            this.yPriFlag = value;
+            this.bIsPriFlagSet = 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 boolean getOFlag() {
+            return this.bOFlag;
+        }
+
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getOptionalTlv() {
+        return this.llOptionalTlv;
+    }
+
+    @Override
+    public void setOptionalTlv(LinkedList<PcepValueType> llOptionalTlv) {
+        this.llOptionalTlv = llOptionalTlv;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("ObjectHeader", rpObjHeader).add("OFlag", (bOFlag) ? 1 : 0)
+                .add("BFlag", (bBFlag) ? 1 : 0).add("RFlag", (bRFlag) ? 1 : 0).add("PriFlag", yPriFlag)
+                .add("RequestIdNumber", iRequestIdNum).add("OptionalTlv", llOptionalTlv).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRroObjectVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRroObjectVer1.java
index d073a02..4aff0db 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRroObjectVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepRroObjectVer1.java
@@ -1,343 +1,343 @@
-/*
- * 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.PcepRroObject;
-import org.onosproject.pcepio.types.IPv4SubObject;
-import org.onosproject.pcepio.types.IPv6SubObject;
-import org.onosproject.pcepio.types.LabelSubObject;
-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 RRO object.
- */
-public class PcepRroObjectVer1 implements PcepRroObject {
-
-    /*
-     * rfc3209
-          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)       |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |                                                               |
-         //                        (Subobjects)                          //
-         |                                                               |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-            Each subobject has its own Length
-            field.  The length contains the total length of the subobject in
-            bytes, including the Type and Length fields.  The length MUST always
-            be a multiple of 4, and at least 4.
-
-            An empty RRO with no subobjects is considered illegal.
-            Three kinds of subobjects are currently defined.
-
-           Subobject 1: IPv4 address
-
-            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
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |      Type     |     Length    | IPv4 address (4 bytes)        |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           | IPv4 address (continued)      | Prefix Length |      Flags    |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-           Subobject 2: IPv6 address
-
-            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
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |      Type     |     Length    | IPv6 address (16 bytes)       |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           | IPv6 address (continued)                                      |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           | IPv6 address (continued)                                      |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           | IPv6 address (continued)                                      |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           | IPv6 address (continued)      | Prefix Length |      Flags    |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-           Subobject 3, Label
-
-            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
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |     Type      |     Length    |    Flags      |   C-Type      |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-           |       Contents of Label Object                                |
-           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepRroObjectVer1.class);
-
-    public static final byte RRO_OBJ_TYPE = 1;
-    public static final byte RRO_OBJ_CLASS = 8;
-    public static final byte RRO_OBJECT_VERSION = 1;
-    public static final short RRO_OBJ_MINIMUM_LENGTH = 12;
-    public static final int OBJECT_HEADER_LENGTH = 4;
-    public static final int YTYPE_SHIFT_VALUE = 0x7F;
-
-    static final PcepObjectHeader DEFAULT_RRO_OBJECT_HEADER = new PcepObjectHeader(RRO_OBJ_CLASS, RRO_OBJ_TYPE,
-            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RRO_OBJ_MINIMUM_LENGTH);
-
-    private short rroObjType = 0;
-    private byte length;
-    private byte prefixLength;
-    private byte resvd;
-    PcepObjectHeader rroObjHeader;
-    private LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
-
-    /**
-     * Reset variables.
-     */
-    public PcepRroObjectVer1() {
-        this.rroObjHeader = null;
-        this.rroObjType = 0;
-        this.length = 0;
-    }
-
-    /**
-     * constructor to initialize parameters for RRO object.
-     *
-     * @param rroObjHeader RRO object header
-     * @param llSubObjects list of sub objects
-     */
-    public PcepRroObjectVer1(PcepObjectHeader rroObjHeader, LinkedList<PcepValueType> llSubObjects) {
-        this.rroObjHeader = rroObjHeader;
-        this.llSubObjects = llSubObjects;
-    }
-
-    /**
-     * Returns PCEP RRO Object Header.
-     *
-     * @return rroObjHeader RRO Object header
-     */
-    public PcepObjectHeader getRroObjHeader() {
-        return this.rroObjHeader;
-    }
-
-    /**
-     * Sets PCEP RRO Object Header.
-     *
-     * @param obj Object header
-     */
-    public void setRroObjHeader(PcepObjectHeader obj) {
-        this.rroObjHeader = obj;
-    }
-
-    @Override
-    public LinkedList<PcepValueType> getSubObjects() {
-        return this.llSubObjects;
-    }
-
-    @Override
-    public void setSubObjects(LinkedList<PcepValueType> llSubObjects) {
-        this.llSubObjects = llSubObjects;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of PcepRroObject.
-     *
-     * @param cb of type channel buffer
-     * @return object of PcepRroObject
-     * @throws PcepParseException when fails to read from channel buffer
-     */
-    public static PcepRroObject read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepObjectHeader rroObjHeader;
-        LinkedList<PcepValueType> llSubObjects;
-        rroObjHeader = PcepObjectHeader.read(cb);
-
-        //take only RroObject buffer.
-        ChannelBuffer tempCb = cb.readBytes(rroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
-        llSubObjects = parseSubObjects(tempCb);
-
-        return new PcepRroObjectVer1(rroObjHeader, llSubObjects);
-    }
-
-    /**
-     * Returns list of sub objects.
-     *
-     * @param cb of type channel buffer
-     * @return list of sub objects
-     * @throws PcepParseException when fails to parse list of sub objects
-     */
-    protected static LinkedList<PcepValueType> parseSubObjects(ChannelBuffer cb) throws PcepParseException {
-
-        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
-
-        while (0 < cb.readableBytes()) {
-
-            //check the Type of the Sub objects
-            byte yType = cb.readByte();
-            yType = (byte) (yType & (YTYPE_SHIFT_VALUE));
-            byte hLength = cb.readByte();
-
-            PcepValueType subObj;
-
-            switch (yType) {
-
-            case IPv4SubObject.TYPE:
-                subObj = IPv4SubObject.read(cb);
-                break;
-            case IPv6SubObject.TYPE:
-                byte[] ipv6Value = new byte[IPv6SubObject.VALUE_LENGTH];
-                cb.readBytes(ipv6Value, 0, IPv6SubObject.VALUE_LENGTH);
-                subObj = new IPv6SubObject(ipv6Value);
-                break;
-            case LabelSubObject.TYPE:
-                subObj = LabelSubObject.read(cb);
-                break;
-            default:
-                throw new PcepParseException(" Unexpected sub object. Type: " + (int) yType);
-            }
-            // Check for the padding
-            int pad = hLength % 4;
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= cb.readableBytes()) {
-                    cb.skipBytes(pad);
-                }
-            }
-            llSubObjects.add(subObj);
-        }
-
-        return llSubObjects;
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) throws PcepParseException {
-        //write Object header
-        int objStartIndex = cb.writerIndex();
-
-        int objLenIndex = rroObjHeader.write(cb);
-
-        if (objLenIndex <= 0) {
-            throw new PcepParseException(" object Length Index" + objLenIndex);
-        }
-
-        ListIterator<PcepValueType> listIterator = llSubObjects.listIterator();
-
-        while (listIterator.hasNext()) {
-            listIterator.next().write(cb);
-        }
-
-        //Update object length now
-        int length = cb.writerIndex() - objStartIndex;
-        cb.setShort(objLenIndex, (short) length);
-        //will be helpful during print().
-        rroObjHeader.setObjLen((short) length);
-
-        //As per RFC the length of object should be multiples of 4
-        int pad = length % 4;
-
-        if (0 != pad) {
-            pad = 4 - pad;
-            for (int i = 0; i < pad; i++) {
-                cb.writeByte((byte) 0);
-            }
-            length = length + pad;
-        }
-        objLenIndex = cb.writerIndex();
-        return objLenIndex;
-    }
-
-    /**
-     * Builder class for PCEP RRO object.
-     */
-    public static class Builder implements PcepRroObject.Builder {
-        private boolean bIsHeaderSet = false;
-
-        private PcepObjectHeader rroObjHeader;
-        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
-
-        private boolean bIsPFlagSet = false;
-        private boolean bPFlag;
-
-        private boolean bIsIFlagSet = false;
-        private boolean bIFlag;
-
-        @Override
-        public PcepRroObject build() {
-
-            PcepObjectHeader rroObjHeader = this.bIsHeaderSet ? this.rroObjHeader : DEFAULT_RRO_OBJECT_HEADER;
-
-            if (bIsPFlagSet) {
-                rroObjHeader.setPFlag(bPFlag);
-            }
-
-            if (bIsIFlagSet) {
-                rroObjHeader.setIFlag(bIFlag);
-            }
-            return new PcepRroObjectVer1(rroObjHeader, this.llSubObjects);
-        }
-
-        @Override
-        public PcepObjectHeader getRroObjHeader() {
-            return this.rroObjHeader;
-        }
-
-        @Override
-        public Builder setRroObjHeader(PcepObjectHeader obj) {
-            this.rroObjHeader = obj;
-            this.bIsHeaderSet = true;
-            return this;
-        }
-
-        @Override
-        public LinkedList<PcepValueType> getSubObjects() {
-            return this.llSubObjects;
-        }
-
-        @Override
-        public Builder setSubObjects(LinkedList<PcepValueType> llSubObjects) {
-            this.llSubObjects = llSubObjects;
-            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("SubObjects", llSubObjects).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.PcepRroObject;
+import org.onosproject.pcepio.types.IPv4SubObject;
+import org.onosproject.pcepio.types.IPv6SubObject;
+import org.onosproject.pcepio.types.LabelSubObject;
+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 RRO object.
+ */
+public class PcepRroObjectVer1 implements PcepRroObject {
+
+    /*
+     * rfc3209
+          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)       |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               |
+         //                        (Subobjects)                          //
+         |                                                               |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+            Each subobject has its own Length
+            field.  The length contains the total length of the subobject in
+            bytes, including the Type and Length fields.  The length MUST always
+            be a multiple of 4, and at least 4.
+
+            An empty RRO with no subobjects is considered illegal.
+            Three kinds of subobjects are currently defined.
+
+           Subobject 1: IPv4 address
+
+            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
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |      Type     |     Length    | IPv4 address (4 bytes)        |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | IPv4 address (continued)      | Prefix Length |      Flags    |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+           Subobject 2: IPv6 address
+
+            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
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |      Type     |     Length    | IPv6 address (16 bytes)       |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | IPv6 address (continued)                                      |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | IPv6 address (continued)                                      |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | IPv6 address (continued)                                      |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | IPv6 address (continued)      | Prefix Length |      Flags    |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+           Subobject 3, Label
+
+            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
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |     Type      |     Length    |    Flags      |   C-Type      |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           |       Contents of Label Object                                |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepRroObjectVer1.class);
+
+    public static final byte RRO_OBJ_TYPE = 1;
+    public static final byte RRO_OBJ_CLASS = 8;
+    public static final byte RRO_OBJECT_VERSION = 1;
+    public static final short RRO_OBJ_MINIMUM_LENGTH = 12;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+    public static final int YTYPE_SHIFT_VALUE = 0x7F;
+
+    static final PcepObjectHeader DEFAULT_RRO_OBJECT_HEADER = new PcepObjectHeader(RRO_OBJ_CLASS, RRO_OBJ_TYPE,
+            PcepObjectHeader.REQ_OBJ_OPTIONAL_PROCESS, PcepObjectHeader.RSP_OBJ_PROCESSED, RRO_OBJ_MINIMUM_LENGTH);
+
+    private short rroObjType = 0;
+    private byte length;
+    private byte prefixLength;
+    private byte resvd;
+    PcepObjectHeader rroObjHeader;
+    private LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+    /**
+     * Reset variables.
+     */
+    public PcepRroObjectVer1() {
+        this.rroObjHeader = null;
+        this.rroObjType = 0;
+        this.length = 0;
+    }
+
+    /**
+     * constructor to initialize parameters for RRO object.
+     *
+     * @param rroObjHeader RRO object header
+     * @param llSubObjects list of sub objects
+     */
+    public PcepRroObjectVer1(PcepObjectHeader rroObjHeader, LinkedList<PcepValueType> llSubObjects) {
+        this.rroObjHeader = rroObjHeader;
+        this.llSubObjects = llSubObjects;
+    }
+
+    /**
+     * Returns PCEP RRO Object Header.
+     *
+     * @return rroObjHeader RRO Object header
+     */
+    public PcepObjectHeader getRroObjHeader() {
+        return this.rroObjHeader;
+    }
+
+    /**
+     * Sets PCEP RRO Object Header.
+     *
+     * @param obj Object header
+     */
+    public void setRroObjHeader(PcepObjectHeader obj) {
+        this.rroObjHeader = obj;
+    }
+
+    @Override
+    public LinkedList<PcepValueType> getSubObjects() {
+        return this.llSubObjects;
+    }
+
+    @Override
+    public void setSubObjects(LinkedList<PcepValueType> llSubObjects) {
+        this.llSubObjects = llSubObjects;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of PcepRroObject.
+     *
+     * @param cb of type channel buffer
+     * @return object of PcepRroObject
+     * @throws PcepParseException when fails to read from channel buffer
+     */
+    public static PcepRroObject read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepObjectHeader rroObjHeader;
+        LinkedList<PcepValueType> llSubObjects;
+        rroObjHeader = PcepObjectHeader.read(cb);
+
+        //take only RroObject buffer.
+        ChannelBuffer tempCb = cb.readBytes(rroObjHeader.getObjLen() - OBJECT_HEADER_LENGTH);
+        llSubObjects = parseSubObjects(tempCb);
+
+        return new PcepRroObjectVer1(rroObjHeader, llSubObjects);
+    }
+
+    /**
+     * Returns list of sub objects.
+     *
+     * @param cb of type channel buffer
+     * @return list of sub objects
+     * @throws PcepParseException when fails to parse list of sub objects
+     */
+    protected static LinkedList<PcepValueType> parseSubObjects(ChannelBuffer cb) throws PcepParseException {
+
+        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+        while (0 < cb.readableBytes()) {
+
+            //check the Type of the Sub objects
+            byte yType = cb.readByte();
+            yType = (byte) (yType & (YTYPE_SHIFT_VALUE));
+            byte hLength = cb.readByte();
+
+            PcepValueType subObj;
+
+            switch (yType) {
+
+            case IPv4SubObject.TYPE:
+                subObj = IPv4SubObject.read(cb);
+                break;
+            case IPv6SubObject.TYPE:
+                byte[] ipv6Value = new byte[IPv6SubObject.VALUE_LENGTH];
+                cb.readBytes(ipv6Value, 0, IPv6SubObject.VALUE_LENGTH);
+                subObj = new IPv6SubObject(ipv6Value);
+                break;
+            case LabelSubObject.TYPE:
+                subObj = LabelSubObject.read(cb);
+                break;
+            default:
+                throw new PcepParseException(" Unexpected sub object. Type: " + (int) yType);
+            }
+            // Check for the padding
+            int pad = hLength % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= cb.readableBytes()) {
+                    cb.skipBytes(pad);
+                }
+            }
+            llSubObjects.add(subObj);
+        }
+
+        return llSubObjects;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) throws PcepParseException {
+        //write Object header
+        int objStartIndex = cb.writerIndex();
+
+        int objLenIndex = rroObjHeader.write(cb);
+
+        if (objLenIndex <= 0) {
+            throw new PcepParseException(" object Length Index" + objLenIndex);
+        }
+
+        ListIterator<PcepValueType> listIterator = llSubObjects.listIterator();
+
+        while (listIterator.hasNext()) {
+            listIterator.next().write(cb);
+        }
+
+        //Update object length now
+        int length = cb.writerIndex() - objStartIndex;
+        cb.setShort(objLenIndex, (short) length);
+        //will be helpful during print().
+        rroObjHeader.setObjLen((short) length);
+
+        //As per RFC the length of object should be multiples of 4
+        int pad = length % 4;
+
+        if (0 != pad) {
+            pad = 4 - pad;
+            for (int i = 0; i < pad; i++) {
+                cb.writeByte((byte) 0);
+            }
+            length = length + pad;
+        }
+        objLenIndex = cb.writerIndex();
+        return objLenIndex;
+    }
+
+    /**
+     * Builder class for PCEP RRO object.
+     */
+    public static class Builder implements PcepRroObject.Builder {
+        private boolean bIsHeaderSet = false;
+
+        private PcepObjectHeader rroObjHeader;
+        LinkedList<PcepValueType> llSubObjects = new LinkedList<PcepValueType>();
+
+        private boolean bIsPFlagSet = false;
+        private boolean bPFlag;
+
+        private boolean bIsIFlagSet = false;
+        private boolean bIFlag;
+
+        @Override
+        public PcepRroObject build() {
+
+            PcepObjectHeader rroObjHeader = this.bIsHeaderSet ? this.rroObjHeader : DEFAULT_RRO_OBJECT_HEADER;
+
+            if (bIsPFlagSet) {
+                rroObjHeader.setPFlag(bPFlag);
+            }
+
+            if (bIsIFlagSet) {
+                rroObjHeader.setIFlag(bIFlag);
+            }
+            return new PcepRroObjectVer1(rroObjHeader, this.llSubObjects);
+        }
+
+        @Override
+        public PcepObjectHeader getRroObjHeader() {
+            return this.rroObjHeader;
+        }
+
+        @Override
+        public Builder setRroObjHeader(PcepObjectHeader obj) {
+            this.rroObjHeader = obj;
+            this.bIsHeaderSet = true;
+            return this;
+        }
+
+        @Override
+        public LinkedList<PcepValueType> getSubObjects() {
+            return this.llSubObjects;
+        }
+
+        @Override
+        public Builder setSubObjects(LinkedList<PcepValueType> llSubObjects) {
+            this.llSubObjects = llSubObjects;
+            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("SubObjects", llSubObjects).toString();
+    }
+}
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();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepStateReportVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepStateReportVer1.java
index 6c17274..3a1bfcf 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepStateReportVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepStateReportVer1.java
@@ -1,427 +1,427 @@
-/*
- * 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 org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepAttribute;
-import org.onosproject.pcepio.protocol.PcepBandwidthObject;
-import org.onosproject.pcepio.protocol.PcepEroObject;
-import org.onosproject.pcepio.protocol.PcepLspObject;
-import org.onosproject.pcepio.protocol.PcepRroObject;
-import org.onosproject.pcepio.protocol.PcepSrpObject;
-import org.onosproject.pcepio.protocol.PcepStateReport;
-import org.onosproject.pcepio.types.PcepObjectHeader;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provide the State Report for the Pcep Report Message.
- * Reference :PCE extensions for stateful draft-ietf-pce-stateful-pce-10.
- */
-public class PcepStateReportVer1 implements PcepStateReport {
-    /*
-     * <state-report>     ::= [<SRP>]
-                               <LSP>
-                               <path>
-       Where:
-               <path>     ::= <ERO><attribute-list>[<RRO>]
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepStateReport.class);
-
-    public static final int OBJECT_HEADER_LENGTH = 4;
-
-    /**
-     * Provides PCEP Message path for report message.
-     */
-    public class PcepMsgPath implements PcepStateReport.PcepMsgPath {
-
-        /*
-         * <path>                  ::= <ERO><attribute-list>[<RRO>]
-         */
-
-        //PcepEroObject
-        private PcepEroObject eroObj;
-        private boolean isEroObjectSet;
-        //PcepAttribute List
-        private PcepAttribute attrList;
-        private boolean isAttributeListSet;
-        //PcepRroObject
-        private PcepRroObject rroObj;
-        private boolean isRroObjectSet;
-        private PcepBandwidthObject bandwidth;
-        private boolean isBandwidthObjectSet;
-
-        /**
-         * Constructor to reset the parameters.
-         */
-        public PcepMsgPath() {
-            eroObj = null;
-            attrList = null;
-            rroObj = null;
-            this.isEroObjectSet = false;
-            this.isAttributeListSet = false;
-            this.isRroObjectSet = false;
-            this.isBandwidthObjectSet = false;
-        }
-
-        /**
-         * Constructor to initialize the parameters from PCEP Message path.
-         *
-         * @param eroObj PCEP ERO Object
-         * @param attrList PCEP Attribute
-         * @param rroObj PCEP Rro Object
-         * @param bandwidth PCEP bandwidth object
-         */
-        public PcepMsgPath(PcepEroObject eroObj, PcepAttribute attrList, PcepRroObject rroObj,
-                           PcepBandwidthObject bandwidth) {
-
-            this.eroObj = eroObj;
-            this.attrList = attrList;
-            this.rroObj = rroObj;
-            this.bandwidth = bandwidth;
-            if (null == rroObj) {
-                this.isRroObjectSet = false;
-            } else {
-                this.isRroObjectSet = true;
-            }
-            if (null == eroObj) {
-                this.isEroObjectSet = false;
-            } else {
-                this.isEroObjectSet = true;
-            }
-            if (null == attrList) {
-                this.isAttributeListSet = false;
-            } else {
-                this.isAttributeListSet = true;
-            }
-            if (null == bandwidth) {
-                this.isBandwidthObjectSet = false;
-            } else {
-                this.isBandwidthObjectSet = true;
-            }
-        }
-
-        /**
-         * Returns PcepEroObject.
-         *
-         * @return eroObj PCEP ERO Object
-         */
-        @Override
-        public PcepEroObject getEroObject() {
-            return this.eroObj;
-        }
-
-        /**
-         * Returns PCEP Attribute.
-         *
-         * @return attrList Attribute list
-         */
-        @Override
-        public PcepAttribute getPcepAttribute() {
-            return this.attrList;
-        }
-
-        /**
-         * Returns PcepRroObject.
-         *
-         * @return rroObj PCEP RRO Object
-         */
-        @Override
-        public PcepRroObject getRroObject() {
-            return this.rroObj;
-        }
-
-        @Override
-        public PcepBandwidthObject getBandwidthObject() {
-            return this.bandwidth;
-        }
-
-        @Override
-        public void setEroObject(PcepEroObject eroObj) {
-            this.eroObj = eroObj;
-        }
-
-        @Override
-        public void setPcepAttribute(PcepAttribute attrList) {
-            this.attrList = attrList;
-        }
-
-        @Override
-        public void setRroObject(PcepRroObject rroObj) {
-            this.rroObj = rroObj;
-        }
-
-        @Override
-        public void setBandwidthObject(PcepBandwidthObject bandwidth) {
-            this.bandwidth = bandwidth;
-        }
-
-        /**
-         * Reads all the Objects for PCEP Message Path.
-         *
-         * @param bb of type channel buffer
-         * @return PCEP Message path
-         * @throws PcepParseException when fails to read pcep message path
-         */
-        @Override
-        public PcepMsgPath read(ChannelBuffer bb) throws PcepParseException {
-
-            PcepEroObject eroObj;
-            PcepAttribute attrList;
-            PcepRroObject rroObj = null;
-            PcepBandwidthObject bandwidth = null;
-
-            eroObj = PcepEroObjectVer1.read(bb);
-            attrList = PcepAttributeVer1.read(bb);
-
-            boolean bBreakWhile = false;
-            while (0 < bb.readableBytes()) {
-
-                if (bb.readableBytes() < OBJECT_HEADER_LENGTH) {
-                    break;
-                }
-                bb.markReaderIndex();
-                PcepObjectHeader tempObjHeader = PcepObjectHeader.read(bb);
-                bb.resetReaderIndex();
-                byte yObjClass = tempObjHeader.getObjClass();
-
-                switch (yObjClass) {
-                case PcepRroObjectVer1.RRO_OBJ_CLASS:
-                    rroObj = PcepRroObjectVer1.read(bb);
-                    break;
-                case PcepInterLayerObjectVer1.INTER_LAYER_OBJ_CLASS:
-                    bb.skipBytes(tempObjHeader.getObjLen());
-                    break;
-                case PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS:
-                    bandwidth = PcepBandwidthObjectVer1.read(bb);
-                    break;
-                default:
-                    //Otherthan above objects handle those objects in caller.
-                    bBreakWhile = true;
-                    break;
-                }
-                if (bBreakWhile) {
-                    break;
-                }
-            }
-            return new PcepMsgPath(eroObj, attrList, rroObj, bandwidth);
-        }
-
-        /**
-         * Writes all the objects for PCEP message path.
-         *
-         * @param bb of type channel buffer.
-         * @return object length index
-         * @throws PcepParseException when fails to write to channel buffer
-         */
-        @Override
-        public int write(ChannelBuffer bb) throws PcepParseException {
-            int iLenStartIndex = bb.writerIndex();
-
-            //write Object header
-            if (this.isEroObjectSet) {
-                this.eroObj.write(bb);
-            } else {
-                throw new PcepParseException("Ero object is not set in path");
-            }
-
-            if (this.isAttributeListSet) {
-                this.attrList.write(bb);
-            }
-
-            // RRO is optional check and read
-            if (this.isRroObjectSet) {
-                this.rroObj.write(bb);
-                // bandwidth should come along with RRO.
-                if (this.isBandwidthObjectSet) {
-                    this.bandwidth.write(bb);
-                }
-            }
-            return bb.writerIndex() - iLenStartIndex;
-        }
-
-        @Override
-        public String toString() {
-            ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-            if (attrList instanceof PcepAttribute) {
-                toStrHelper.add("AttributeList", attrList);
-            }
-            if (rroObj instanceof PcepRroObjectVer1) {
-                toStrHelper.add("RroObject", rroObj);
-            }
-            if (bandwidth instanceof PcepBandwidthObjectVer1) {
-                toStrHelper.add("bandwidthObject", bandwidth);
-            }
-            return toStrHelper.toString();
-        }
-    }
-
-    //SRP Object
-    private PcepSrpObject srpObject;
-    //LSP Object
-    private PcepLspObject lspObject;
-    //PcepMsgPath
-    private PcepStateReport.PcepMsgPath msgPath;
-
-    /**
-     * Constructor to reset objects.
-     */
-    public PcepStateReportVer1() {
-        this.srpObject = null;
-        this.lspObject = null;
-        this.msgPath = null;
-    }
-
-    public PcepStateReportVer1(PcepSrpObject srpObject, PcepLspObject lspObject, PcepStateReport.PcepMsgPath msgPath) {
-        this.srpObject = srpObject;
-        this.lspObject = lspObject;
-        this.msgPath = msgPath;
-    }
-
-    @Override
-    public PcepSrpObject getSrpObject() {
-        return srpObject;
-    }
-
-    @Override
-    public PcepLspObject getLspObject() {
-        return lspObject;
-    }
-
-    @Override
-    public PcepStateReport.PcepMsgPath getMsgPath() {
-        return msgPath;
-    }
-
-    @Override
-    public void setSrpObject(PcepSrpObject srpObj) {
-        this.srpObject = srpObj;
-    }
-
-    @Override
-    public void setLspObject(PcepLspObject lspObject) {
-        this.lspObject = lspObject;
-    }
-
-    @Override
-    public void setMsgPath(PcepStateReport.PcepMsgPath msgPath) {
-        this.msgPath = msgPath;
-    }
-
-    /**
-     * Builder class for PCEP state report.
-     */
-    public static class Builder implements PcepStateReport.Builder {
-
-        private boolean bIsSRPObjectSet = false;
-        private boolean bIsLSPObjectSet = false;
-        private boolean bIsPcepMsgPathSet = false;
-
-        //PCEP SRP Object
-        private PcepSrpObject srpObject;
-        //PCEP LSP Object
-        private PcepLspObject lspObject;
-        //PCEP Attribute list
-        private PcepStateReport.PcepMsgPath msgPath;
-
-        @Override
-        public PcepStateReport build() throws PcepParseException {
-
-            //PCEP SRP Object
-            PcepSrpObject srpObject = null;
-            //PCEP LSP Object
-            PcepLspObject lspObject = null;
-            //PCEP Attribute list
-            PcepStateReport.PcepMsgPath msgPath = null;
-
-            if (this.bIsSRPObjectSet) {
-                srpObject = this.srpObject;
-            }
-
-            if (!this.bIsLSPObjectSet) {
-                throw new PcepParseException(" LSP Object NOT Set while building PcepStateReport.");
-            } else {
-                lspObject = this.lspObject;
-            }
-            if (!this.bIsPcepMsgPathSet) {
-                throw new PcepParseException(" Message Path NOT Set while building PcepStateReport.");
-            } else {
-                msgPath = this.msgPath;
-            }
-
-            return new PcepStateReportVer1(srpObject, lspObject, msgPath);
-        }
-
-        @Override
-        public PcepSrpObject getSrpObject() {
-            return this.srpObject;
-        }
-
-        @Override
-        public PcepLspObject getLspObject() {
-            return this.lspObject;
-        }
-
-        @Override
-        public PcepStateReport.PcepMsgPath getMsgPath() {
-            return this.msgPath;
-        }
-
-        @Override
-        public Builder setSrpObject(PcepSrpObject srpobj) {
-            this.srpObject = srpobj;
-            this.bIsSRPObjectSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setLspObject(PcepLspObject lspObject) {
-            this.lspObject = lspObject;
-            this.bIsLSPObjectSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setMsgPath(PcepStateReport.PcepMsgPath msgPath) {
-            this.msgPath = msgPath;
-            this.bIsPcepMsgPathSet = true;
-            return this;
-        }
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        if (this.srpObject instanceof PcepSrpObject) {
-            toStrHelper.add("SrpObject", srpObject);
-        }
-        if (this.lspObject instanceof PcepLspObject) {
-            toStrHelper.add("LspObject", lspObject);
-        }
-        if (this.msgPath instanceof PcepStateReport.PcepMsgPath) {
-            toStrHelper.add("MsgPath", msgPath);
-        }
-        return toStrHelper.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 org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepAttribute;
+import org.onosproject.pcepio.protocol.PcepBandwidthObject;
+import org.onosproject.pcepio.protocol.PcepEroObject;
+import org.onosproject.pcepio.protocol.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepRroObject;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.protocol.PcepStateReport;
+import org.onosproject.pcepio.types.PcepObjectHeader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provide the State Report for the Pcep Report Message.
+ * Reference :PCE extensions for stateful draft-ietf-pce-stateful-pce-10.
+ */
+public class PcepStateReportVer1 implements PcepStateReport {
+    /*
+     * <state-report>     ::= [<SRP>]
+                               <LSP>
+                               <path>
+       Where:
+               <path>     ::= <ERO><attribute-list>[<RRO>]
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepStateReport.class);
+
+    public static final int OBJECT_HEADER_LENGTH = 4;
+
+    /**
+     * Provides PCEP Message path for report message.
+     */
+    public class PcepMsgPath implements PcepStateReport.PcepMsgPath {
+
+        /*
+         * <path>                  ::= <ERO><attribute-list>[<RRO>]
+         */
+
+        //PcepEroObject
+        private PcepEroObject eroObj;
+        private boolean isEroObjectSet;
+        //PcepAttribute List
+        private PcepAttribute attrList;
+        private boolean isAttributeListSet;
+        //PcepRroObject
+        private PcepRroObject rroObj;
+        private boolean isRroObjectSet;
+        private PcepBandwidthObject bandwidth;
+        private boolean isBandwidthObjectSet;
+
+        /**
+         * Constructor to reset the parameters.
+         */
+        public PcepMsgPath() {
+            eroObj = null;
+            attrList = null;
+            rroObj = null;
+            this.isEroObjectSet = false;
+            this.isAttributeListSet = false;
+            this.isRroObjectSet = false;
+            this.isBandwidthObjectSet = false;
+        }
+
+        /**
+         * Constructor to initialize the parameters from PCEP Message path.
+         *
+         * @param eroObj PCEP ERO Object
+         * @param attrList PCEP Attribute
+         * @param rroObj PCEP Rro Object
+         * @param bandwidth PCEP bandwidth object
+         */
+        public PcepMsgPath(PcepEroObject eroObj, PcepAttribute attrList, PcepRroObject rroObj,
+                           PcepBandwidthObject bandwidth) {
+
+            this.eroObj = eroObj;
+            this.attrList = attrList;
+            this.rroObj = rroObj;
+            this.bandwidth = bandwidth;
+            if (null == rroObj) {
+                this.isRroObjectSet = false;
+            } else {
+                this.isRroObjectSet = true;
+            }
+            if (null == eroObj) {
+                this.isEroObjectSet = false;
+            } else {
+                this.isEroObjectSet = true;
+            }
+            if (null == attrList) {
+                this.isAttributeListSet = false;
+            } else {
+                this.isAttributeListSet = true;
+            }
+            if (null == bandwidth) {
+                this.isBandwidthObjectSet = false;
+            } else {
+                this.isBandwidthObjectSet = true;
+            }
+        }
+
+        /**
+         * Returns PcepEroObject.
+         *
+         * @return eroObj PCEP ERO Object
+         */
+        @Override
+        public PcepEroObject getEroObject() {
+            return this.eroObj;
+        }
+
+        /**
+         * Returns PCEP Attribute.
+         *
+         * @return attrList Attribute list
+         */
+        @Override
+        public PcepAttribute getPcepAttribute() {
+            return this.attrList;
+        }
+
+        /**
+         * Returns PcepRroObject.
+         *
+         * @return rroObj PCEP RRO Object
+         */
+        @Override
+        public PcepRroObject getRroObject() {
+            return this.rroObj;
+        }
+
+        @Override
+        public PcepBandwidthObject getBandwidthObject() {
+            return this.bandwidth;
+        }
+
+        @Override
+        public void setEroObject(PcepEroObject eroObj) {
+            this.eroObj = eroObj;
+        }
+
+        @Override
+        public void setPcepAttribute(PcepAttribute attrList) {
+            this.attrList = attrList;
+        }
+
+        @Override
+        public void setRroObject(PcepRroObject rroObj) {
+            this.rroObj = rroObj;
+        }
+
+        @Override
+        public void setBandwidthObject(PcepBandwidthObject bandwidth) {
+            this.bandwidth = bandwidth;
+        }
+
+        /**
+         * Reads all the Objects for PCEP Message Path.
+         *
+         * @param bb of type channel buffer
+         * @return PCEP Message path
+         * @throws PcepParseException when fails to read pcep message path
+         */
+        @Override
+        public PcepMsgPath read(ChannelBuffer bb) throws PcepParseException {
+
+            PcepEroObject eroObj;
+            PcepAttribute attrList;
+            PcepRroObject rroObj = null;
+            PcepBandwidthObject bandwidth = null;
+
+            eroObj = PcepEroObjectVer1.read(bb);
+            attrList = PcepAttributeVer1.read(bb);
+
+            boolean bBreakWhile = false;
+            while (0 < bb.readableBytes()) {
+
+                if (bb.readableBytes() < OBJECT_HEADER_LENGTH) {
+                    break;
+                }
+                bb.markReaderIndex();
+                PcepObjectHeader tempObjHeader = PcepObjectHeader.read(bb);
+                bb.resetReaderIndex();
+                byte yObjClass = tempObjHeader.getObjClass();
+
+                switch (yObjClass) {
+                case PcepRroObjectVer1.RRO_OBJ_CLASS:
+                    rroObj = PcepRroObjectVer1.read(bb);
+                    break;
+                case PcepInterLayerObjectVer1.INTER_LAYER_OBJ_CLASS:
+                    bb.skipBytes(tempObjHeader.getObjLen());
+                    break;
+                case PcepBandwidthObjectVer1.BANDWIDTH_OBJ_CLASS:
+                    bandwidth = PcepBandwidthObjectVer1.read(bb);
+                    break;
+                default:
+                    //Otherthan above objects handle those objects in caller.
+                    bBreakWhile = true;
+                    break;
+                }
+                if (bBreakWhile) {
+                    break;
+                }
+            }
+            return new PcepMsgPath(eroObj, attrList, rroObj, bandwidth);
+        }
+
+        /**
+         * Writes all the objects for PCEP message path.
+         *
+         * @param bb of type channel buffer.
+         * @return object length index
+         * @throws PcepParseException when fails to write to channel buffer
+         */
+        @Override
+        public int write(ChannelBuffer bb) throws PcepParseException {
+            int iLenStartIndex = bb.writerIndex();
+
+            //write Object header
+            if (this.isEroObjectSet) {
+                this.eroObj.write(bb);
+            } else {
+                throw new PcepParseException("Ero object is not set in path");
+            }
+
+            if (this.isAttributeListSet) {
+                this.attrList.write(bb);
+            }
+
+            // RRO is optional check and read
+            if (this.isRroObjectSet) {
+                this.rroObj.write(bb);
+                // bandwidth should come along with RRO.
+                if (this.isBandwidthObjectSet) {
+                    this.bandwidth.write(bb);
+                }
+            }
+            return bb.writerIndex() - iLenStartIndex;
+        }
+
+        @Override
+        public String toString() {
+            ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+            if (attrList instanceof PcepAttribute) {
+                toStrHelper.add("AttributeList", attrList);
+            }
+            if (rroObj instanceof PcepRroObjectVer1) {
+                toStrHelper.add("RroObject", rroObj);
+            }
+            if (bandwidth instanceof PcepBandwidthObjectVer1) {
+                toStrHelper.add("bandwidthObject", bandwidth);
+            }
+            return toStrHelper.toString();
+        }
+    }
+
+    //SRP Object
+    private PcepSrpObject srpObject;
+    //LSP Object
+    private PcepLspObject lspObject;
+    //PcepMsgPath
+    private PcepStateReport.PcepMsgPath msgPath;
+
+    /**
+     * Constructor to reset objects.
+     */
+    public PcepStateReportVer1() {
+        this.srpObject = null;
+        this.lspObject = null;
+        this.msgPath = null;
+    }
+
+    public PcepStateReportVer1(PcepSrpObject srpObject, PcepLspObject lspObject, PcepStateReport.PcepMsgPath msgPath) {
+        this.srpObject = srpObject;
+        this.lspObject = lspObject;
+        this.msgPath = msgPath;
+    }
+
+    @Override
+    public PcepSrpObject getSrpObject() {
+        return srpObject;
+    }
+
+    @Override
+    public PcepLspObject getLspObject() {
+        return lspObject;
+    }
+
+    @Override
+    public PcepStateReport.PcepMsgPath getMsgPath() {
+        return msgPath;
+    }
+
+    @Override
+    public void setSrpObject(PcepSrpObject srpObj) {
+        this.srpObject = srpObj;
+    }
+
+    @Override
+    public void setLspObject(PcepLspObject lspObject) {
+        this.lspObject = lspObject;
+    }
+
+    @Override
+    public void setMsgPath(PcepStateReport.PcepMsgPath msgPath) {
+        this.msgPath = msgPath;
+    }
+
+    /**
+     * Builder class for PCEP state report.
+     */
+    public static class Builder implements PcepStateReport.Builder {
+
+        private boolean bIsSRPObjectSet = false;
+        private boolean bIsLSPObjectSet = false;
+        private boolean bIsPcepMsgPathSet = false;
+
+        //PCEP SRP Object
+        private PcepSrpObject srpObject;
+        //PCEP LSP Object
+        private PcepLspObject lspObject;
+        //PCEP Attribute list
+        private PcepStateReport.PcepMsgPath msgPath;
+
+        @Override
+        public PcepStateReport build() throws PcepParseException {
+
+            //PCEP SRP Object
+            PcepSrpObject srpObject = null;
+            //PCEP LSP Object
+            PcepLspObject lspObject = null;
+            //PCEP Attribute list
+            PcepStateReport.PcepMsgPath msgPath = null;
+
+            if (this.bIsSRPObjectSet) {
+                srpObject = this.srpObject;
+            }
+
+            if (!this.bIsLSPObjectSet) {
+                throw new PcepParseException(" LSP Object NOT Set while building PcepStateReport.");
+            } else {
+                lspObject = this.lspObject;
+            }
+            if (!this.bIsPcepMsgPathSet) {
+                throw new PcepParseException(" Message Path NOT Set while building PcepStateReport.");
+            } else {
+                msgPath = this.msgPath;
+            }
+
+            return new PcepStateReportVer1(srpObject, lspObject, msgPath);
+        }
+
+        @Override
+        public PcepSrpObject getSrpObject() {
+            return this.srpObject;
+        }
+
+        @Override
+        public PcepLspObject getLspObject() {
+            return this.lspObject;
+        }
+
+        @Override
+        public PcepStateReport.PcepMsgPath getMsgPath() {
+            return this.msgPath;
+        }
+
+        @Override
+        public Builder setSrpObject(PcepSrpObject srpobj) {
+            this.srpObject = srpobj;
+            this.bIsSRPObjectSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setLspObject(PcepLspObject lspObject) {
+            this.lspObject = lspObject;
+            this.bIsLSPObjectSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setMsgPath(PcepStateReport.PcepMsgPath msgPath) {
+            this.msgPath = msgPath;
+            this.bIsPcepMsgPathSet = true;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        if (this.srpObject instanceof PcepSrpObject) {
+            toStrHelper.add("SrpObject", srpObject);
+        }
+        if (this.lspObject instanceof PcepLspObject) {
+            toStrHelper.add("LspObject", lspObject);
+        }
+        if (this.msgPath instanceof PcepStateReport.PcepMsgPath) {
+            toStrHelper.add("MsgPath", msgPath);
+        }
+        return toStrHelper.toString();
+    }
 }
\ No newline at end of file
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepUpdateRequestVer1.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepUpdateRequestVer1.java
index b0afabd..10b1b87 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepUpdateRequestVer1.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/protocol/ver1/PcepUpdateRequestVer1.java
@@ -1,196 +1,196 @@
-/*
- * 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 org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepLspObject;
-import org.onosproject.pcepio.protocol.PcepMsgPath;
-import org.onosproject.pcepio.protocol.PcepSrpObject;
-import org.onosproject.pcepio.protocol.PcepUpdateRequest;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PCEP Update Request List.
- */
-public class PcepUpdateRequestVer1 implements PcepUpdateRequest {
-
-    /*                     <update-request-list>
-     * Where:
-     *   <update-request-list>     ::= <update-request>[<update-request-list>]
-     *   <update-request>          ::= <SRP>
-     *                                 <LSP>
-     *                                 <path>
-     * Where:
-     *   <path>                     ::= <ERO><attribute-list>
-     * Where:
-     * <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PcepUpdateRequestVer1.class);
-
-    //PCEP SRP Object
-    private PcepSrpObject srpObject;
-    //PCEP LSP Object
-    private PcepLspObject lspObject;
-    //PCEP Message path
-    private PcepMsgPath msgPath;
-
-    /**
-     * Default constructor.
-     */
-    public PcepUpdateRequestVer1() {
-        srpObject = null;
-        lspObject = null;
-        msgPath = null;
-    }
-
-    /**
-     * Constructor to initialize all member variables.
-     *
-     * @param srpObject srp object
-     * @param lspObject lsp object
-     * @param msgPath message path object
-     */
-    public PcepUpdateRequestVer1(PcepSrpObject srpObject, PcepLspObject lspObject, PcepMsgPath msgPath) {
-        this.srpObject = srpObject;
-        this.lspObject = lspObject;
-        this.msgPath = msgPath;
-    }
-
-    @Override
-    public PcepSrpObject getSrpObject() {
-        return srpObject;
-    }
-
-    @Override
-    public PcepLspObject getLspObject() {
-        return lspObject;
-    }
-
-    @Override
-    public PcepMsgPath getMsgPath() {
-        return msgPath;
-    }
-
-    @Override
-    public void setSrpObject(PcepSrpObject srpObject) {
-        this.srpObject = srpObject;
-
-    }
-
-    @Override
-    public void setLspObject(PcepLspObject lspObject) {
-        this.lspObject = lspObject;
-    }
-
-    @Override
-    public void setMsgPath(PcepMsgPath msgPath) {
-        this.msgPath = msgPath;
-    }
-
-    /**
-     * Builder class for PCEP update request.
-     */
-    public static class Builder implements PcepUpdateRequest.Builder {
-
-        private boolean bIsSRPObjectSet = false;
-        private boolean bIsLSPObjectSet = false;
-        private boolean bIsPcepMsgPathSet = false;
-
-        //PCEP SRP Object
-        private PcepSrpObject srpObject;
-        //PCEP LSP Object
-        private PcepLspObject lspObject;
-        //PCEP Attribute list
-        private PcepMsgPath msgPath;
-
-        @Override
-        public PcepUpdateRequest build() throws PcepParseException {
-
-            //PCEP SRP Object
-            PcepSrpObject srpObject = null;
-            //PCEP LSP Object
-            PcepLspObject lspObject = null;
-            //PCEP Attribute list
-            PcepMsgPath msgPath = null;
-
-            if (!this.bIsSRPObjectSet) {
-                throw new PcepParseException(" SRP Object NOT Set while building PcepUpdateRequest.");
-            } else {
-                srpObject = this.srpObject;
-            }
-            if (!this.bIsLSPObjectSet) {
-                throw new PcepParseException(" LSP Object NOT Set while building PcepUpdateRequest.");
-            } else {
-                lspObject = this.lspObject;
-            }
-            if (!this.bIsPcepMsgPathSet) {
-                throw new PcepParseException(" Msg Path NOT Set while building PcepUpdateRequest.");
-            } else {
-                msgPath = this.msgPath;
-            }
-
-            return new PcepUpdateRequestVer1(srpObject, lspObject, msgPath);
-        }
-
-        @Override
-        public PcepSrpObject getSrpObject() {
-            return this.srpObject;
-        }
-
-        @Override
-        public PcepLspObject getLspObject() {
-            return this.lspObject;
-        }
-
-        @Override
-        public PcepMsgPath getMsgPath() {
-            return this.msgPath;
-        }
-
-        @Override
-        public Builder setSrpObject(PcepSrpObject srpobj) {
-            this.srpObject = srpobj;
-            this.bIsSRPObjectSet = true;
-            return this;
-
-        }
-
-        @Override
-        public Builder setLspObject(PcepLspObject lspObject) {
-            this.lspObject = lspObject;
-            this.bIsLSPObjectSet = true;
-            return this;
-        }
-
-        @Override
-        public Builder setMsgPath(PcepMsgPath msgPath) {
-            this.msgPath = msgPath;
-            this.bIsPcepMsgPathSet = true;
-            return this;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("SrpObject", srpObject).add("LspObject", lspObject)
-                .add("MsgPath", msgPath).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 org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepLspObject;
+import org.onosproject.pcepio.protocol.PcepMsgPath;
+import org.onosproject.pcepio.protocol.PcepSrpObject;
+import org.onosproject.pcepio.protocol.PcepUpdateRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PCEP Update Request List.
+ */
+public class PcepUpdateRequestVer1 implements PcepUpdateRequest {
+
+    /*                     <update-request-list>
+     * Where:
+     *   <update-request-list>     ::= <update-request>[<update-request-list>]
+     *   <update-request>          ::= <SRP>
+     *                                 <LSP>
+     *                                 <path>
+     * Where:
+     *   <path>                     ::= <ERO><attribute-list>
+     * Where:
+     * <attribute-list> is defined in [RFC5440] and extended by PCEP extensions.
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PcepUpdateRequestVer1.class);
+
+    //PCEP SRP Object
+    private PcepSrpObject srpObject;
+    //PCEP LSP Object
+    private PcepLspObject lspObject;
+    //PCEP Message path
+    private PcepMsgPath msgPath;
+
+    /**
+     * Default constructor.
+     */
+    public PcepUpdateRequestVer1() {
+        srpObject = null;
+        lspObject = null;
+        msgPath = null;
+    }
+
+    /**
+     * Constructor to initialize all member variables.
+     *
+     * @param srpObject srp object
+     * @param lspObject lsp object
+     * @param msgPath message path object
+     */
+    public PcepUpdateRequestVer1(PcepSrpObject srpObject, PcepLspObject lspObject, PcepMsgPath msgPath) {
+        this.srpObject = srpObject;
+        this.lspObject = lspObject;
+        this.msgPath = msgPath;
+    }
+
+    @Override
+    public PcepSrpObject getSrpObject() {
+        return srpObject;
+    }
+
+    @Override
+    public PcepLspObject getLspObject() {
+        return lspObject;
+    }
+
+    @Override
+    public PcepMsgPath getMsgPath() {
+        return msgPath;
+    }
+
+    @Override
+    public void setSrpObject(PcepSrpObject srpObject) {
+        this.srpObject = srpObject;
+
+    }
+
+    @Override
+    public void setLspObject(PcepLspObject lspObject) {
+        this.lspObject = lspObject;
+    }
+
+    @Override
+    public void setMsgPath(PcepMsgPath msgPath) {
+        this.msgPath = msgPath;
+    }
+
+    /**
+     * Builder class for PCEP update request.
+     */
+    public static class Builder implements PcepUpdateRequest.Builder {
+
+        private boolean bIsSRPObjectSet = false;
+        private boolean bIsLSPObjectSet = false;
+        private boolean bIsPcepMsgPathSet = false;
+
+        //PCEP SRP Object
+        private PcepSrpObject srpObject;
+        //PCEP LSP Object
+        private PcepLspObject lspObject;
+        //PCEP Attribute list
+        private PcepMsgPath msgPath;
+
+        @Override
+        public PcepUpdateRequest build() throws PcepParseException {
+
+            //PCEP SRP Object
+            PcepSrpObject srpObject = null;
+            //PCEP LSP Object
+            PcepLspObject lspObject = null;
+            //PCEP Attribute list
+            PcepMsgPath msgPath = null;
+
+            if (!this.bIsSRPObjectSet) {
+                throw new PcepParseException(" SRP Object NOT Set while building PcepUpdateRequest.");
+            } else {
+                srpObject = this.srpObject;
+            }
+            if (!this.bIsLSPObjectSet) {
+                throw new PcepParseException(" LSP Object NOT Set while building PcepUpdateRequest.");
+            } else {
+                lspObject = this.lspObject;
+            }
+            if (!this.bIsPcepMsgPathSet) {
+                throw new PcepParseException(" Msg Path NOT Set while building PcepUpdateRequest.");
+            } else {
+                msgPath = this.msgPath;
+            }
+
+            return new PcepUpdateRequestVer1(srpObject, lspObject, msgPath);
+        }
+
+        @Override
+        public PcepSrpObject getSrpObject() {
+            return this.srpObject;
+        }
+
+        @Override
+        public PcepLspObject getLspObject() {
+            return this.lspObject;
+        }
+
+        @Override
+        public PcepMsgPath getMsgPath() {
+            return this.msgPath;
+        }
+
+        @Override
+        public Builder setSrpObject(PcepSrpObject srpobj) {
+            this.srpObject = srpobj;
+            this.bIsSRPObjectSet = true;
+            return this;
+
+        }
+
+        @Override
+        public Builder setLspObject(PcepLspObject lspObject) {
+            this.lspObject = lspObject;
+            this.bIsLSPObjectSet = true;
+            return this;
+        }
+
+        @Override
+        public Builder setMsgPath(PcepMsgPath msgPath) {
+            this.msgPath = msgPath;
+            this.bIsPcepMsgPathSet = true;
+            return this;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("SrpObject", srpObject).add("LspObject", lspObject)
+                .add("MsgPath", msgPath).toString();
+    }
 }
\ No newline at end of file
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AdministrativeGroupTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AdministrativeGroupTlv.java
index cf4396d..99ea8dd 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AdministrativeGroupTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AdministrativeGroupTlv.java
@@ -1,133 +1,133 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Administrative Group Tlv which contains value (32 Bit ).
- */
-public class AdministrativeGroupTlv implements PcepValueType {
-
-    /* REFERENCE :[RFC5305]/3.1
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TDB33]         |             Length=4         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                     value (32 Bit )                           |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(AdministrativeGroupTlv.class);
-
-    public static final short TYPE = 3; //TDB33
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue of Administrative-Group-Tlv.
-     */
-    public AdministrativeGroupTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created AdministrativeGroupTlv object.
-     *
-     * @param raw value.
-     * @return object of Administrative-Group-Tlv
-     */
-    public static AdministrativeGroupTlv of(final int raw) {
-        return new AdministrativeGroupTlv(raw);
-    }
-
-    /**
-     * Returns raw value.
-     *
-     * @return rawValue raw value
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof AdministrativeGroupTlv) {
-            AdministrativeGroupTlv other = (AdministrativeGroupTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of Administrative-Group-Tlv.
-     *
-     * @param c input channel buffer
-     * @return object of Administrative-Group-Tlv
-     */
-    public static AdministrativeGroupTlv read(ChannelBuffer c) {
-        return AdministrativeGroupTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Administrative Group Tlv which contains value (32 Bit ).
+ */
+public class AdministrativeGroupTlv implements PcepValueType {
+
+    /* REFERENCE :[RFC5305]/3.1
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TDB33]         |             Length=4         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                     value (32 Bit )                           |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(AdministrativeGroupTlv.class);
+
+    public static final short TYPE = 3; //TDB33
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue of Administrative-Group-Tlv.
+     */
+    public AdministrativeGroupTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created AdministrativeGroupTlv object.
+     *
+     * @param raw value.
+     * @return object of Administrative-Group-Tlv
+     */
+    public static AdministrativeGroupTlv of(final int raw) {
+        return new AdministrativeGroupTlv(raw);
+    }
+
+    /**
+     * Returns raw value.
+     *
+     * @return rawValue raw value
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof AdministrativeGroupTlv) {
+            AdministrativeGroupTlv other = (AdministrativeGroupTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of Administrative-Group-Tlv.
+     *
+     * @param c input channel buffer
+     * @return object of Administrative-Group-Tlv
+     */
+    public static AdministrativeGroupTlv read(ChannelBuffer c) {
+        return AdministrativeGroupTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AutonomousSystemTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AutonomousSystemTlv.java
index bfe6f44..3f21319 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AutonomousSystemTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/AutonomousSystemTlv.java
@@ -1,136 +1,136 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Autonomous-System-Tlv which contains opaque value (32 Bit AS Number).
- */
-public class AutonomousSystemTlv implements PcepValueType {
-
-    /* Reference :RFC3209
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD10]         |             Length=4         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                    opaque value (32 Bit AS Number)            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(AutonomousSystemTlv.class);
-
-    public static final short TYPE = 100; //TODD:change this TBD10
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue Autonomous-System-Tlv
-     */
-    public AutonomousSystemTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created AutonomousSystemTlv object.
-     *
-     * @param raw value of opaque.
-     * @return object of Autonomous-System-Tlv
-     */
-    public static AutonomousSystemTlv of(final int raw) {
-        return new AutonomousSystemTlv(raw);
-    }
-
-    /**
-     * Returns opaque value.
-     *
-     * @return rawValue opaque value.
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof AutonomousSystemTlv) {
-            AutonomousSystemTlv other = (AutonomousSystemTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of AutonomousSystemTlv.
-     *
-     * @param c input channel buffer
-     * @return object of Autonomous-System-Tlv
-     */
-    public static AutonomousSystemTlv read(ChannelBuffer c) {
-        return AutonomousSystemTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("TYPE", TYPE)
-                .add("Length", LENGTH)
-                .add("value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Autonomous-System-Tlv which contains opaque value (32 Bit AS Number).
+ */
+public class AutonomousSystemTlv implements PcepValueType {
+
+    /* Reference :RFC3209
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD10]         |             Length=4         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                    opaque value (32 Bit AS Number)            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(AutonomousSystemTlv.class);
+
+    public static final short TYPE = 100; //TODD:change this TBD10
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue Autonomous-System-Tlv
+     */
+    public AutonomousSystemTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created AutonomousSystemTlv object.
+     *
+     * @param raw value of opaque.
+     * @return object of Autonomous-System-Tlv
+     */
+    public static AutonomousSystemTlv of(final int raw) {
+        return new AutonomousSystemTlv(raw);
+    }
+
+    /**
+     * Returns opaque value.
+     *
+     * @return rawValue opaque value.
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof AutonomousSystemTlv) {
+            AutonomousSystemTlv other = (AutonomousSystemTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of AutonomousSystemTlv.
+     *
+     * @param c input channel buffer
+     * @return object of Autonomous-System-Tlv
+     */
+    public static AutonomousSystemTlv read(ChannelBuffer c) {
+        return AutonomousSystemTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("TYPE", TYPE)
+                .add("Length", LENGTH)
+                .add("value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/BGPLSidentifierTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/BGPLSidentifierTlv.java
index 0c20b21..cef4418 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/BGPLSidentifierTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/BGPLSidentifierTlv.java
@@ -1,133 +1,133 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides BGP LS identifier which contains opaque value (32 Bit ID).
- */
-public class BGPLSidentifierTlv implements PcepValueType {
-
-    /* Reference :draft-ietf-idr-ls-distribution-10
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD11]         |             Length=4         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                    opaque value (32 Bit ID).                  |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(BGPLSidentifierTlv.class);
-
-    public static final short TYPE = 17; //TODD:change this TBD11
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue BGP LS identifier Tlv
-     */
-    public BGPLSidentifierTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created BGPLSidentifierTlv object.
-     *
-     * @param raw value
-     * @return object of BGPLSidentifierTlv
-     */
-    public static BGPLSidentifierTlv of(final int raw) {
-        return new BGPLSidentifierTlv(raw);
-    }
-
-    /**
-     * Returns opaque value.
-     *
-     * @return rawValue opaque value
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof BGPLSidentifierTlv) {
-            BGPLSidentifierTlv other = (BGPLSidentifierTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of BGPLSidentifierTlv.
-     *
-     * @param c input channel buffer
-     * @return object of BGP LS identifier Tlv
-     */
-    public static BGPLSidentifierTlv read(ChannelBuffer c) {
-        return BGPLSidentifierTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides BGP LS identifier which contains opaque value (32 Bit ID).
+ */
+public class BGPLSidentifierTlv implements PcepValueType {
+
+    /* Reference :draft-ietf-idr-ls-distribution-10
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD11]         |             Length=4         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                    opaque value (32 Bit ID).                  |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(BGPLSidentifierTlv.class);
+
+    public static final short TYPE = 17; //TODD:change this TBD11
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue BGP LS identifier Tlv
+     */
+    public BGPLSidentifierTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created BGPLSidentifierTlv object.
+     *
+     * @param raw value
+     * @return object of BGPLSidentifierTlv
+     */
+    public static BGPLSidentifierTlv of(final int raw) {
+        return new BGPLSidentifierTlv(raw);
+    }
+
+    /**
+     * Returns opaque value.
+     *
+     * @return rawValue opaque value
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof BGPLSidentifierTlv) {
+            BGPLSidentifierTlv other = (BGPLSidentifierTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of BGPLSidentifierTlv.
+     *
+     * @param c input channel buffer
+     * @return object of BGP LS identifier Tlv
+     */
+    public static BGPLSidentifierTlv read(ChannelBuffer c) {
+        return BGPLSidentifierTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/GmplsCapabilityTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/GmplsCapabilityTlv.java
index 37bb053..eef2d45 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/GmplsCapabilityTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/GmplsCapabilityTlv.java
@@ -1,135 +1,135 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides GMPLS Capability Tlv.
- */
-public class GmplsCapabilityTlv implements PcepValueType {
-
-    /*
-     * GMPLS-CAPABILITY TLV format
-     * reference :draft-ietf-pce-gmpls-pcep-extensions -2.1.1
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |               Type=14       |             Length              |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                             Flags                             |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-    protected static final Logger log = LoggerFactory.getLogger(GmplsCapabilityTlv.class);
-
-    public static final short TYPE = 14;
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize raw value.
-     *
-     * @param rawValue of Gmpls-Capability-Tlv
-     */
-    public GmplsCapabilityTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created GmplsCapabilityTlv object.
-     *
-     * @param raw Flags value
-     * @return object of Gmpls-Capability-Tlv
-     */
-    public static GmplsCapabilityTlv of(final int raw) {
-        return new GmplsCapabilityTlv(raw);
-    }
-
-    /**
-     * Returns value of Flags.
-     *
-     * @return rawValue Flags
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof GmplsCapabilityTlv) {
-            GmplsCapabilityTlv other = (GmplsCapabilityTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of Gmpls-Capability-Tlv.
-     *
-     * @param c input channel buffer
-     * @return object of Gmpls-Capability-Tlv
-     */
-    public static GmplsCapabilityTlv read(ChannelBuffer c) {
-        return GmplsCapabilityTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides GMPLS Capability Tlv.
+ */
+public class GmplsCapabilityTlv implements PcepValueType {
+
+    /*
+     * GMPLS-CAPABILITY TLV format
+     * reference :draft-ietf-pce-gmpls-pcep-extensions -2.1.1
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |               Type=14       |             Length              |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                             Flags                             |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(GmplsCapabilityTlv.class);
+
+    public static final short TYPE = 14;
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize raw value.
+     *
+     * @param rawValue of Gmpls-Capability-Tlv
+     */
+    public GmplsCapabilityTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created GmplsCapabilityTlv object.
+     *
+     * @param raw Flags value
+     * @return object of Gmpls-Capability-Tlv
+     */
+    public static GmplsCapabilityTlv of(final int raw) {
+        return new GmplsCapabilityTlv(raw);
+    }
+
+    /**
+     * Returns value of Flags.
+     *
+     * @return rawValue Flags
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof GmplsCapabilityTlv) {
+            GmplsCapabilityTlv other = (GmplsCapabilityTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of Gmpls-Capability-Tlv.
+     *
+     * @param c input channel buffer
+     * @return object of Gmpls-Capability-Tlv
+     */
+    public static GmplsCapabilityTlv read(ChannelBuffer c) {
+        return GmplsCapabilityTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IGPMetricTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IGPMetricTlv.java
index 5381508..ab3f124 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IGPMetricTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IGPMetricTlv.java
@@ -1,150 +1,150 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides IGP Link Metric .
- */
-public class IGPMetricTlv implements PcepValueType {
-
-    /* Reference :[I-D.ietf-idr-ls-distribution] /3.3.2.4
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=TDB40             |             Length      |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //      IGP Link Metric (variable length)      //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(IGPMetricTlv.class);
-
-    public static final short TYPE = 1095; //TODO:NEED TO HANDLE TDB40
-    private short hLength;
-
-    private final byte[] rawValue;
-
-    /**
-     * Constructor to initialize raw value.
-     *
-     * @param rawValue IGP Link Metric
-     * @param hLength length
-     */
-    public IGPMetricTlv(byte[] rawValue, short hLength) {
-        this.rawValue = rawValue;
-        this.hLength = hLength;
-    }
-
-    /**
-     * Returns newly created IGPMetricTlv object.
-     *
-     * @param raw value of IGP Link Metric
-     * @param hLength length
-     * @return object of IGPMetricTlv
-     */
-    public static IGPMetricTlv of(final byte[] raw, short hLength) {
-        return new IGPMetricTlv(raw, hLength);
-    }
-
-    /**
-     * Returns value of IGP Link Metric.
-     *
-     * @return rawValue of IGP Link Metric
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IGPMetricTlv) {
-            IGPMetricTlv other = (IGPMetricTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IGPMetricTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of IGPMetricTlv
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) {
-        byte[] iIGPMetric = new byte[hLength];
-        c.readBytes(iIGPMetric, 0, hLength);
-        return new IGPMetricTlv(iIGPMetric, hLength);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", hLength);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides IGP Link Metric .
+ */
+public class IGPMetricTlv implements PcepValueType {
+
+    /* Reference :[I-D.ietf-idr-ls-distribution] /3.3.2.4
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=TDB40             |             Length      |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //      IGP Link Metric (variable length)      //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(IGPMetricTlv.class);
+
+    public static final short TYPE = 1095; //TODO:NEED TO HANDLE TDB40
+    private short hLength;
+
+    private final byte[] rawValue;
+
+    /**
+     * Constructor to initialize raw value.
+     *
+     * @param rawValue IGP Link Metric
+     * @param hLength length
+     */
+    public IGPMetricTlv(byte[] rawValue, short hLength) {
+        this.rawValue = rawValue;
+        this.hLength = hLength;
+    }
+
+    /**
+     * Returns newly created IGPMetricTlv object.
+     *
+     * @param raw value of IGP Link Metric
+     * @param hLength length
+     * @return object of IGPMetricTlv
+     */
+    public static IGPMetricTlv of(final byte[] raw, short hLength) {
+        return new IGPMetricTlv(raw, hLength);
+    }
+
+    /**
+     * Returns value of IGP Link Metric.
+     *
+     * @return rawValue of IGP Link Metric
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IGPMetricTlv) {
+            IGPMetricTlv other = (IGPMetricTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IGPMetricTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of IGPMetricTlv
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) {
+        byte[] iIGPMetric = new byte[hLength];
+        c.readBytes(iIGPMetric, 0, hLength);
+        return new IGPMetricTlv(iIGPMetric, hLength);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", hLength);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4InterfaceAddressTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4InterfaceAddressTlv.java
index 71bfac5..529eaeb 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4InterfaceAddressTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4InterfaceAddressTlv.java
@@ -1,134 +1,134 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides IPv4 Interface Address .
- */
-public class IPv4InterfaceAddressTlv implements PcepValueType {
-
-    /*
-     * reference :[RFC5305]/3.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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=6              |             Length=4          |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                IPv4 Interface Address                         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(IPv4InterfaceAddressTlv.class);
-
-    public static final short TYPE = 6;
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue of IPv4-Interface-Address.
-     */
-    public IPv4InterfaceAddressTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created IPv4InterfaceAddressTlv object.
-     *
-     * @param raw value of IPv4-Interface-Address
-     * @return object of IPv4-Interface-Address-Tlv
-     */
-    public static IPv4InterfaceAddressTlv of(final int raw) {
-        return new IPv4InterfaceAddressTlv(raw);
-    }
-
-    /**
-     * Returns value of IPv4 Interface Address.
-     *
-     * @return rawValue IPv4 Interface Address
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv4InterfaceAddressTlv) {
-            IPv4InterfaceAddressTlv other = (IPv4InterfaceAddressTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv4InterfaceAddressTlv.
-     *
-     * @param c input channel buffer
-     * @return object of IPv4-Interface-Address-Tlv
-     */
-    public static IPv4InterfaceAddressTlv read(ChannelBuffer c) {
-        return IPv4InterfaceAddressTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides IPv4 Interface Address .
+ */
+public class IPv4InterfaceAddressTlv implements PcepValueType {
+
+    /*
+     * reference :[RFC5305]/3.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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=6              |             Length=4          |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                IPv4 Interface Address                         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(IPv4InterfaceAddressTlv.class);
+
+    public static final short TYPE = 6;
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue of IPv4-Interface-Address.
+     */
+    public IPv4InterfaceAddressTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created IPv4InterfaceAddressTlv object.
+     *
+     * @param raw value of IPv4-Interface-Address
+     * @return object of IPv4-Interface-Address-Tlv
+     */
+    public static IPv4InterfaceAddressTlv of(final int raw) {
+        return new IPv4InterfaceAddressTlv(raw);
+    }
+
+    /**
+     * Returns value of IPv4 Interface Address.
+     *
+     * @return rawValue IPv4 Interface Address
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv4InterfaceAddressTlv) {
+            IPv4InterfaceAddressTlv other = (IPv4InterfaceAddressTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv4InterfaceAddressTlv.
+     *
+     * @param c input channel buffer
+     * @return object of IPv4-Interface-Address-Tlv
+     */
+    public static IPv4InterfaceAddressTlv read(ChannelBuffer c) {
+        return IPv4InterfaceAddressTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
 }
\ No newline at end of file
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4NeighborAddressTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4NeighborAddressTlv.java
index 9f78b2c..04a25b6 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4NeighborAddressTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4NeighborAddressTlv.java
@@ -1,134 +1,134 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides IPv4 Neighbor Address .
- */
-public class IPv4NeighborAddressTlv implements PcepValueType {
-
-    /* Reference :[RFC5305]/3.3
-      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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=8              |             Length=4          |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                   IPv4 Neighbor Address                       |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(IPv4NeighborAddressTlv.class);
-
-    public static final short TYPE = 8;
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue IPv4-Neighbor-Address-Tlv
-     */
-    public IPv4NeighborAddressTlv(int rawValue) {
-        log.debug("IPv4NeighborAddressTlv");
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created IPv4NeighborAddressTlv object.
-     *
-     * @param raw value of IPv4-Neighbor-Address
-     * @return object of IPv4NeighborAddressTlv
-     */
-    public static IPv4NeighborAddressTlv of(final int raw) {
-        return new IPv4NeighborAddressTlv(raw);
-    }
-
-    /**
-     * Returns value of IPv4 Neighbor Address.
-     *
-     * @return rawValue IPv4 Neighbor Address
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv4NeighborAddressTlv) {
-            IPv4NeighborAddressTlv other = (IPv4NeighborAddressTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv4-Neighbor-Address-Tlv.
-     *
-     * @param c input channel buffer
-     * @return object of IPv4-Neighbor-Address-Tlv
-     */
-    public static IPv4NeighborAddressTlv read(ChannelBuffer c) {
-        return IPv4NeighborAddressTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides IPv4 Neighbor Address .
+ */
+public class IPv4NeighborAddressTlv implements PcepValueType {
+
+    /* Reference :[RFC5305]/3.3
+      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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=8              |             Length=4          |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                   IPv4 Neighbor Address                       |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(IPv4NeighborAddressTlv.class);
+
+    public static final short TYPE = 8;
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue IPv4-Neighbor-Address-Tlv
+     */
+    public IPv4NeighborAddressTlv(int rawValue) {
+        log.debug("IPv4NeighborAddressTlv");
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created IPv4NeighborAddressTlv object.
+     *
+     * @param raw value of IPv4-Neighbor-Address
+     * @return object of IPv4NeighborAddressTlv
+     */
+    public static IPv4NeighborAddressTlv of(final int raw) {
+        return new IPv4NeighborAddressTlv(raw);
+    }
+
+    /**
+     * Returns value of IPv4 Neighbor Address.
+     *
+     * @return rawValue IPv4 Neighbor Address
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv4NeighborAddressTlv) {
+            IPv4NeighborAddressTlv other = (IPv4NeighborAddressTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv4-Neighbor-Address-Tlv.
+     *
+     * @param c input channel buffer
+     * @return object of IPv4-Neighbor-Address-Tlv
+     */
+    public static IPv4NeighborAddressTlv read(ChannelBuffer c) {
+        return IPv4NeighborAddressTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
 }
\ No newline at end of file
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4SubObject.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4SubObject.java
index b0576fe..031b5db 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4SubObject.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4SubObject.java
@@ -1,180 +1,180 @@
-/*
- * 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.
- */
-
-/**
- * @author b00295750
- *
- */
-package org.onosproject.pcepio.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides IPv4 Sub Object.
- */
-public class IPv4SubObject implements PcepValueType {
-
-    /*Reference : RFC 4874:3.1.1
-     *  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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |L|    Type     |     Length    | IPv4 address (4 bytes)        |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    | IPv4 address (continued)      | Prefix Length |      Resvd    |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-    protected static final Logger log = LoggerFactory.getLogger(IPv4SubObject.class);
-
-    public static final byte TYPE = 0x01;
-    public static final byte LENGTH = 8;
-    public static final byte VALUE_LENGTH = 6;
-    public static final byte OBJ_LENGTH = 8;
-    public static final byte LBIT = 0;
-    public static final int SHIFT_LBIT_POSITION = 7;
-    private int ipAddress;
-    private byte prefixLen;
-    private byte resvd;
-
-    /**
-     * Constructor to initialize ipv4 address.
-     *
-     * @param ipAddr ipv4 address
-     */
-    public IPv4SubObject(int ipAddr) {
-        this.ipAddress = ipAddr;
-    }
-
-    /**
-     * constructor to initialize ipAddress, prefixLen and resvd.
-     *
-     * @param ipAddress ipv4 address
-     * @param prefixLen prefix length
-     * @param resvd reserved flags value
-     */
-    public IPv4SubObject(int ipAddress, byte prefixLen, byte resvd) {
-        this.ipAddress = ipAddress;
-        this.prefixLen = prefixLen;
-        this.resvd = resvd;
-    }
-
-    /**
-     * Returns a new instance of IPv4SubObject.
-     *
-     * @param ipAddress ipv4 address
-     * @param prefixLen prefix length
-     * @param resvd reserved flags value
-     * @return object of IPv4SubObject
-     */
-    public static IPv4SubObject of(int ipAddress, byte prefixLen, byte resvd) {
-        return new IPv4SubObject(ipAddress, prefixLen, resvd);
-    }
-
-    /**
-     * Returns prefixLen of IPv4 IP address.
-     *
-     * @return byte  value of rawValue
-     */
-    public byte getPrefixLen() {
-        return prefixLen;
-    }
-
-    /**
-     * Returns value of IPv4 IP address.
-     *
-     * @return int value of ipv4 address
-     */
-    public int getIpAddress() {
-        return ipAddress;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(ipAddress, prefixLen, resvd);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv4SubObject) {
-            IPv4SubObject other = (IPv4SubObject) obj;
-            return Objects.equals(this.ipAddress, other.ipAddress) && Objects.equals(this.prefixLen, other.prefixLen)
-                    && Objects.equals(this.resvd, other.resvd);
-        }
-        return false;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv4SubObject.
-     *
-     * @param c type of channel buffer
-     * @return object of IPv4SubObject
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        int ipAddess = c.readInt();
-        byte prefixLen = c.readByte();
-        byte resvd = c.readByte();
-        return new IPv4SubObject(ipAddess, prefixLen, resvd);
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        byte bValue = LBIT;
-        bValue = (byte) (bValue << SHIFT_LBIT_POSITION);
-        bValue = (byte) (bValue | TYPE);
-        c.writeByte(bValue);
-        c.writeByte(OBJ_LENGTH);
-        c.writeInt(ipAddress);
-        c.writeByte(prefixLen);
-        c.writeByte(resvd);
-
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("Type", TYPE)
-                .add("Length", LENGTH)
-                .add("IPv4Address", ipAddress)
-                .add("PrefixLength", prefixLen)
-                .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.
+ */
+
+/**
+ * @author b00295750
+ *
+ */
+package org.onosproject.pcepio.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides IPv4 Sub Object.
+ */
+public class IPv4SubObject implements PcepValueType {
+
+    /*Reference : RFC 4874:3.1.1
+     *  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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |L|    Type     |     Length    | IPv4 address (4 bytes)        |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | IPv4 address (continued)      | Prefix Length |      Resvd    |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(IPv4SubObject.class);
+
+    public static final byte TYPE = 0x01;
+    public static final byte LENGTH = 8;
+    public static final byte VALUE_LENGTH = 6;
+    public static final byte OBJ_LENGTH = 8;
+    public static final byte LBIT = 0;
+    public static final int SHIFT_LBIT_POSITION = 7;
+    private int ipAddress;
+    private byte prefixLen;
+    private byte resvd;
+
+    /**
+     * Constructor to initialize ipv4 address.
+     *
+     * @param ipAddr ipv4 address
+     */
+    public IPv4SubObject(int ipAddr) {
+        this.ipAddress = ipAddr;
+    }
+
+    /**
+     * constructor to initialize ipAddress, prefixLen and resvd.
+     *
+     * @param ipAddress ipv4 address
+     * @param prefixLen prefix length
+     * @param resvd reserved flags value
+     */
+    public IPv4SubObject(int ipAddress, byte prefixLen, byte resvd) {
+        this.ipAddress = ipAddress;
+        this.prefixLen = prefixLen;
+        this.resvd = resvd;
+    }
+
+    /**
+     * Returns a new instance of IPv4SubObject.
+     *
+     * @param ipAddress ipv4 address
+     * @param prefixLen prefix length
+     * @param resvd reserved flags value
+     * @return object of IPv4SubObject
+     */
+    public static IPv4SubObject of(int ipAddress, byte prefixLen, byte resvd) {
+        return new IPv4SubObject(ipAddress, prefixLen, resvd);
+    }
+
+    /**
+     * Returns prefixLen of IPv4 IP address.
+     *
+     * @return byte  value of rawValue
+     */
+    public byte getPrefixLen() {
+        return prefixLen;
+    }
+
+    /**
+     * Returns value of IPv4 IP address.
+     *
+     * @return int value of ipv4 address
+     */
+    public int getIpAddress() {
+        return ipAddress;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipAddress, prefixLen, resvd);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv4SubObject) {
+            IPv4SubObject other = (IPv4SubObject) obj;
+            return Objects.equals(this.ipAddress, other.ipAddress) && Objects.equals(this.prefixLen, other.prefixLen)
+                    && Objects.equals(this.resvd, other.resvd);
+        }
+        return false;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv4SubObject.
+     *
+     * @param c type of channel buffer
+     * @return object of IPv4SubObject
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        int ipAddess = c.readInt();
+        byte prefixLen = c.readByte();
+        byte resvd = c.readByte();
+        return new IPv4SubObject(ipAddess, prefixLen, resvd);
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        byte bValue = LBIT;
+        bValue = (byte) (bValue << SHIFT_LBIT_POSITION);
+        bValue = (byte) (bValue | TYPE);
+        c.writeByte(bValue);
+        c.writeByte(OBJ_LENGTH);
+        c.writeInt(ipAddress);
+        c.writeByte(prefixLen);
+        c.writeByte(resvd);
+
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("Type", TYPE)
+                .add("Length", LENGTH)
+                .add("IPv4Address", ipAddress)
+                .add("PrefixLength", prefixLen)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfLocalNodeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfLocalNodeTlv.java
index 33b7f36..5086566 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfLocalNodeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfLocalNodeTlv.java
@@ -1,133 +1,133 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides IPv4 TE Router Id Of Local Node.
- */
-public class IPv4TERouterIdOfLocalNodeTlv implements PcepValueType {
-
-    /* Reference:[RFC5305]/4.3
-     * 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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TDB25]      |             Length=4         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |               IPv4 TE Router Id Of Local Node                |
-     +-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(IPv4TERouterIdOfLocalNodeTlv.class);
-
-    public static final short TYPE = 134; //TDB25
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue IPv4-TE-RouterId-Of-Local-Node-Tlv
-     */
-    public IPv4TERouterIdOfLocalNodeTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created IPv4TERouterIdOfLocalNodeTlv object.
-     *
-     * @param raw value of IPv4-TE-RouterId-Of-Local-Node
-     * @return object of IPv4TERouterIdOfLocalNodeTlv
-     */
-    public static IPv4TERouterIdOfLocalNodeTlv of(final int raw) {
-        return new IPv4TERouterIdOfLocalNodeTlv(raw);
-    }
-
-    /**
-     * Returns value of IPv4 TE Router Id Of Local Node.
-     *
-     * @return rawValue IPv4 TE Router Id Of Local Node
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv4TERouterIdOfLocalNodeTlv) {
-            IPv4TERouterIdOfLocalNodeTlv other = (IPv4TERouterIdOfLocalNodeTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv4TERouterIdOfLocalNodeTlv.
-     *
-     * @param c input channel buffer
-     * @return object of IPv4TERouterIdOfLocalNodeTlv
-     */
-    public static IPv4TERouterIdOfLocalNodeTlv read(ChannelBuffer c) {
-        return IPv4TERouterIdOfLocalNodeTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides IPv4 TE Router Id Of Local Node.
+ */
+public class IPv4TERouterIdOfLocalNodeTlv implements PcepValueType {
+
+    /* Reference:[RFC5305]/4.3
+     * 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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TDB25]      |             Length=4         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |               IPv4 TE Router Id Of Local Node                |
+     +-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(IPv4TERouterIdOfLocalNodeTlv.class);
+
+    public static final short TYPE = 134; //TDB25
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue IPv4-TE-RouterId-Of-Local-Node-Tlv
+     */
+    public IPv4TERouterIdOfLocalNodeTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created IPv4TERouterIdOfLocalNodeTlv object.
+     *
+     * @param raw value of IPv4-TE-RouterId-Of-Local-Node
+     * @return object of IPv4TERouterIdOfLocalNodeTlv
+     */
+    public static IPv4TERouterIdOfLocalNodeTlv of(final int raw) {
+        return new IPv4TERouterIdOfLocalNodeTlv(raw);
+    }
+
+    /**
+     * Returns value of IPv4 TE Router Id Of Local Node.
+     *
+     * @return rawValue IPv4 TE Router Id Of Local Node
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv4TERouterIdOfLocalNodeTlv) {
+            IPv4TERouterIdOfLocalNodeTlv other = (IPv4TERouterIdOfLocalNodeTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv4TERouterIdOfLocalNodeTlv.
+     *
+     * @param c input channel buffer
+     * @return object of IPv4TERouterIdOfLocalNodeTlv
+     */
+    public static IPv4TERouterIdOfLocalNodeTlv read(ChannelBuffer c) {
+        return IPv4TERouterIdOfLocalNodeTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfRemoteNodeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfRemoteNodeTlv.java
index 937d33a..6fdcd2c 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfRemoteNodeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv4TERouterIdOfRemoteNodeTlv.java
@@ -1,134 +1,134 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides IPv4 TE Router Id Of Remote Node.
- */
-public class IPv4TERouterIdOfRemoteNodeTlv implements PcepValueType {
-
-    /* Reference :[RFC5305]/4.3
-     * 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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TDB28]      |             Length=4         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |               IPv4 TE Router Id Of Remote Node                |
-     +-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(IPv4TERouterIdOfRemoteNodeTlv.class);
-
-    public static final short TYPE = 1340; //TDB28
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue IPv4 TE RouterId Of Remote Node Tlv
-     */
-    public IPv4TERouterIdOfRemoteNodeTlv(int rawValue) {
-        log.debug("IPv4TERouterIdOfRemoteNodeTlv");
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created IPv4TERouterIdOfRemoteNodeTlv object.
-     *
-     * @param raw IPv4 TE RouterId Of Remote Node
-     * @return object of IPv4TERouterIdOfRemoteNodeTlv
-     */
-    public static IPv4TERouterIdOfRemoteNodeTlv of(final int raw) {
-        return new IPv4TERouterIdOfRemoteNodeTlv(raw);
-    }
-
-    /**
-     * Returns value of IPv4 TE Router Id Of Remote Node.
-     *
-     * @return rawValue IPv4 TE Router Id Of Remote Node
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv4TERouterIdOfRemoteNodeTlv) {
-            IPv4TERouterIdOfRemoteNodeTlv other = (IPv4TERouterIdOfRemoteNodeTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv4TERouterIdOfRemoteNodeTlv.
-     *
-     * @param c input channel buffer
-     * @return object of IPv4TERouterIdOfRemoteNodeTlv
-     */
-    public static IPv4TERouterIdOfRemoteNodeTlv read(ChannelBuffer c) {
-        return IPv4TERouterIdOfRemoteNodeTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides IPv4 TE Router Id Of Remote Node.
+ */
+public class IPv4TERouterIdOfRemoteNodeTlv implements PcepValueType {
+
+    /* Reference :[RFC5305]/4.3
+     * 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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TDB28]      |             Length=4         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |               IPv4 TE Router Id Of Remote Node                |
+     +-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(IPv4TERouterIdOfRemoteNodeTlv.class);
+
+    public static final short TYPE = 1340; //TDB28
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue IPv4 TE RouterId Of Remote Node Tlv
+     */
+    public IPv4TERouterIdOfRemoteNodeTlv(int rawValue) {
+        log.debug("IPv4TERouterIdOfRemoteNodeTlv");
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created IPv4TERouterIdOfRemoteNodeTlv object.
+     *
+     * @param raw IPv4 TE RouterId Of Remote Node
+     * @return object of IPv4TERouterIdOfRemoteNodeTlv
+     */
+    public static IPv4TERouterIdOfRemoteNodeTlv of(final int raw) {
+        return new IPv4TERouterIdOfRemoteNodeTlv(raw);
+    }
+
+    /**
+     * Returns value of IPv4 TE Router Id Of Remote Node.
+     *
+     * @return rawValue IPv4 TE Router Id Of Remote Node
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv4TERouterIdOfRemoteNodeTlv) {
+            IPv4TERouterIdOfRemoteNodeTlv other = (IPv4TERouterIdOfRemoteNodeTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv4TERouterIdOfRemoteNodeTlv.
+     *
+     * @param c input channel buffer
+     * @return object of IPv4TERouterIdOfRemoteNodeTlv
+     */
+    public static IPv4TERouterIdOfRemoteNodeTlv read(ChannelBuffer c) {
+        return IPv4TERouterIdOfRemoteNodeTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6InterfaceAddressTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6InterfaceAddressTlv.java
index 725fb5d..2ebab1a 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6InterfaceAddressTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6InterfaceAddressTlv.java
@@ -1,181 +1,181 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides IPv6 Interface Address. REFERENCE :[RFC6119]/4.2.
- */
-public class IPv6InterfaceAddressTlv implements PcepValueType {
-
-    protected static final Logger log = LoggerFactory.getLogger(IPv6InterfaceAddressTlv.class);
-
-    public static final short TYPE = 12; //TDB18
-    public static final short LENGTH = 20;
-    public static final byte VALUE_LENGTH = 18;
-
-    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-    public static final IPv6InterfaceAddressTlv NONE = new IPv6InterfaceAddressTlv(NONE_VAL);
-
-    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
-    public static final IPv6InterfaceAddressTlv NO_MASK = new IPv6InterfaceAddressTlv(NO_MASK_VAL);
-    public static final IPv6InterfaceAddressTlv FULL_MASK = NONE;
-
-    private final byte[] rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue IPv6 Interface Address Tlv
-     */
-    public IPv6InterfaceAddressTlv(byte[] rawValue) {
-        log.debug("IPv6InterfaceAddressTlv");
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created IPv6InterfaceAddressTlv object.
-     *
-     * @param raw IPv6 Interface Address
-     * @return object of IPv6InterfaceAddressTlv
-     */
-    public static IPv6InterfaceAddressTlv of(final byte[] raw) {
-        //check NONE_VAL
-        boolean bFoundNONE = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (NONE_VAL[i] != raw[i]) {
-                bFoundNONE = false;
-            }
-        }
-
-        if (bFoundNONE) {
-            return NONE;
-        }
-
-        //check NO_MASK_VAL
-        boolean bFoundNoMask = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (0xFF != raw[i]) {
-                bFoundNoMask = false;
-            }
-        }
-        if (bFoundNoMask) {
-            return NO_MASK;
-        }
-
-        return new IPv6InterfaceAddressTlv(raw);
-    }
-
-    /**
-     * Returns value of IPv6 Interface Address.
-     *
-     * @return rawValue raw value
-     */
-    public byte[] getBytes() {
-        return rawValue;
-    }
-
-    /**
-     * Returns value of IPv6 Interface Address.
-     *
-     * @return rawValue raw value
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv6InterfaceAddressTlv) {
-            IPv6InterfaceAddressTlv other = (IPv6InterfaceAddressTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv6InterfaceAddressTlv.
-     *
-     * @param c input channel buffer
-     * @return object of IPv6InterfaceAddressTlv
-     */
-    public static IPv6InterfaceAddressTlv read20Bytes(ChannelBuffer c) {
-        byte[] yTemp = new byte[20];
-        c.readBytes(yTemp, 0, 20);
-        return IPv6InterfaceAddressTlv.of(yTemp);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", LENGTH);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides IPv6 Interface Address. REFERENCE :[RFC6119]/4.2.
+ */
+public class IPv6InterfaceAddressTlv implements PcepValueType {
+
+    protected static final Logger log = LoggerFactory.getLogger(IPv6InterfaceAddressTlv.class);
+
+    public static final short TYPE = 12; //TDB18
+    public static final short LENGTH = 20;
+    public static final byte VALUE_LENGTH = 18;
+
+    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    public static final IPv6InterfaceAddressTlv NONE = new IPv6InterfaceAddressTlv(NONE_VAL);
+
+    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+    public static final IPv6InterfaceAddressTlv NO_MASK = new IPv6InterfaceAddressTlv(NO_MASK_VAL);
+    public static final IPv6InterfaceAddressTlv FULL_MASK = NONE;
+
+    private final byte[] rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue IPv6 Interface Address Tlv
+     */
+    public IPv6InterfaceAddressTlv(byte[] rawValue) {
+        log.debug("IPv6InterfaceAddressTlv");
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created IPv6InterfaceAddressTlv object.
+     *
+     * @param raw IPv6 Interface Address
+     * @return object of IPv6InterfaceAddressTlv
+     */
+    public static IPv6InterfaceAddressTlv of(final byte[] raw) {
+        //check NONE_VAL
+        boolean bFoundNONE = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (NONE_VAL[i] != raw[i]) {
+                bFoundNONE = false;
+            }
+        }
+
+        if (bFoundNONE) {
+            return NONE;
+        }
+
+        //check NO_MASK_VAL
+        boolean bFoundNoMask = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (0xFF != raw[i]) {
+                bFoundNoMask = false;
+            }
+        }
+        if (bFoundNoMask) {
+            return NO_MASK;
+        }
+
+        return new IPv6InterfaceAddressTlv(raw);
+    }
+
+    /**
+     * Returns value of IPv6 Interface Address.
+     *
+     * @return rawValue raw value
+     */
+    public byte[] getBytes() {
+        return rawValue;
+    }
+
+    /**
+     * Returns value of IPv6 Interface Address.
+     *
+     * @return rawValue raw value
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6InterfaceAddressTlv) {
+            IPv6InterfaceAddressTlv other = (IPv6InterfaceAddressTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv6InterfaceAddressTlv.
+     *
+     * @param c input channel buffer
+     * @return object of IPv6InterfaceAddressTlv
+     */
+    public static IPv6InterfaceAddressTlv read20Bytes(ChannelBuffer c) {
+        byte[] yTemp = new byte[20];
+        c.readBytes(yTemp, 0, 20);
+        return IPv6InterfaceAddressTlv.of(yTemp);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", LENGTH);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6NeighborAddressTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6NeighborAddressTlv.java
index 5bb33ef..8b3390b 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6NeighborAddressTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6NeighborAddressTlv.java
@@ -1,179 +1,179 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides IPv6 Neighbor Address. Reference :[RFC6119]/4.3.
- */
-public class IPv6NeighborAddressTlv implements PcepValueType {
-    protected static final Logger log = LoggerFactory.getLogger(IPv6NeighborAddressTlv.class);
-
-    public static final short TYPE = 13; // TDB19
-    public static final short LENGTH = 20;
-    public static final byte VALUE_LENGTH = 18;
-
-    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-    public static final IPv6NeighborAddressTlv NONE = new IPv6NeighborAddressTlv(NONE_VAL);
-
-    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
-    public static final IPv6NeighborAddressTlv NO_MASK = new IPv6NeighborAddressTlv(NO_MASK_VAL);
-    public static final IPv6NeighborAddressTlv FULL_MASK = NONE;
-
-    private final byte[] rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue IPv6 Neighbor Address Tlv
-     */
-    public IPv6NeighborAddressTlv(byte[] rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created IPv6NeighborAddressTlv object.
-     *
-     * @param raw IPv6 Neighbor Address
-     * @return object of IPv6 Neighbor Address Tlv
-     */
-    public static IPv6NeighborAddressTlv of(final byte[] raw) {
-        //check NONE_VAL
-        boolean bFoundNONE = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (NONE_VAL[i] != raw[i]) {
-                bFoundNONE = false;
-            }
-        }
-
-        if (bFoundNONE) {
-            return NONE;
-        }
-
-        //check NO_MASK_VAL
-        boolean bFoundNoMask = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (0xFF != raw[i]) {
-                bFoundNoMask = false;
-            }
-        }
-        if (bFoundNoMask) {
-            return NO_MASK;
-        }
-
-        return new IPv6NeighborAddressTlv(raw);
-    }
-
-    /**
-     * Returns value of IPv6 Neighbor Address.
-     *
-     * @return rawValue raw value
-     */
-    public byte[] getBytes() {
-        return rawValue;
-    }
-
-    /**
-     * Returns value of IPv6 Neighbor Address.
-     *
-     * @return rawValue raw value
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv6NeighborAddressTlv) {
-            IPv6NeighborAddressTlv other = (IPv6NeighborAddressTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv6NeighborAddressTlv.
-     *
-     * @param c input channel buffer
-     * @return object of IPv6NeighborAddressTlv
-     */
-    public static IPv6NeighborAddressTlv read20Bytes(ChannelBuffer c) {
-        byte[] yTemp = new byte[20];
-        c.readBytes(yTemp, 0, 20);
-        return IPv6NeighborAddressTlv.of(yTemp);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", LENGTH);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides IPv6 Neighbor Address. Reference :[RFC6119]/4.3.
+ */
+public class IPv6NeighborAddressTlv implements PcepValueType {
+    protected static final Logger log = LoggerFactory.getLogger(IPv6NeighborAddressTlv.class);
+
+    public static final short TYPE = 13; // TDB19
+    public static final short LENGTH = 20;
+    public static final byte VALUE_LENGTH = 18;
+
+    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    public static final IPv6NeighborAddressTlv NONE = new IPv6NeighborAddressTlv(NONE_VAL);
+
+    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+    public static final IPv6NeighborAddressTlv NO_MASK = new IPv6NeighborAddressTlv(NO_MASK_VAL);
+    public static final IPv6NeighborAddressTlv FULL_MASK = NONE;
+
+    private final byte[] rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue IPv6 Neighbor Address Tlv
+     */
+    public IPv6NeighborAddressTlv(byte[] rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created IPv6NeighborAddressTlv object.
+     *
+     * @param raw IPv6 Neighbor Address
+     * @return object of IPv6 Neighbor Address Tlv
+     */
+    public static IPv6NeighborAddressTlv of(final byte[] raw) {
+        //check NONE_VAL
+        boolean bFoundNONE = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (NONE_VAL[i] != raw[i]) {
+                bFoundNONE = false;
+            }
+        }
+
+        if (bFoundNONE) {
+            return NONE;
+        }
+
+        //check NO_MASK_VAL
+        boolean bFoundNoMask = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (0xFF != raw[i]) {
+                bFoundNoMask = false;
+            }
+        }
+        if (bFoundNoMask) {
+            return NO_MASK;
+        }
+
+        return new IPv6NeighborAddressTlv(raw);
+    }
+
+    /**
+     * Returns value of IPv6 Neighbor Address.
+     *
+     * @return rawValue raw value
+     */
+    public byte[] getBytes() {
+        return rawValue;
+    }
+
+    /**
+     * Returns value of IPv6 Neighbor Address.
+     *
+     * @return rawValue raw value
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6NeighborAddressTlv) {
+            IPv6NeighborAddressTlv other = (IPv6NeighborAddressTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv6NeighborAddressTlv.
+     *
+     * @param c input channel buffer
+     * @return object of IPv6NeighborAddressTlv
+     */
+    public static IPv6NeighborAddressTlv read20Bytes(ChannelBuffer c) {
+        byte[] yTemp = new byte[20];
+        c.readBytes(yTemp, 0, 20);
+        return IPv6NeighborAddressTlv.of(yTemp);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", LENGTH);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6SubObject.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6SubObject.java
index ecd6132..8e1719e 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6SubObject.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6SubObject.java
@@ -1,222 +1,222 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides IPv6 Sub Object.
- */
-public class IPv6SubObject implements PcepValueType {
-
-    /* reference :RFC 4874.
-    Subobject : IPv6 address
-
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |      Type     |     Length    | IPv6 address (16 bytes)       |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    | IPv6 address (continued)                                      |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    | IPv6 address (continued)                                      |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    | IPv6 address (continued)                                      |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    | IPv6 address (continued)      | Prefix Length |      Flags    |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-      Type
-
-         0x02  IPv6 address
-
-      Length
-
-         The Length contains the total length of the subobject in bytes,
-         including the Type and Length fields.  The Length is always 20.
-
-      IPv6 address
-
-         A 128-bit unicast host address.
-
-      Prefix length
-
-         128
-
-      Flags
-
-         0x01  Local protection available
-
-               Indicates that the link downstream of this node is
-               protected via a local repair mechanism.  This flag can
-               only be set if the Local protection flag was set in the
-               SESSION_ATTRIBUTE object of the corresponding Path
-               message.
-
-         0x02  Local protection in use
-
-               Indicates that a local repair mechanism is in use to
-               maintain this tunnel (usually in the face of an outage
-               of the link it was previously routed over).
-     */
-    protected static final Logger log = LoggerFactory.getLogger(IPv6SubObject.class);
-
-    public static final short TYPE = 0x02;
-    public static final short LENGTH = 20;
-    public static final byte VALUE_LENGTH = 18;
-
-    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-    public static final IPv6SubObject NONE = new IPv6SubObject(NONE_VAL);
-
-    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
-    public static final IPv6SubObject NO_MASK = new IPv6SubObject(NO_MASK_VAL);
-    public static final IPv6SubObject FULL_MASK = NONE;
-
-    private final byte[] rawValue;
-
-    /**
-     * constructor to initialize rawValue with ipv6 address.
-     *
-     * @param rawValue ipv6 address
-     */
-    public IPv6SubObject(byte[] rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * To create instance of IPv6SubObject.
-     *
-     * @param raw byte array of ipv6 address
-     * @return object of IPv6SubObject
-     */
-    public static IPv6SubObject of(final byte[] raw) {
-        //check NONE_VAL
-        boolean bFoundNONE = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (NONE_VAL[i] != raw[i]) {
-                bFoundNONE = false;
-            }
-        }
-
-        if (bFoundNONE) {
-            return NONE;
-        }
-
-        //check NO_MASK_VAL
-        boolean bFoundNoMask = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (0xFF != raw[i]) {
-                bFoundNoMask = false;
-            }
-        }
-        if (bFoundNoMask) {
-            return NO_MASK;
-        }
-
-        return new IPv6SubObject(raw);
-    }
-
-    /**
-     * Returns value of IPv6 Sub Object.
-     *
-     * @return byte array of ipv6 address
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv6SubObject) {
-            IPv6SubObject other = (IPv6SubObject) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv6SubObject.
-     *
-     * @param c type of channel buffer
-     * @return object of IPv6SubObject
-     */
-    public static IPv6SubObject read20Bytes(ChannelBuffer c) {
-        byte[] yTemp = new byte[20];
-        c.readBytes(yTemp, 0, 20);
-        return IPv6SubObject.of(yTemp);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", LENGTH);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides IPv6 Sub Object.
+ */
+public class IPv6SubObject implements PcepValueType {
+
+    /* reference :RFC 4874.
+    Subobject : IPv6 address
+
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |      Type     |     Length    | IPv6 address (16 bytes)       |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | IPv6 address (continued)                                      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | IPv6 address (continued)                                      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | IPv6 address (continued)                                      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    | IPv6 address (continued)      | Prefix Length |      Flags    |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+      Type
+
+         0x02  IPv6 address
+
+      Length
+
+         The Length contains the total length of the subobject in bytes,
+         including the Type and Length fields.  The Length is always 20.
+
+      IPv6 address
+
+         A 128-bit unicast host address.
+
+      Prefix length
+
+         128
+
+      Flags
+
+         0x01  Local protection available
+
+               Indicates that the link downstream of this node is
+               protected via a local repair mechanism.  This flag can
+               only be set if the Local protection flag was set in the
+               SESSION_ATTRIBUTE object of the corresponding Path
+               message.
+
+         0x02  Local protection in use
+
+               Indicates that a local repair mechanism is in use to
+               maintain this tunnel (usually in the face of an outage
+               of the link it was previously routed over).
+     */
+    protected static final Logger log = LoggerFactory.getLogger(IPv6SubObject.class);
+
+    public static final short TYPE = 0x02;
+    public static final short LENGTH = 20;
+    public static final byte VALUE_LENGTH = 18;
+
+    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+    public static final IPv6SubObject NONE = new IPv6SubObject(NONE_VAL);
+
+    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
+    public static final IPv6SubObject NO_MASK = new IPv6SubObject(NO_MASK_VAL);
+    public static final IPv6SubObject FULL_MASK = NONE;
+
+    private final byte[] rawValue;
+
+    /**
+     * constructor to initialize rawValue with ipv6 address.
+     *
+     * @param rawValue ipv6 address
+     */
+    public IPv6SubObject(byte[] rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * To create instance of IPv6SubObject.
+     *
+     * @param raw byte array of ipv6 address
+     * @return object of IPv6SubObject
+     */
+    public static IPv6SubObject of(final byte[] raw) {
+        //check NONE_VAL
+        boolean bFoundNONE = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (NONE_VAL[i] != raw[i]) {
+                bFoundNONE = false;
+            }
+        }
+
+        if (bFoundNONE) {
+            return NONE;
+        }
+
+        //check NO_MASK_VAL
+        boolean bFoundNoMask = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (0xFF != raw[i]) {
+                bFoundNoMask = false;
+            }
+        }
+        if (bFoundNoMask) {
+            return NO_MASK;
+        }
+
+        return new IPv6SubObject(raw);
+    }
+
+    /**
+     * Returns value of IPv6 Sub Object.
+     *
+     * @return byte array of ipv6 address
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6SubObject) {
+            IPv6SubObject other = (IPv6SubObject) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv6SubObject.
+     *
+     * @param c type of channel buffer
+     * @return object of IPv6SubObject
+     */
+    public static IPv6SubObject read20Bytes(ChannelBuffer c) {
+        byte[] yTemp = new byte[20];
+        c.readBytes(yTemp, 0, 20);
+        return IPv6SubObject.of(yTemp);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", LENGTH);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofLocalNodeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofLocalNodeTlv.java
index 4da8b14..bc8eca6 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofLocalNodeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofLocalNodeTlv.java
@@ -1,179 +1,179 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides IPv6 TE Router Id of Local Node. Reference :[RFC6119]/4.1.
- */
-public class IPv6TERouterIdofLocalNodeTlv implements PcepValueType {
-    protected static final Logger log = LoggerFactory.getLogger(IPv6TERouterIdofLocalNodeTlv.class);
-
-    public static final short TYPE = 140; //TDB26
-    public static final short LENGTH = 20;
-    public static final byte VALUE_LENGTH = 18;
-
-    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-    public static final IPv6TERouterIdofLocalNodeTlv NONE = new IPv6TERouterIdofLocalNodeTlv(NONE_VAL);
-
-    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
-    public static final IPv6TERouterIdofLocalNodeTlv NO_MASK = new IPv6TERouterIdofLocalNodeTlv(NO_MASK_VAL);
-    public static final IPv6TERouterIdofLocalNodeTlv FULL_MASK = NONE;
-
-    private final byte[] rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue IPv6TERouterIdofLocalNodeTlv
-     */
-    public IPv6TERouterIdofLocalNodeTlv(byte[] rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created IPv6TERouterIdofLocalNodeTlv object.
-     *
-     * @param raw IPv6 TE Router Id of Local Node
-     * @return object of IPv6TERouterIdofLocalNodeTlv
-     */
-    public static IPv6TERouterIdofLocalNodeTlv of(final byte[] raw) {
-        //check NONE_VAL
-        boolean bFoundNONE = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (NONE_VAL[i] != raw[i]) {
-                bFoundNONE = false;
-            }
-        }
-
-        if (bFoundNONE) {
-            return NONE;
-        }
-
-        //check NO_MASK_VAL
-        boolean bFoundNoMask = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (0xFF != raw[i]) {
-                bFoundNoMask = false;
-            }
-        }
-        if (bFoundNoMask) {
-            return NO_MASK;
-        }
-
-        return new IPv6TERouterIdofLocalNodeTlv(raw);
-    }
-
-    /**
-     * Returns value of IPv6 TE Router Id of Local Node.
-     *
-     * @return byte array value of rawValue
-     */
-    public byte[] getBytes() {
-        return rawValue;
-    }
-
-    /**
-     * Returns value of IPv6 TE Router Id of Local Node.
-     *
-     * @return byte array value of rawValue
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv6TERouterIdofLocalNodeTlv) {
-            IPv6TERouterIdofLocalNodeTlv other = (IPv6TERouterIdofLocalNodeTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv6TERouterIdofLocalNodeTlv.
-     *
-     * @param c input channel buffer
-     * @return object of IPv6TERouterIdofLocalNodeTlv
-     */
-    public static IPv6TERouterIdofLocalNodeTlv read20Bytes(ChannelBuffer c) {
-        byte[] yTemp = new byte[20];
-        c.readBytes(yTemp, 0, 20);
-        return IPv6TERouterIdofLocalNodeTlv.of(yTemp);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", LENGTH);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides IPv6 TE Router Id of Local Node. Reference :[RFC6119]/4.1.
+ */
+public class IPv6TERouterIdofLocalNodeTlv implements PcepValueType {
+    protected static final Logger log = LoggerFactory.getLogger(IPv6TERouterIdofLocalNodeTlv.class);
+
+    public static final short TYPE = 140; //TDB26
+    public static final short LENGTH = 20;
+    public static final byte VALUE_LENGTH = 18;
+
+    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+    public static final IPv6TERouterIdofLocalNodeTlv NONE = new IPv6TERouterIdofLocalNodeTlv(NONE_VAL);
+
+    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
+    public static final IPv6TERouterIdofLocalNodeTlv NO_MASK = new IPv6TERouterIdofLocalNodeTlv(NO_MASK_VAL);
+    public static final IPv6TERouterIdofLocalNodeTlv FULL_MASK = NONE;
+
+    private final byte[] rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue IPv6TERouterIdofLocalNodeTlv
+     */
+    public IPv6TERouterIdofLocalNodeTlv(byte[] rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created IPv6TERouterIdofLocalNodeTlv object.
+     *
+     * @param raw IPv6 TE Router Id of Local Node
+     * @return object of IPv6TERouterIdofLocalNodeTlv
+     */
+    public static IPv6TERouterIdofLocalNodeTlv of(final byte[] raw) {
+        //check NONE_VAL
+        boolean bFoundNONE = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (NONE_VAL[i] != raw[i]) {
+                bFoundNONE = false;
+            }
+        }
+
+        if (bFoundNONE) {
+            return NONE;
+        }
+
+        //check NO_MASK_VAL
+        boolean bFoundNoMask = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (0xFF != raw[i]) {
+                bFoundNoMask = false;
+            }
+        }
+        if (bFoundNoMask) {
+            return NO_MASK;
+        }
+
+        return new IPv6TERouterIdofLocalNodeTlv(raw);
+    }
+
+    /**
+     * Returns value of IPv6 TE Router Id of Local Node.
+     *
+     * @return byte array value of rawValue
+     */
+    public byte[] getBytes() {
+        return rawValue;
+    }
+
+    /**
+     * Returns value of IPv6 TE Router Id of Local Node.
+     *
+     * @return byte array value of rawValue
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6TERouterIdofLocalNodeTlv) {
+            IPv6TERouterIdofLocalNodeTlv other = (IPv6TERouterIdofLocalNodeTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv6TERouterIdofLocalNodeTlv.
+     *
+     * @param c input channel buffer
+     * @return object of IPv6TERouterIdofLocalNodeTlv
+     */
+    public static IPv6TERouterIdofLocalNodeTlv read20Bytes(ChannelBuffer c) {
+        byte[] yTemp = new byte[20];
+        c.readBytes(yTemp, 0, 20);
+        return IPv6TERouterIdofLocalNodeTlv.of(yTemp);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", LENGTH);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofRemoteNodeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofRemoteNodeTlv.java
index 3e47088..1fc7124 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofRemoteNodeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/IPv6TERouterIdofRemoteNodeTlv.java
@@ -1,171 +1,171 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides IPv6 TE Router Id of Remote Node.  Reference :[RFC6119]/4.1.
- */
-public class IPv6TERouterIdofRemoteNodeTlv implements PcepValueType {
-    protected static final Logger log = LoggerFactory.getLogger(IPv6TERouterIdofRemoteNodeTlv.class);
-
-    public static final short TYPE = 1400; //TDB29
-    public static final short LENGTH = 20;
-    public static final byte VALUE_LENGTH = 18;
-
-    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-    public static final IPv6TERouterIdofRemoteNodeTlv NONE = new IPv6TERouterIdofRemoteNodeTlv(NONE_VAL);
-
-    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
-    public static final IPv6TERouterIdofRemoteNodeTlv NO_MASK = new IPv6TERouterIdofRemoteNodeTlv(NO_MASK_VAL);
-    public static final IPv6TERouterIdofRemoteNodeTlv FULL_MASK = NONE;
-
-    private final byte[] rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue IPv6TERouterIdofRemoteNodeTlv
-     */
-    public IPv6TERouterIdofRemoteNodeTlv(byte[] rawValue) {
-        log.debug("IPv6TERouterIdofRemoteNodeTlv");
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created IPv6TERouterIdofRemoteNodeTlv object.
-     *
-     * @param raw IPv6 TE Router Id of RemoteNode
-     * @return object of IPv6TERouterIdofRemoteNodeTlv
-     */
-    public static IPv6TERouterIdofRemoteNodeTlv of(final byte[] raw) {
-        //check NONE_VAL
-        boolean bFoundNONE = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (NONE_VAL[i] != raw[i]) {
-                bFoundNONE = false;
-            }
-        }
-
-        if (bFoundNONE) {
-            return NONE;
-        }
-
-        //check NO_MASK_VAL
-        boolean bFoundNoMask = true;
-        //value starts from 3rd byte.
-        for (int i = 2; i < 20; ++i) {
-            if (0xFF != raw[i]) {
-                bFoundNoMask = false;
-            }
-        }
-        if (bFoundNoMask) {
-            return NO_MASK;
-        }
-
-        return new IPv6TERouterIdofRemoteNodeTlv(raw);
-    }
-
-    /**
-     * Returns value of IPv6 TE Router Id of Remote Node.
-     *
-     * @return byte array value of rawValue
-     */
-    public byte[] getBytes() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof IPv6TERouterIdofRemoteNodeTlv) {
-            IPv6TERouterIdofRemoteNodeTlv other = (IPv6TERouterIdofRemoteNodeTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of IPv6TERouterIdofRemoteNodeTlv.
-     *
-     * @param c input channel buffer
-     * @return object of IPv6TERouterIdofRemoteNodeTlv
-     */
-    public static IPv6TERouterIdofRemoteNodeTlv read20Bytes(ChannelBuffer c) {
-        byte[] yTemp = new byte[20];
-        c.readBytes(yTemp, 0, 20);
-        return IPv6TERouterIdofRemoteNodeTlv.of(yTemp);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", LENGTH);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides IPv6 TE Router Id of Remote Node.  Reference :[RFC6119]/4.1.
+ */
+public class IPv6TERouterIdofRemoteNodeTlv implements PcepValueType {
+    protected static final Logger log = LoggerFactory.getLogger(IPv6TERouterIdofRemoteNodeTlv.class);
+
+    public static final short TYPE = 1400; //TDB29
+    public static final short LENGTH = 20;
+    public static final byte VALUE_LENGTH = 18;
+
+    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    public static final IPv6TERouterIdofRemoteNodeTlv NONE = new IPv6TERouterIdofRemoteNodeTlv(NONE_VAL);
+
+    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+            (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+    public static final IPv6TERouterIdofRemoteNodeTlv NO_MASK = new IPv6TERouterIdofRemoteNodeTlv(NO_MASK_VAL);
+    public static final IPv6TERouterIdofRemoteNodeTlv FULL_MASK = NONE;
+
+    private final byte[] rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue IPv6TERouterIdofRemoteNodeTlv
+     */
+    public IPv6TERouterIdofRemoteNodeTlv(byte[] rawValue) {
+        log.debug("IPv6TERouterIdofRemoteNodeTlv");
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created IPv6TERouterIdofRemoteNodeTlv object.
+     *
+     * @param raw IPv6 TE Router Id of RemoteNode
+     * @return object of IPv6TERouterIdofRemoteNodeTlv
+     */
+    public static IPv6TERouterIdofRemoteNodeTlv of(final byte[] raw) {
+        //check NONE_VAL
+        boolean bFoundNONE = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (NONE_VAL[i] != raw[i]) {
+                bFoundNONE = false;
+            }
+        }
+
+        if (bFoundNONE) {
+            return NONE;
+        }
+
+        //check NO_MASK_VAL
+        boolean bFoundNoMask = true;
+        //value starts from 3rd byte.
+        for (int i = 2; i < 20; ++i) {
+            if (0xFF != raw[i]) {
+                bFoundNoMask = false;
+            }
+        }
+        if (bFoundNoMask) {
+            return NO_MASK;
+        }
+
+        return new IPv6TERouterIdofRemoteNodeTlv(raw);
+    }
+
+    /**
+     * Returns value of IPv6 TE Router Id of Remote Node.
+     *
+     * @return byte array value of rawValue
+     */
+    public byte[] getBytes() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof IPv6TERouterIdofRemoteNodeTlv) {
+            IPv6TERouterIdofRemoteNodeTlv other = (IPv6TERouterIdofRemoteNodeTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of IPv6TERouterIdofRemoteNodeTlv.
+     *
+     * @param c input channel buffer
+     * @return object of IPv6TERouterIdofRemoteNodeTlv
+     */
+    public static IPv6TERouterIdofRemoteNodeTlv read20Bytes(ChannelBuffer c) {
+        byte[] yTemp = new byte[20];
+        c.readBytes(yTemp, 0, 20);
+        return IPv6TERouterIdofRemoteNodeTlv.of(yTemp);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", LENGTH);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/ISISAreaIdentifierTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/ISISAreaIdentifierTlv.java
index 1a0f2f8..648dbb6 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/ISISAreaIdentifierTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/ISISAreaIdentifierTlv.java
@@ -1,155 +1,155 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides ISIS Area Identifier.
- */
-public class ISISAreaIdentifierTlv implements PcepValueType {
-
-    /* Reference :[I-D.ietf-idr- ls-distribution]/3.3.1.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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TBD24]    |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //                 Area Identifier (variable)                  //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(ISISAreaIdentifierTlv.class);
-
-    public static final short TYPE = 107; //TODO:NEED TO HANDLE TBD24
-    private short hLength;
-
-    private final byte[] rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue ISIS-Area-Identifier
-     * @param hLength length
-     */
-    public ISISAreaIdentifierTlv(byte[] rawValue, short hLength) {
-        log.debug("ISISAreaIdentifierTlv");
-        this.rawValue = rawValue;
-        if (0 == hLength) {
-            this.hLength = (short) rawValue.length;
-        } else {
-            this.hLength = hLength;
-        }
-    }
-
-    /**
-     * Returns newly created ISISAreaIdentifierTlv object.
-     *
-     * @param raw ISIS-Area-Identifier
-     * @param hLength length
-     * @return object of ISISAreaIdentifierTlv
-     */
-    public static ISISAreaIdentifierTlv of(final byte[] raw, short hLength) {
-        return new ISISAreaIdentifierTlv(raw, hLength);
-    }
-
-    /**
-     * Returns value of ISIS-Area-Identifier.
-     *
-     * @return byte array of rawValue
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof ISISAreaIdentifierTlv) {
-            ISISAreaIdentifierTlv other = (ISISAreaIdentifierTlv) obj;
-            return Objects.equals(hLength, other.hLength) && Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of ISISAreaIdentifierTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of ISISAreaIdentifierTlv
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) {
-        byte[] iISISAreaIdentifier = new byte[hLength];
-        c.readBytes(iISISAreaIdentifier, 0, hLength);
-        return new ISISAreaIdentifierTlv(iISISAreaIdentifier, hLength);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", hLength);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides ISIS Area Identifier.
+ */
+public class ISISAreaIdentifierTlv implements PcepValueType {
+
+    /* Reference :[I-D.ietf-idr- ls-distribution]/3.3.1.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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TBD24]    |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //                 Area Identifier (variable)                  //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(ISISAreaIdentifierTlv.class);
+
+    public static final short TYPE = 107; //TODO:NEED TO HANDLE TBD24
+    private short hLength;
+
+    private final byte[] rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue ISIS-Area-Identifier
+     * @param hLength length
+     */
+    public ISISAreaIdentifierTlv(byte[] rawValue, short hLength) {
+        log.debug("ISISAreaIdentifierTlv");
+        this.rawValue = rawValue;
+        if (0 == hLength) {
+            this.hLength = (short) rawValue.length;
+        } else {
+            this.hLength = hLength;
+        }
+    }
+
+    /**
+     * Returns newly created ISISAreaIdentifierTlv object.
+     *
+     * @param raw ISIS-Area-Identifier
+     * @param hLength length
+     * @return object of ISISAreaIdentifierTlv
+     */
+    public static ISISAreaIdentifierTlv of(final byte[] raw, short hLength) {
+        return new ISISAreaIdentifierTlv(raw, hLength);
+    }
+
+    /**
+     * Returns value of ISIS-Area-Identifier.
+     *
+     * @return byte array of rawValue
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof ISISAreaIdentifierTlv) {
+            ISISAreaIdentifierTlv other = (ISISAreaIdentifierTlv) obj;
+            return Objects.equals(hLength, other.hLength) && Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of ISISAreaIdentifierTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of ISISAreaIdentifierTlv
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) {
+        byte[] iISISAreaIdentifier = new byte[hLength];
+        c.readBytes(iISISAreaIdentifier, 0, hLength);
+        return new ISISAreaIdentifierTlv(iISISAreaIdentifier, hLength);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", hLength);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LabelSubObject.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LabelSubObject.java
index 9815e43..ab1b620 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LabelSubObject.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LabelSubObject.java
@@ -1,166 +1,166 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * LabelSubObject: Provides a LabelSubObject.
- */
-public class LabelSubObject implements PcepValueType {
-
-    /* Reference : RFC 3209
-     * LABEL Sub Object
-     *
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |     Type      |     Length    |    Flags      |   C-Type      |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |       Contents of Label Object                                |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-    protected static final Logger log = LoggerFactory.getLogger(LabelSubObject.class);
-
-    public static final short TYPE = 0x03;
-    public static final short LENGTH = 8;
-    private final byte flags;
-    private final byte cType;
-    private final int contents;
-
-    /**
-     * constructor to initialize parameters for LabelSubObject.
-     *
-     * @param flags flags
-     * @param cType C-Type
-     * @param contents Contents of label object
-     */
-    public LabelSubObject(byte flags, byte cType, int contents) {
-        this.flags = flags;
-        this.cType = cType;
-        this.contents = contents;
-    }
-
-    /**
-     * Return an object of LabelSubObject.
-     *
-     * @param flags flags
-     * @param cType C-type
-     * @param contents contents of label objects
-     * @return object of LabelSubObject
-     */
-    public static LabelSubObject of(byte flags, byte cType, int contents) {
-        return new LabelSubObject(flags, cType, contents);
-    }
-
-    /**
-     * Returns Flags.
-     *
-     * @return flags
-     */
-    public byte getFlags() {
-        return flags;
-    }
-
-    /**
-     * Returns cType.
-     *
-     * @return cType
-     */
-    public byte getCtype() {
-        return cType;
-    }
-
-    /**
-     * Returns contents.
-     *
-     * @return contents
-     */
-    public int getContents() {
-        return contents;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(flags, cType, contents);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof LabelSubObject) {
-            LabelSubObject other = (LabelSubObject) obj;
-            return Objects.equals(this.flags, other.flags) && Objects.equals(this.cType, other.cType)
-                    && Objects.equals(this.contents, other.contents);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeByte(flags);
-        c.writeByte(cType);
-        c.writeByte(contents);
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of LabelSubObject.
-     *
-     * @param c type of channel buffer
-     * @return object of LabelSubObject
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        byte flags = c.readByte();
-        byte cType = c.readByte();
-        int contents = c.readInt();
-        return new LabelSubObject(flags, cType, contents);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("type", TYPE).add("Length", LENGTH).add("flags", flags)
-                .add("C-type", cType).add("contents", contents).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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * LabelSubObject: Provides a LabelSubObject.
+ */
+public class LabelSubObject implements PcepValueType {
+
+    /* Reference : RFC 3209
+     * LABEL Sub Object
+     *
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |     Type      |     Length    |    Flags      |   C-Type      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |       Contents of Label Object                                |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(LabelSubObject.class);
+
+    public static final short TYPE = 0x03;
+    public static final short LENGTH = 8;
+    private final byte flags;
+    private final byte cType;
+    private final int contents;
+
+    /**
+     * constructor to initialize parameters for LabelSubObject.
+     *
+     * @param flags flags
+     * @param cType C-Type
+     * @param contents Contents of label object
+     */
+    public LabelSubObject(byte flags, byte cType, int contents) {
+        this.flags = flags;
+        this.cType = cType;
+        this.contents = contents;
+    }
+
+    /**
+     * Return an object of LabelSubObject.
+     *
+     * @param flags flags
+     * @param cType C-type
+     * @param contents contents of label objects
+     * @return object of LabelSubObject
+     */
+    public static LabelSubObject of(byte flags, byte cType, int contents) {
+        return new LabelSubObject(flags, cType, contents);
+    }
+
+    /**
+     * Returns Flags.
+     *
+     * @return flags
+     */
+    public byte getFlags() {
+        return flags;
+    }
+
+    /**
+     * Returns cType.
+     *
+     * @return cType
+     */
+    public byte getCtype() {
+        return cType;
+    }
+
+    /**
+     * Returns contents.
+     *
+     * @return contents
+     */
+    public int getContents() {
+        return contents;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(flags, cType, contents);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof LabelSubObject) {
+            LabelSubObject other = (LabelSubObject) obj;
+            return Objects.equals(this.flags, other.flags) && Objects.equals(this.cType, other.cType)
+                    && Objects.equals(this.contents, other.contents);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeByte(flags);
+        c.writeByte(cType);
+        c.writeByte(contents);
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of LabelSubObject.
+     *
+     * @param c type of channel buffer
+     * @return object of LabelSubObject
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        byte flags = c.readByte();
+        byte cType = c.readByte();
+        int contents = c.readInt();
+        return new LabelSubObject(flags, cType, contents);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("type", TYPE).add("Length", LENGTH).add("flags", flags)
+                .add("C-type", cType).add("contents", contents).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkLocalRemoteIdentifiersTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkLocalRemoteIdentifiersTlv.java
index 1d391fa..5c05b30 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkLocalRemoteIdentifiersTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkLocalRemoteIdentifiersTlv.java
@@ -1,152 +1,152 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Local and remote Link Identifiers.
- */
-public class LinkLocalRemoteIdentifiersTlv implements PcepValueType {
-
-    /* Reference :RFC5307
-     * 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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=4      |             Length=8               |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |               Link Local Identifier                           |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |               Link Remote Identifier                          |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(LinkLocalRemoteIdentifiersTlv.class);
-
-    public static final short TYPE = 4;
-    public static final short LENGTH = 8;
-    private final int iLinkLocalIdentifier;
-    private final int iLinkRemoteIdentifier;
-
-    /**
-     * Constructor to initialize iLinkLocalIdentifier , iLinkRemoteIdentifier.
-     *
-     * @param iLinkLocalIdentifier Link Local identifier
-     * @param iLinkRemoteIdentifier Link Remote identifier
-     */
-    public LinkLocalRemoteIdentifiersTlv(int iLinkLocalIdentifier, int iLinkRemoteIdentifier) {
-        this.iLinkLocalIdentifier = iLinkLocalIdentifier;
-        this.iLinkRemoteIdentifier = iLinkRemoteIdentifier;
-    }
-
-    /**
-     * Retruns an object of Link Local Remote Identifiers Tlv.
-     *
-     * @param iLinkLocalIdentifier Link Local identifier
-     * @param iLinkRemoteIdentifier Link Remote identifier
-     * @return object of LinkLocalRemoteIdentifiersTlv
-     */
-    public static LinkLocalRemoteIdentifiersTlv of(int iLinkLocalIdentifier, int iLinkRemoteIdentifier) {
-        return new LinkLocalRemoteIdentifiersTlv(iLinkLocalIdentifier, iLinkRemoteIdentifier);
-    }
-
-    /**
-     * Returns Link-Local-Identifier.
-     *
-     * @return iLinkLocalIdentifier Link Local Identifier
-     */
-    public int getLinkLocalIdentifier() {
-        return iLinkLocalIdentifier;
-    }
-
-    /**
-     * Returns Link-Remote-Identifier.
-     *
-     * @return iLinkRemoteIdentifier Link Remote Identifier.
-     */
-    public int getLinkRemoteIdentifier() {
-        return iLinkRemoteIdentifier;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(iLinkLocalIdentifier, iLinkRemoteIdentifier);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof LinkLocalRemoteIdentifiersTlv) {
-            LinkLocalRemoteIdentifiersTlv other = (LinkLocalRemoteIdentifiersTlv) obj;
-            return Objects.equals(iLinkLocalIdentifier, other.iLinkLocalIdentifier)
-                    && Objects.equals(iLinkRemoteIdentifier, other.iLinkRemoteIdentifier);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(iLinkLocalIdentifier);
-        c.writeInt(iLinkRemoteIdentifier);
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of LinkLocalRemoteIdentifiersTlv.
-     *
-     * @param c input channel buffer
-     * @return object of LinkLocalRemoteIdentifiersTlv
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        int iLinkLocalIdentifier = c.readInt();
-        int iLinkRemoteIdentifier = c.readInt();
-        return new LinkLocalRemoteIdentifiersTlv(iLinkLocalIdentifier, iLinkRemoteIdentifier);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH)
-                .add("LinkLocalIdentifier", iLinkLocalIdentifier).add("LinkRemoteIdentifier", iLinkRemoteIdentifier)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Local and remote Link Identifiers.
+ */
+public class LinkLocalRemoteIdentifiersTlv implements PcepValueType {
+
+    /* Reference :RFC5307
+     * 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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=4      |             Length=8               |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |               Link Local Identifier                           |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |               Link Remote Identifier                          |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(LinkLocalRemoteIdentifiersTlv.class);
+
+    public static final short TYPE = 4;
+    public static final short LENGTH = 8;
+    private final int iLinkLocalIdentifier;
+    private final int iLinkRemoteIdentifier;
+
+    /**
+     * Constructor to initialize iLinkLocalIdentifier , iLinkRemoteIdentifier.
+     *
+     * @param iLinkLocalIdentifier Link Local identifier
+     * @param iLinkRemoteIdentifier Link Remote identifier
+     */
+    public LinkLocalRemoteIdentifiersTlv(int iLinkLocalIdentifier, int iLinkRemoteIdentifier) {
+        this.iLinkLocalIdentifier = iLinkLocalIdentifier;
+        this.iLinkRemoteIdentifier = iLinkRemoteIdentifier;
+    }
+
+    /**
+     * Retruns an object of Link Local Remote Identifiers Tlv.
+     *
+     * @param iLinkLocalIdentifier Link Local identifier
+     * @param iLinkRemoteIdentifier Link Remote identifier
+     * @return object of LinkLocalRemoteIdentifiersTlv
+     */
+    public static LinkLocalRemoteIdentifiersTlv of(int iLinkLocalIdentifier, int iLinkRemoteIdentifier) {
+        return new LinkLocalRemoteIdentifiersTlv(iLinkLocalIdentifier, iLinkRemoteIdentifier);
+    }
+
+    /**
+     * Returns Link-Local-Identifier.
+     *
+     * @return iLinkLocalIdentifier Link Local Identifier
+     */
+    public int getLinkLocalIdentifier() {
+        return iLinkLocalIdentifier;
+    }
+
+    /**
+     * Returns Link-Remote-Identifier.
+     *
+     * @return iLinkRemoteIdentifier Link Remote Identifier.
+     */
+    public int getLinkRemoteIdentifier() {
+        return iLinkRemoteIdentifier;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(iLinkLocalIdentifier, iLinkRemoteIdentifier);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof LinkLocalRemoteIdentifiersTlv) {
+            LinkLocalRemoteIdentifiersTlv other = (LinkLocalRemoteIdentifiersTlv) obj;
+            return Objects.equals(iLinkLocalIdentifier, other.iLinkLocalIdentifier)
+                    && Objects.equals(iLinkRemoteIdentifier, other.iLinkRemoteIdentifier);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(iLinkLocalIdentifier);
+        c.writeInt(iLinkRemoteIdentifier);
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of LinkLocalRemoteIdentifiersTlv.
+     *
+     * @param c input channel buffer
+     * @return object of LinkLocalRemoteIdentifiersTlv
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        int iLinkLocalIdentifier = c.readInt();
+        int iLinkRemoteIdentifier = c.readInt();
+        return new LinkLocalRemoteIdentifiersTlv(iLinkLocalIdentifier, iLinkRemoteIdentifier);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH)
+                .add("LinkLocalIdentifier", iLinkLocalIdentifier).add("LinkRemoteIdentifier", iLinkRemoteIdentifier)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkNameTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkNameTlv.java
index fb36613..aa0f11a 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkNameTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkNameTlv.java
@@ -1,155 +1,155 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides the Link Name.
- */
-public class LinkNameTlv implements PcepValueType {
-
-    /* Reference :[I-D.ietf-idr- ls-distribution] /3.3.2.7
-     * Link name tlv 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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=TDB43       |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //                     Link Name (variable)                    //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(LinkNameTlv.class);
-
-    public static final short TYPE = 1098; //TODO:NEED TO HANDLE TDB43
-    private short hLength;
-
-    private final byte[] rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue Link-Name
-     * @param hLength length
-     */
-    public LinkNameTlv(byte[] rawValue, short hLength) {
-        this.rawValue = rawValue;
-        if (0 == hLength) {
-            this.hLength = (short) rawValue.length;
-        } else {
-            this.hLength = hLength;
-        }
-    }
-
-    /**
-     * Returns newly created LinkNameTlv object.
-     *
-     * @param raw Link-Name
-     * @param hLength length
-     * @return object of LinkNameTlv
-     */
-    public static LinkNameTlv of(final byte[] raw, short hLength) {
-        return new LinkNameTlv(raw, hLength);
-    }
-
-    /**
-     * Returns value of Link-Name.
-     *
-     * @return raw value
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof LinkNameTlv) {
-            LinkNameTlv other = (LinkNameTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of LinkNameTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of LinkNameTlv
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) {
-        byte[] linkName = new byte[hLength];
-        c.readBytes(linkName, 0, hLength);
-        return new LinkNameTlv(linkName, hLength);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", hLength);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides the Link Name.
+ */
+public class LinkNameTlv implements PcepValueType {
+
+    /* Reference :[I-D.ietf-idr- ls-distribution] /3.3.2.7
+     * Link name tlv 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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=TDB43       |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //                     Link Name (variable)                    //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(LinkNameTlv.class);
+
+    public static final short TYPE = 1098; //TODO:NEED TO HANDLE TDB43
+    private short hLength;
+
+    private final byte[] rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue Link-Name
+     * @param hLength length
+     */
+    public LinkNameTlv(byte[] rawValue, short hLength) {
+        this.rawValue = rawValue;
+        if (0 == hLength) {
+            this.hLength = (short) rawValue.length;
+        } else {
+            this.hLength = hLength;
+        }
+    }
+
+    /**
+     * Returns newly created LinkNameTlv object.
+     *
+     * @param raw Link-Name
+     * @param hLength length
+     * @return object of LinkNameTlv
+     */
+    public static LinkNameTlv of(final byte[] raw, short hLength) {
+        return new LinkNameTlv(raw, hLength);
+    }
+
+    /**
+     * Returns value of Link-Name.
+     *
+     * @return raw value
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof LinkNameTlv) {
+            LinkNameTlv other = (LinkNameTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of LinkNameTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of LinkNameTlv
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) {
+        byte[] linkName = new byte[hLength];
+        c.readBytes(linkName, 0, hLength);
+        return new LinkNameTlv(linkName, hLength);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", hLength);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkProtectionTypeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkProtectionTypeTlv.java
index f6faa8d..1327cc3 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkProtectionTypeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LinkProtectionTypeTlv.java
@@ -1,139 +1,139 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provide Link Protection Type.
- */
-
-public class LinkProtectionTypeTlv implements PcepValueType {
-
-    /* Reference  :[RFC5307]/1.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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TDB38]      |             Length=2         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |Protection Cap | Reserved      |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-    protected static final Logger log = LoggerFactory.getLogger(LinkProtectionTypeTlv.class);
-
-    public static final short TYPE = 20; //TDB38
-    public static final short LENGTH = 2;
-    private final byte protectionCap;
-    private final byte reserved;
-
-    /**
-     * Constructor to initialize protectionCap.
-     *
-     * @param protectionCap Protection Cap
-     */
-    public LinkProtectionTypeTlv(byte protectionCap) {
-        this.protectionCap = protectionCap;
-        this.reserved = 0;
-    }
-
-    /**
-     * Constructor to initialize protectionCap, reserved.
-     *
-     * @param protectionCap Protection Cap
-     * @param reserved Reserved value
-     */
-    public LinkProtectionTypeTlv(byte protectionCap, byte reserved) {
-        this.protectionCap = protectionCap;
-        this.reserved = reserved;
-    }
-
-    /**
-     * Returns Protection Cap.
-     *
-     * @return protectionCap Protection Cap
-     */
-    public byte getProtectionCap() {
-        return protectionCap;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(protectionCap, reserved);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof LinkProtectionTypeTlv) {
-            LinkProtectionTypeTlv other = (LinkProtectionTypeTlv) obj;
-            return Objects.equals(protectionCap, other.protectionCap) && Objects.equals(reserved, other.reserved);
-        }
-
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeByte(protectionCap);
-        c.writeByte(reserved);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of LinkProtectionTypeTlv.
-     *
-     * @param c input channel buffer
-     * @return object of LinkProtectionTypeTlv
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        byte protectionCap = c.readByte();
-        byte reserved = c.readByte();
-        return new LinkProtectionTypeTlv(protectionCap, reserved);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH)
-                .add("ProtectionCap", protectionCap).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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provide Link Protection Type.
+ */
+
+public class LinkProtectionTypeTlv implements PcepValueType {
+
+    /* Reference  :[RFC5307]/1.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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TDB38]      |             Length=2         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |Protection Cap | Reserved      |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(LinkProtectionTypeTlv.class);
+
+    public static final short TYPE = 20; //TDB38
+    public static final short LENGTH = 2;
+    private final byte protectionCap;
+    private final byte reserved;
+
+    /**
+     * Constructor to initialize protectionCap.
+     *
+     * @param protectionCap Protection Cap
+     */
+    public LinkProtectionTypeTlv(byte protectionCap) {
+        this.protectionCap = protectionCap;
+        this.reserved = 0;
+    }
+
+    /**
+     * Constructor to initialize protectionCap, reserved.
+     *
+     * @param protectionCap Protection Cap
+     * @param reserved Reserved value
+     */
+    public LinkProtectionTypeTlv(byte protectionCap, byte reserved) {
+        this.protectionCap = protectionCap;
+        this.reserved = reserved;
+    }
+
+    /**
+     * Returns Protection Cap.
+     *
+     * @return protectionCap Protection Cap
+     */
+    public byte getProtectionCap() {
+        return protectionCap;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(protectionCap, reserved);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof LinkProtectionTypeTlv) {
+            LinkProtectionTypeTlv other = (LinkProtectionTypeTlv) obj;
+            return Objects.equals(protectionCap, other.protectionCap) && Objects.equals(reserved, other.reserved);
+        }
+
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeByte(protectionCap);
+        c.writeByte(reserved);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of LinkProtectionTypeTlv.
+     *
+     * @param c input channel buffer
+     * @return object of LinkProtectionTypeTlv
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        byte protectionCap = c.readByte();
+        byte reserved = c.readByte();
+        return new LinkProtectionTypeTlv(protectionCap, reserved);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH)
+                .add("ProtectionCap", protectionCap).toString();
+    }
 }
\ No newline at end of file
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LocalTENodeDescriptorsTLV.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LocalTENodeDescriptorsTLV.java
index 5ba6297..b33029d 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LocalTENodeDescriptorsTLV.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/LocalTENodeDescriptorsTLV.java
@@ -1,243 +1,243 @@
-/*
- * 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.types;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Local TE Node Descriptors TLV which contains Node Descriptor Sub-TLVs.
- */
-public class LocalTENodeDescriptorsTLV implements PcepValueType {
-
-    /* REFERENCE :draft-ietf-idr-ls-distribution-10
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD8]         |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                                                               |
-     //              Node Descriptor Sub-TLVs (variable)            //
-     |                                                               |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     Note: Length is including header here. Refer Routing Universe TLV.
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(LocalTENodeDescriptorsTLV.class);
-
-    public static final short TYPE = 1637; //TODD:change this TBD8
-    public short hLength;
-
-    public static final int TLV_HEADER_LENGTH = 4;
-    // Node Descriptor Sub-TLVs (variable)
-    private LinkedList<PcepValueType> llNodeDescriptorSubTLVs;
-
-    /**
-     * Constructor to initialize llNodeDescriptorSubTLVs.
-     *
-     * @param llNodeDescriptorSubTLVs LinkedList of PcepValueType
-     */
-    public LocalTENodeDescriptorsTLV(LinkedList<PcepValueType> llNodeDescriptorSubTLVs) {
-        this.llNodeDescriptorSubTLVs = llNodeDescriptorSubTLVs;
-    }
-
-    /**
-     * Returns a new object of LocalTENodeDescriptorsTLV.
-     *
-     * @param llNodeDescriptorSubTLVs linked list of Node Descriptor Sub TLVs
-     * @return object of LocalTENodeDescriptorsTLV
-     */
-    public static LocalTENodeDescriptorsTLV of(final LinkedList<PcepValueType> llNodeDescriptorSubTLVs) {
-        return new LocalTENodeDescriptorsTLV(llNodeDescriptorSubTLVs);
-    }
-
-    /**
-     * Returns Linked List of tlvs.
-     *
-     * @return llNodeDescriptorSubTLVs linked list of Node Descriptor Sub TLV
-     */
-    public LinkedList<PcepValueType> getllNodeDescriptorSubTLVs() {
-        return llNodeDescriptorSubTLVs;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(llNodeDescriptorSubTLVs.hashCode());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-
-        /*
-         * Here we have a list of Tlv so to compare each sub tlv between the object
-         * we have to take a list iterator so one by one we can get each sub tlv object
-         * and can compare them.
-         * it may be possible that the size of 2 lists is not equal so we have to first check
-         * the size, if both are same then we should check for the subtlv objects otherwise
-         * we should return false.
-         */
-        if (obj instanceof LocalTENodeDescriptorsTLV) {
-            int countObjSubTlv = 0;
-            int countOtherSubTlv = 0;
-            boolean isCommonSubTlv = true;
-            LocalTENodeDescriptorsTLV other = (LocalTENodeDescriptorsTLV) obj;
-            Iterator<PcepValueType> objListIterator = ((LocalTENodeDescriptorsTLV) obj).llNodeDescriptorSubTLVs
-                    .iterator();
-            countObjSubTlv = ((LocalTENodeDescriptorsTLV) obj).llNodeDescriptorSubTLVs.size();
-            countOtherSubTlv = other.llNodeDescriptorSubTLVs.size();
-            if (countObjSubTlv != countOtherSubTlv) {
-                return false;
-            } else {
-                while (objListIterator.hasNext() && isCommonSubTlv) {
-                    PcepValueType subTlv = objListIterator.next();
-                    isCommonSubTlv = Objects.equals(llNodeDescriptorSubTLVs.contains(subTlv),
-                            other.llNodeDescriptorSubTLVs.contains(subTlv));
-                }
-                return isCommonSubTlv;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int tlvStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        int tlvLenIndex = c.writerIndex();
-        hLength = 0;
-        c.writeShort(0);
-
-        ListIterator<PcepValueType> listIterator = llNodeDescriptorSubTLVs.listIterator();
-
-        while (listIterator.hasNext()) {
-            PcepValueType tlv = listIterator.next();
-            if (null == tlv) {
-                log.debug("TLV is null from subTlv list");
-                continue;
-            }
-            tlv.write(c);
-
-            // need to take care of padding
-            int pad = tlv.getLength() % 4;
-
-            if (0 != pad) {
-                pad = 4 - pad;
-                for (int i = 0; i < pad; ++i) {
-                    c.writeByte((byte) 0);
-                }
-            }
-        }
-        hLength = (short) (c.writerIndex() - tlvStartIndex);
-        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
-        return c.writerIndex() - tlvStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of AutonomousSystemTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length of subtlvs.
-     * @return object of AutonomousSystemTlv
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
-
-        // Node Descriptor Sub-TLVs (variable)
-        LinkedList<PcepValueType> llNodeDescriptorSubTLVs = new LinkedList<PcepValueType>();
-
-        ChannelBuffer tempCb = c.readBytes(hLength);
-
-        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
-
-            PcepValueType tlv;
-            short hType = tempCb.readShort();
-            int iValue = 0;
-            short length = tempCb.readShort();
-
-            switch (hType) {
-
-            case AutonomousSystemTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new AutonomousSystemTlv(iValue);
-                break;
-            case BGPLSidentifierTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new BGPLSidentifierTlv(iValue);
-                break;
-            case OSPFareaIDsubTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new OSPFareaIDsubTlv(iValue);
-                break;
-            case RouterIDSubTlv.TYPE:
-                tlv = RouterIDSubTlv.read(tempCb, length);
-                break;
-
-            default:
-                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
-            }
-
-            // Check for the padding
-            int pad = length % 4;
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= tempCb.readableBytes()) {
-                    tempCb.skipBytes(pad);
-                }
-            }
-
-            llNodeDescriptorSubTLVs.add(tlv);
-        }
-
-        if (0 < tempCb.readableBytes()) {
-            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
-        }
-        return new LocalTENodeDescriptorsTLV(llNodeDescriptorSubTLVs);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
-                .add("NodeDescriptorSubTLVs", llNodeDescriptorSubTLVs).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.types;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Local TE Node Descriptors TLV which contains Node Descriptor Sub-TLVs.
+ */
+public class LocalTENodeDescriptorsTLV implements PcepValueType {
+
+    /* REFERENCE :draft-ietf-idr-ls-distribution-10
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD8]         |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                                                               |
+     //              Node Descriptor Sub-TLVs (variable)            //
+     |                                                               |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     Note: Length is including header here. Refer Routing Universe TLV.
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(LocalTENodeDescriptorsTLV.class);
+
+    public static final short TYPE = 1637; //TODD:change this TBD8
+    public short hLength;
+
+    public static final int TLV_HEADER_LENGTH = 4;
+    // Node Descriptor Sub-TLVs (variable)
+    private LinkedList<PcepValueType> llNodeDescriptorSubTLVs;
+
+    /**
+     * Constructor to initialize llNodeDescriptorSubTLVs.
+     *
+     * @param llNodeDescriptorSubTLVs LinkedList of PcepValueType
+     */
+    public LocalTENodeDescriptorsTLV(LinkedList<PcepValueType> llNodeDescriptorSubTLVs) {
+        this.llNodeDescriptorSubTLVs = llNodeDescriptorSubTLVs;
+    }
+
+    /**
+     * Returns a new object of LocalTENodeDescriptorsTLV.
+     *
+     * @param llNodeDescriptorSubTLVs linked list of Node Descriptor Sub TLVs
+     * @return object of LocalTENodeDescriptorsTLV
+     */
+    public static LocalTENodeDescriptorsTLV of(final LinkedList<PcepValueType> llNodeDescriptorSubTLVs) {
+        return new LocalTENodeDescriptorsTLV(llNodeDescriptorSubTLVs);
+    }
+
+    /**
+     * Returns Linked List of tlvs.
+     *
+     * @return llNodeDescriptorSubTLVs linked list of Node Descriptor Sub TLV
+     */
+    public LinkedList<PcepValueType> getllNodeDescriptorSubTLVs() {
+        return llNodeDescriptorSubTLVs;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(llNodeDescriptorSubTLVs.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+
+        /*
+         * Here we have a list of Tlv so to compare each sub tlv between the object
+         * we have to take a list iterator so one by one we can get each sub tlv object
+         * and can compare them.
+         * it may be possible that the size of 2 lists is not equal so we have to first check
+         * the size, if both are same then we should check for the subtlv objects otherwise
+         * we should return false.
+         */
+        if (obj instanceof LocalTENodeDescriptorsTLV) {
+            int countObjSubTlv = 0;
+            int countOtherSubTlv = 0;
+            boolean isCommonSubTlv = true;
+            LocalTENodeDescriptorsTLV other = (LocalTENodeDescriptorsTLV) obj;
+            Iterator<PcepValueType> objListIterator = ((LocalTENodeDescriptorsTLV) obj).llNodeDescriptorSubTLVs
+                    .iterator();
+            countObjSubTlv = ((LocalTENodeDescriptorsTLV) obj).llNodeDescriptorSubTLVs.size();
+            countOtherSubTlv = other.llNodeDescriptorSubTLVs.size();
+            if (countObjSubTlv != countOtherSubTlv) {
+                return false;
+            } else {
+                while (objListIterator.hasNext() && isCommonSubTlv) {
+                    PcepValueType subTlv = objListIterator.next();
+                    isCommonSubTlv = Objects.equals(llNodeDescriptorSubTLVs.contains(subTlv),
+                            other.llNodeDescriptorSubTLVs.contains(subTlv));
+                }
+                return isCommonSubTlv;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int tlvStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        int tlvLenIndex = c.writerIndex();
+        hLength = 0;
+        c.writeShort(0);
+
+        ListIterator<PcepValueType> listIterator = llNodeDescriptorSubTLVs.listIterator();
+
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+            if (null == tlv) {
+                log.debug("TLV is null from subTlv list");
+                continue;
+            }
+            tlv.write(c);
+
+            // need to take care of padding
+            int pad = tlv.getLength() % 4;
+
+            if (0 != pad) {
+                pad = 4 - pad;
+                for (int i = 0; i < pad; ++i) {
+                    c.writeByte((byte) 0);
+                }
+            }
+        }
+        hLength = (short) (c.writerIndex() - tlvStartIndex);
+        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
+        return c.writerIndex() - tlvStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of AutonomousSystemTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length of subtlvs.
+     * @return object of AutonomousSystemTlv
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
+
+        // Node Descriptor Sub-TLVs (variable)
+        LinkedList<PcepValueType> llNodeDescriptorSubTLVs = new LinkedList<PcepValueType>();
+
+        ChannelBuffer tempCb = c.readBytes(hLength);
+
+        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
+
+            PcepValueType tlv;
+            short hType = tempCb.readShort();
+            int iValue = 0;
+            short length = tempCb.readShort();
+
+            switch (hType) {
+
+            case AutonomousSystemTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new AutonomousSystemTlv(iValue);
+                break;
+            case BGPLSidentifierTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new BGPLSidentifierTlv(iValue);
+                break;
+            case OSPFareaIDsubTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new OSPFareaIDsubTlv(iValue);
+                break;
+            case RouterIDSubTlv.TYPE:
+                tlv = RouterIDSubTlv.read(tempCb, length);
+                break;
+
+            default:
+                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
+            }
+
+            // Check for the padding
+            int pad = length % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= tempCb.readableBytes()) {
+                    tempCb.skipBytes(pad);
+                }
+            }
+
+            llNodeDescriptorSubTLVs.add(tlv);
+        }
+
+        if (0 < tempCb.readableBytes()) {
+            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
+        }
+        return new LocalTENodeDescriptorsTLV(llNodeDescriptorSubTLVs);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
+                .add("NodeDescriptorSubTLVs", llNodeDescriptorSubTLVs).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MPLSProtocolMaskTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MPLSProtocolMaskTlv.java
index ce495cd..ba5231b 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MPLSProtocolMaskTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MPLSProtocolMaskTlv.java
@@ -1,215 +1,215 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides MPLS Protocol Mask.
- */
-public class MPLSProtocolMaskTlv implements PcepValueType {
-
-    /* Reference :[I-D.ietf-idr-ls-distribution]/3.3.2.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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=TDB39       |             Length =1         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |L|R|  Reserved |
-     +-+-+-+-+-+-+-+-+
-     */
-    protected static final Logger log = LoggerFactory.getLogger(MPLSProtocolMaskTlv.class);
-
-    public static final short TYPE = 1094; //TDB39
-    public static final short LENGTH = 1;
-    public static final int SET = 1;
-    public static final byte LFLAG_SET = (byte) 0x80;
-    public static final byte RFLAG_SET = 0x40;
-
-    private final byte rawValue;
-    private final boolean bLFlag;
-    private final boolean bRFlag;
-    private final boolean isRawValueSet;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue MPLS Protocol Mask Flag Bits
-     */
-    public MPLSProtocolMaskTlv(byte rawValue) {
-        this.rawValue = rawValue;
-        isRawValueSet = true;
-        byte temp = rawValue;
-        if ((temp & LFLAG_SET) == SET) {
-            this.bLFlag = true;
-
-        } else {
-            this.bLFlag = false;
-        }
-        if ((temp & RFLAG_SET) == SET) {
-            this.bRFlag = true;
-        } else {
-            this.bRFlag = false;
-        }
-    }
-
-    /**
-     * constructor to initialize different Flags.
-     *
-     * @param bLFlag L-flag
-     * @param bRFlag R-flag
-     */
-    public MPLSProtocolMaskTlv(boolean bLFlag, boolean bRFlag) {
-        this.bLFlag = bLFlag;
-        this.bRFlag = bRFlag;
-        this.rawValue = 0;
-        isRawValueSet = false;
-    }
-
-    /**
-     * Returns newly created MPLSProtocolMaskTlv object.
-     *
-     * @param raw MPLS Protocol Mask Tlv
-     * @return new object of MPLS Protocol Mask Tlv
-     */
-    public static MPLSProtocolMaskTlv of(final byte raw) {
-        return new MPLSProtocolMaskTlv(raw);
-    }
-
-    /**
-     * Returns L-flag.
-     *
-     * @return bLFlag L-flag
-     */
-    public boolean getbLFlag() {
-        return bLFlag;
-    }
-
-    /**
-     * Returns R-flag.
-     *
-     * @return bRFlag R-flag
-     */
-    public boolean getbRFlag() {
-        return bRFlag;
-    }
-
-    /**
-     * Returns raw value.
-     *
-     * @return rawValue raw value
-     */
-    public byte getByte() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        if (isRawValueSet) {
-            return Objects.hash(rawValue);
-        } else {
-            return Objects.hash(bLFlag, bRFlag);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof MPLSProtocolMaskTlv) {
-            MPLSProtocolMaskTlv other = (MPLSProtocolMaskTlv) obj;
-            if (isRawValueSet) {
-                return Objects.equals(this.rawValue, other.rawValue);
-            } else {
-                return Objects.equals(this.bLFlag, other.bLFlag) && Objects.equals(this.bRFlag, other.bRFlag);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        if (isRawValueSet) {
-            c.writeByte(rawValue);
-        } else {
-            byte temp = 0;
-            if (bLFlag) {
-                temp = (byte) (temp | LFLAG_SET);
-            }
-            if (bRFlag) {
-                temp = (byte) (temp | RFLAG_SET);
-            }
-            c.writeByte(temp);
-        }
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of MPLS Protocol Mask Tlv.
-     *
-     * @param c input channel buffer
-     * @return object of MPLS Protocol Mask Tlv
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        byte temp = c.readByte();
-        boolean bLFlag;
-        boolean bRFlag;
-
-        if ((temp & LFLAG_SET) == SET) {
-            bLFlag = true;
-        } else {
-            bLFlag = false;
-        }
-        if ((temp & RFLAG_SET) == SET) {
-            bRFlag = true;
-        } else {
-            bRFlag = false;
-        }
-        return new MPLSProtocolMaskTlv(bLFlag, bRFlag);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides MPLS Protocol Mask.
+ */
+public class MPLSProtocolMaskTlv implements PcepValueType {
+
+    /* Reference :[I-D.ietf-idr-ls-distribution]/3.3.2.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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=TDB39       |             Length =1         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |L|R|  Reserved |
+     +-+-+-+-+-+-+-+-+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(MPLSProtocolMaskTlv.class);
+
+    public static final short TYPE = 1094; //TDB39
+    public static final short LENGTH = 1;
+    public static final int SET = 1;
+    public static final byte LFLAG_SET = (byte) 0x80;
+    public static final byte RFLAG_SET = 0x40;
+
+    private final byte rawValue;
+    private final boolean bLFlag;
+    private final boolean bRFlag;
+    private final boolean isRawValueSet;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue MPLS Protocol Mask Flag Bits
+     */
+    public MPLSProtocolMaskTlv(byte rawValue) {
+        this.rawValue = rawValue;
+        isRawValueSet = true;
+        byte temp = rawValue;
+        if ((temp & LFLAG_SET) == SET) {
+            this.bLFlag = true;
+
+        } else {
+            this.bLFlag = false;
+        }
+        if ((temp & RFLAG_SET) == SET) {
+            this.bRFlag = true;
+        } else {
+            this.bRFlag = false;
+        }
+    }
+
+    /**
+     * constructor to initialize different Flags.
+     *
+     * @param bLFlag L-flag
+     * @param bRFlag R-flag
+     */
+    public MPLSProtocolMaskTlv(boolean bLFlag, boolean bRFlag) {
+        this.bLFlag = bLFlag;
+        this.bRFlag = bRFlag;
+        this.rawValue = 0;
+        isRawValueSet = false;
+    }
+
+    /**
+     * Returns newly created MPLSProtocolMaskTlv object.
+     *
+     * @param raw MPLS Protocol Mask Tlv
+     * @return new object of MPLS Protocol Mask Tlv
+     */
+    public static MPLSProtocolMaskTlv of(final byte raw) {
+        return new MPLSProtocolMaskTlv(raw);
+    }
+
+    /**
+     * Returns L-flag.
+     *
+     * @return bLFlag L-flag
+     */
+    public boolean getbLFlag() {
+        return bLFlag;
+    }
+
+    /**
+     * Returns R-flag.
+     *
+     * @return bRFlag R-flag
+     */
+    public boolean getbRFlag() {
+        return bRFlag;
+    }
+
+    /**
+     * Returns raw value.
+     *
+     * @return rawValue raw value
+     */
+    public byte getByte() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        if (isRawValueSet) {
+            return Objects.hash(rawValue);
+        } else {
+            return Objects.hash(bLFlag, bRFlag);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof MPLSProtocolMaskTlv) {
+            MPLSProtocolMaskTlv other = (MPLSProtocolMaskTlv) obj;
+            if (isRawValueSet) {
+                return Objects.equals(this.rawValue, other.rawValue);
+            } else {
+                return Objects.equals(this.bLFlag, other.bLFlag) && Objects.equals(this.bRFlag, other.bRFlag);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        if (isRawValueSet) {
+            c.writeByte(rawValue);
+        } else {
+            byte temp = 0;
+            if (bLFlag) {
+                temp = (byte) (temp | LFLAG_SET);
+            }
+            if (bRFlag) {
+                temp = (byte) (temp | RFLAG_SET);
+            }
+            c.writeByte(temp);
+        }
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of MPLS Protocol Mask Tlv.
+     *
+     * @param c input channel buffer
+     * @return object of MPLS Protocol Mask Tlv
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        byte temp = c.readByte();
+        boolean bLFlag;
+        boolean bRFlag;
+
+        if ((temp & LFLAG_SET) == SET) {
+            bLFlag = true;
+        } else {
+            bLFlag = false;
+        }
+        if ((temp & RFLAG_SET) == SET) {
+            bRFlag = true;
+        } else {
+            bRFlag = false;
+        }
+        return new MPLSProtocolMaskTlv(bLFlag, bRFlag);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumLinkBandwidthTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumLinkBandwidthTlv.java
index d990c37..7dc2dfb 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumLinkBandwidthTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumLinkBandwidthTlv.java
@@ -1,134 +1,134 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provide the Maximum Link Bandwidth.
- */
-public class MaximumLinkBandwidthTlv implements PcepValueType {
-
-    /* Reference :[RFC5305]/3.3.
-     * 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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TDB34]      |             Length=4         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |               Maximum  Link Bandwidth                         |
-     +-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(MaximumLinkBandwidthTlv.class);
-
-    public static final short TYPE = 9; //TDB34
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue Maximum-Link-Bandwidth
-     */
-
-    public MaximumLinkBandwidthTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created MaximumLinkBandwidthTlv object.
-     *
-     * @param raw value of Maximum-Link-Bandwidth
-     * @return object of MaximumLinkBandwidthTlv
-     */
-    public static MaximumLinkBandwidthTlv of(final int raw) {
-        return new MaximumLinkBandwidthTlv(raw);
-    }
-
-    /**
-     * Returns value of Maximum  Link Bandwidth.
-     *
-     * @return rawValue Maximum  Link Bandwidth
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof MaximumLinkBandwidthTlv) {
-            MaximumLinkBandwidthTlv other = (MaximumLinkBandwidthTlv) obj;
-            return Objects.equals(rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of MaximumLinkBandwidthTlv.
-     *
-     * @param c input channel buffer
-     * @return object of MaximumLinkBandwidthTlv
-     */
-    public static MaximumLinkBandwidthTlv read(ChannelBuffer c) {
-        return MaximumLinkBandwidthTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provide the Maximum Link Bandwidth.
+ */
+public class MaximumLinkBandwidthTlv implements PcepValueType {
+
+    /* Reference :[RFC5305]/3.3.
+     * 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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TDB34]      |             Length=4         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |               Maximum  Link Bandwidth                         |
+     +-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(MaximumLinkBandwidthTlv.class);
+
+    public static final short TYPE = 9; //TDB34
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue Maximum-Link-Bandwidth
+     */
+
+    public MaximumLinkBandwidthTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created MaximumLinkBandwidthTlv object.
+     *
+     * @param raw value of Maximum-Link-Bandwidth
+     * @return object of MaximumLinkBandwidthTlv
+     */
+    public static MaximumLinkBandwidthTlv of(final int raw) {
+        return new MaximumLinkBandwidthTlv(raw);
+    }
+
+    /**
+     * Returns value of Maximum  Link Bandwidth.
+     *
+     * @return rawValue Maximum  Link Bandwidth
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof MaximumLinkBandwidthTlv) {
+            MaximumLinkBandwidthTlv other = (MaximumLinkBandwidthTlv) obj;
+            return Objects.equals(rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of MaximumLinkBandwidthTlv.
+     *
+     * @param c input channel buffer
+     * @return object of MaximumLinkBandwidthTlv
+     */
+    public static MaximumLinkBandwidthTlv read(ChannelBuffer c) {
+        return MaximumLinkBandwidthTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumReservableLinkBandwidthTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumReservableLinkBandwidthTlv.java
index 2d963bb..ac68551 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumReservableLinkBandwidthTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/MaximumReservableLinkBandwidthTlv.java
@@ -1,133 +1,133 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provide the Maximum Reservable Link Bandwidth.
- */
-public class MaximumReservableLinkBandwidthTlv implements PcepValueType {
-
-    /* Reference :[RFC5305]/3.5.
-     * 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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TDB35]      |             Length=4         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |               Maximum Reservable Link Bandwidth               |
-     +-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(MaximumReservableLinkBandwidthTlv.class);
-
-    public static final short TYPE = 10; // TDB35
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue MaximumReservableLinkBandwidth
-     */
-    public MaximumReservableLinkBandwidthTlv(int rawValue) {
-        log.debug("MaximumReservableLinkBandwidthTlv");
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created MaximumReservableLinkBandwidth object.
-     *
-     * @param raw MaximumReservableLinkBandwidth
-     * @return object of MaximumReservableLinkBandwidthTlv
-     */
-    public static MaximumReservableLinkBandwidthTlv of(final int raw) {
-        return new MaximumReservableLinkBandwidthTlv(raw);
-    }
-
-    /**
-     * Returns value of Maximum Reservable Link Bandwidth.
-     * @return rawValue Maximum Reservable Link Bandwidth
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof MaximumReservableLinkBandwidthTlv) {
-            MaximumReservableLinkBandwidthTlv other = (MaximumReservableLinkBandwidthTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of MaximumReservableLinkBandwidthTlv.
-     *
-     * @param c input channel buffer
-     * @return object of MaximumReservableLinkBandwidthTlv
-     */
-    public static MaximumReservableLinkBandwidthTlv read(ChannelBuffer c) {
-        return MaximumReservableLinkBandwidthTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provide the Maximum Reservable Link Bandwidth.
+ */
+public class MaximumReservableLinkBandwidthTlv implements PcepValueType {
+
+    /* Reference :[RFC5305]/3.5.
+     * 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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TDB35]      |             Length=4         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |               Maximum Reservable Link Bandwidth               |
+     +-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-+-++-+-+-+-
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(MaximumReservableLinkBandwidthTlv.class);
+
+    public static final short TYPE = 10; // TDB35
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue MaximumReservableLinkBandwidth
+     */
+    public MaximumReservableLinkBandwidthTlv(int rawValue) {
+        log.debug("MaximumReservableLinkBandwidthTlv");
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created MaximumReservableLinkBandwidth object.
+     *
+     * @param raw MaximumReservableLinkBandwidth
+     * @return object of MaximumReservableLinkBandwidthTlv
+     */
+    public static MaximumReservableLinkBandwidthTlv of(final int raw) {
+        return new MaximumReservableLinkBandwidthTlv(raw);
+    }
+
+    /**
+     * Returns value of Maximum Reservable Link Bandwidth.
+     * @return rawValue Maximum Reservable Link Bandwidth
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof MaximumReservableLinkBandwidthTlv) {
+            MaximumReservableLinkBandwidthTlv other = (MaximumReservableLinkBandwidthTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of MaximumReservableLinkBandwidthTlv.
+     *
+     * @param c input channel buffer
+     * @return object of MaximumReservableLinkBandwidthTlv
+     */
+    public static MaximumReservableLinkBandwidthTlv read(ChannelBuffer c) {
+        return MaximumReservableLinkBandwidthTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv4addressTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv4addressTlv.java
index 2306dcc..6f19338 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv4addressTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv4addressTlv.java
@@ -1,143 +1,143 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * NexthopIPv6addressTlv provides Ipv4 address of next hop.
- */
-public class NexthopIPv4addressTlv implements PcepValueType {
-
-    /*
-        Reference :draft-zhao-pce-pcep-extension-for-pce-controller-01
-
-        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
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       | Type=TBD                      | Length = 8                    |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                     nexthop IPv4 address                      |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                      NEXTHOP-IPV4-ADDRESS TLV
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(NexthopIPv4addressTlv.class);
-
-    public static final short TYPE = 2; //to be defined
-    //Length is header + value
-    public static final short LENGTH = 8;
-    public static final short VALUE_LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize next hop IPv4 address.
-     *
-     * @param rawValue next hop IPv4 address
-     */
-    public NexthopIPv4addressTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Return next hop IPv4 address tlv.
-     *
-     * @param raw of next hop IPv4 address
-     * @return object of NexthopIPv4addressTlv
-     */
-    public static NexthopIPv4addressTlv of(final int raw) {
-        return new NexthopIPv4addressTlv(raw);
-    }
-
-    /**
-     * Returns next hop IPv4 address.
-     *
-     * @return next hop IPv4 address
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof NexthopIPv4addressTlv) {
-            NexthopIPv4addressTlv other = (NexthopIPv4addressTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of NexthopIPv4addressTlv.
-     *
-     * @param c type of channel buffer
-     * @return object of NexthopIPv4addressTlv
-     */
-    public static NexthopIPv4addressTlv read(ChannelBuffer c) {
-        return NexthopIPv4addressTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("Type", TYPE)
-                .add("Length", LENGTH)
-                .add("Ipv4Address ", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * NexthopIPv6addressTlv provides Ipv4 address of next hop.
+ */
+public class NexthopIPv4addressTlv implements PcepValueType {
+
+    /*
+        Reference :draft-zhao-pce-pcep-extension-for-pce-controller-01
+
+        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
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       | Type=TBD                      | Length = 8                    |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                     nexthop IPv4 address                      |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                      NEXTHOP-IPV4-ADDRESS TLV
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(NexthopIPv4addressTlv.class);
+
+    public static final short TYPE = 2; //to be defined
+    //Length is header + value
+    public static final short LENGTH = 8;
+    public static final short VALUE_LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize next hop IPv4 address.
+     *
+     * @param rawValue next hop IPv4 address
+     */
+    public NexthopIPv4addressTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Return next hop IPv4 address tlv.
+     *
+     * @param raw of next hop IPv4 address
+     * @return object of NexthopIPv4addressTlv
+     */
+    public static NexthopIPv4addressTlv of(final int raw) {
+        return new NexthopIPv4addressTlv(raw);
+    }
+
+    /**
+     * Returns next hop IPv4 address.
+     *
+     * @return next hop IPv4 address
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NexthopIPv4addressTlv) {
+            NexthopIPv4addressTlv other = (NexthopIPv4addressTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of NexthopIPv4addressTlv.
+     *
+     * @param c type of channel buffer
+     * @return object of NexthopIPv4addressTlv
+     */
+    public static NexthopIPv4addressTlv read(ChannelBuffer c) {
+        return NexthopIPv4addressTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("Type", TYPE)
+                .add("Length", LENGTH)
+                .add("Ipv4Address ", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv6addressTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv6addressTlv.java
index 9b39dd5..45bf7ac 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv6addressTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopIPv6addressTlv.java
@@ -1,190 +1,190 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * NexthopIPv6addressTlv provides Ipv6  address of next hop.
- */
-public class NexthopIPv6addressTlv implements PcepValueType {
-
-    /*
-       Reference: draft-zhao-pce-pcep-extension-for-pce-controller-01.
-
-        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
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       | Type=TBD                      | Length = 20                   |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                                                               |
-       //               nexthop IPv6 address (16 bytes)                //
-       |                                                               |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                     NEXTHOP-IPV6-ADDRESS TLV:
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(NexthopIPv6addressTlv.class);
-
-    public static final short TYPE = 100; //to be defined
-    //Length is header + value
-    public static final short LENGTH = 20;
-    public static final short VALUE_LENGTH = 16;
-
-    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-    public static final NexthopIPv6addressTlv NONE = new NexthopIPv6addressTlv(NONE_VAL);
-
-    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
-        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
-    public static final NexthopIPv6addressTlv NO_MASK = new NexthopIPv6addressTlv(NO_MASK_VAL);
-    public static final NexthopIPv6addressTlv FULL_MASK = NONE;
-
-    private final byte[] rawValue;
-
-    /**
-     * Constructor to initialize IP address for next hop IPv6 address tlv.
-     *
-     * @param rawValue value of Next hop ipAddress
-     */
-    public NexthopIPv6addressTlv(byte[] rawValue) {
-        log.debug("NexthopIPv6addressTlv");
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Creates next hop IPv6 address tlv.
-     *
-     * @param raw value of Next hop ipAddress
-     * @return object of NexthopIPv6addressTlv
-     */
-    //logic to be checked
-    public static NexthopIPv6addressTlv of(final byte[] raw) {
-        //check NONE_VAL
-        boolean bFoundNONE = true;
-        //value starts from 3rd byte.
-        for (int i = 5; i < 20; ++i) {
-            if (NONE_VAL[i] != raw[i]) {
-                bFoundNONE = false;
-            }
-        }
-
-        if (bFoundNONE) {
-            return NONE;
-        }
-
-        //check NO_MASK_VAL
-        boolean bFoundNoMask = true;
-        //value starts from 3rd byte.
-        for (int i = 5; i < 20; ++i) {
-            if (0xFF != raw[i]) {
-                bFoundNoMask = false;
-            }
-        }
-        if (bFoundNoMask) {
-            return NO_MASK;
-        }
-        return new NexthopIPv6addressTlv(raw);
-    }
-
-    /**
-     * Returns next hop IPv6 address.
-     *
-     * @return next hop IPv6 address
-     */
-    public byte[] getBytes() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof NexthopIPv6addressTlv) {
-            NexthopIPv6addressTlv other = (NexthopIPv6addressTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of NexthopIPv6addressTlv.
-     *
-     * @param c type of channel buffer
-     * @return object of NexthopIPv6addressTlv
-     */
-    public static NexthopIPv6addressTlv read(ChannelBuffer c) {
-        byte[] yTemp = new byte[20];
-        c.readBytes(yTemp, 0, 20);
-        return NexthopIPv6addressTlv.of(yTemp);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", LENGTH);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("IpAddress", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * NexthopIPv6addressTlv provides Ipv6  address of next hop.
+ */
+public class NexthopIPv6addressTlv implements PcepValueType {
+
+    /*
+       Reference: draft-zhao-pce-pcep-extension-for-pce-controller-01.
+
+        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
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       | Type=TBD                      | Length = 20                   |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                                                               |
+       //               nexthop IPv6 address (16 bytes)                //
+       |                                                               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                     NEXTHOP-IPV6-ADDRESS TLV:
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(NexthopIPv6addressTlv.class);
+
+    public static final short TYPE = 100; //to be defined
+    //Length is header + value
+    public static final short LENGTH = 20;
+    public static final short VALUE_LENGTH = 16;
+
+    private static final byte[] NONE_VAL = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+    public static final NexthopIPv6addressTlv NONE = new NexthopIPv6addressTlv(NONE_VAL);
+
+    private static final byte[] NO_MASK_VAL = {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
+        (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF };
+    public static final NexthopIPv6addressTlv NO_MASK = new NexthopIPv6addressTlv(NO_MASK_VAL);
+    public static final NexthopIPv6addressTlv FULL_MASK = NONE;
+
+    private final byte[] rawValue;
+
+    /**
+     * Constructor to initialize IP address for next hop IPv6 address tlv.
+     *
+     * @param rawValue value of Next hop ipAddress
+     */
+    public NexthopIPv6addressTlv(byte[] rawValue) {
+        log.debug("NexthopIPv6addressTlv");
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Creates next hop IPv6 address tlv.
+     *
+     * @param raw value of Next hop ipAddress
+     * @return object of NexthopIPv6addressTlv
+     */
+    //logic to be checked
+    public static NexthopIPv6addressTlv of(final byte[] raw) {
+        //check NONE_VAL
+        boolean bFoundNONE = true;
+        //value starts from 3rd byte.
+        for (int i = 5; i < 20; ++i) {
+            if (NONE_VAL[i] != raw[i]) {
+                bFoundNONE = false;
+            }
+        }
+
+        if (bFoundNONE) {
+            return NONE;
+        }
+
+        //check NO_MASK_VAL
+        boolean bFoundNoMask = true;
+        //value starts from 3rd byte.
+        for (int i = 5; i < 20; ++i) {
+            if (0xFF != raw[i]) {
+                bFoundNoMask = false;
+            }
+        }
+        if (bFoundNoMask) {
+            return NO_MASK;
+        }
+        return new NexthopIPv6addressTlv(raw);
+    }
+
+    /**
+     * Returns next hop IPv6 address.
+     *
+     * @return next hop IPv6 address
+     */
+    public byte[] getBytes() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NexthopIPv6addressTlv) {
+            NexthopIPv6addressTlv other = (NexthopIPv6addressTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of NexthopIPv6addressTlv.
+     *
+     * @param c type of channel buffer
+     * @return object of NexthopIPv6addressTlv
+     */
+    public static NexthopIPv6addressTlv read(ChannelBuffer c) {
+        byte[] yTemp = new byte[20];
+        c.readBytes(yTemp, 0, 20);
+        return NexthopIPv6addressTlv.of(yTemp);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", LENGTH);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("IpAddress", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopUnnumberedIPv4IDTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopUnnumberedIPv4IDTlv.java
index c8fae0a..837fcf4 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopUnnumberedIPv4IDTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NexthopUnnumberedIPv4IDTlv.java
@@ -1,159 +1,159 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * NexthopUnnumberedIPv4IDTlv provides the next node's ID and Interface ID.
- */
-public class NexthopUnnumberedIPv4IDTlv implements PcepValueType {
-
-    /*
-        Reference : draft-zhao-pce-pcep-extension-for-pce-controller-01.
-
-        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
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       | Type=TBD                      | Length = 12                   |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                          Node-ID                              |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                          Interface ID                         |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                      NEXTHOP-UNNUMBERED-IPV4-ID TLV
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(NexthopUnnumberedIPv4IDTlv.class);
-
-    public static final short TYPE = 1; //to be defined
-    //Length is header + value
-    public static final short LENGTH = 12;
-
-    private final int nodeID;
-    private final int interfaceID;
-
-    /**
-     * constructor to initialize nodeID and interfaceID.
-     *
-     * @param nodeID node ID
-     * @param interfaceID interface ID
-     */
-    public NexthopUnnumberedIPv4IDTlv(int nodeID, int interfaceID) {
-        this.nodeID = nodeID;
-        this.interfaceID = interfaceID;
-    }
-
-    /**
-     * Returns new object of NexthopUnnumberedIPv4IDTlv.
-     *
-     * @param nodeID node ID
-     * @param interfaceID interface ID
-     * @return NexthopUnnumberedIPv4IDTlv
-     */
-    public static NexthopUnnumberedIPv4IDTlv of(int nodeID, int interfaceID) {
-        return new NexthopUnnumberedIPv4IDTlv(nodeID, interfaceID);
-    }
-
-    /**
-     * Returns Node Id.
-     *
-     * @return node ID
-     */
-    public int getNodeID() {
-        return nodeID;
-    }
-
-    /**
-     * Returns Interface Id.
-     *
-     * @return interface ID
-     */
-    public int getInterfaceID() {
-        return interfaceID;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(nodeID, interfaceID);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof NexthopUnnumberedIPv4IDTlv) {
-            NexthopUnnumberedIPv4IDTlv other = (NexthopUnnumberedIPv4IDTlv) obj;
-            return Objects.equals(this.nodeID, other.nodeID) && Objects.equals(this.interfaceID, other.interfaceID);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-
-        c.writeInt(nodeID);
-        c.writeInt(interfaceID);
-
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of NexthopUnnumberedIPv4IDTlv.
-     *
-     * @param cb type of channel buffer
-     * @return object of NexthopUnnumberedIPv4IDTlv
-     */
-    public static NexthopUnnumberedIPv4IDTlv read(ChannelBuffer cb) {
-        int nodeID = cb.readInt();
-        int interfaceID = cb.readInt();
-        return new NexthopUnnumberedIPv4IDTlv(nodeID, interfaceID);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("NodeId", nodeID)
-                .add("InterfaceId", interfaceID).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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * NexthopUnnumberedIPv4IDTlv provides the next node's ID and Interface ID.
+ */
+public class NexthopUnnumberedIPv4IDTlv implements PcepValueType {
+
+    /*
+        Reference : draft-zhao-pce-pcep-extension-for-pce-controller-01.
+
+        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
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       | Type=TBD                      | Length = 12                   |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                          Node-ID                              |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                          Interface ID                         |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                      NEXTHOP-UNNUMBERED-IPV4-ID TLV
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(NexthopUnnumberedIPv4IDTlv.class);
+
+    public static final short TYPE = 1; //to be defined
+    //Length is header + value
+    public static final short LENGTH = 12;
+
+    private final int nodeID;
+    private final int interfaceID;
+
+    /**
+     * constructor to initialize nodeID and interfaceID.
+     *
+     * @param nodeID node ID
+     * @param interfaceID interface ID
+     */
+    public NexthopUnnumberedIPv4IDTlv(int nodeID, int interfaceID) {
+        this.nodeID = nodeID;
+        this.interfaceID = interfaceID;
+    }
+
+    /**
+     * Returns new object of NexthopUnnumberedIPv4IDTlv.
+     *
+     * @param nodeID node ID
+     * @param interfaceID interface ID
+     * @return NexthopUnnumberedIPv4IDTlv
+     */
+    public static NexthopUnnumberedIPv4IDTlv of(int nodeID, int interfaceID) {
+        return new NexthopUnnumberedIPv4IDTlv(nodeID, interfaceID);
+    }
+
+    /**
+     * Returns Node Id.
+     *
+     * @return node ID
+     */
+    public int getNodeID() {
+        return nodeID;
+    }
+
+    /**
+     * Returns Interface Id.
+     *
+     * @return interface ID
+     */
+    public int getInterfaceID() {
+        return interfaceID;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(nodeID, interfaceID);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NexthopUnnumberedIPv4IDTlv) {
+            NexthopUnnumberedIPv4IDTlv other = (NexthopUnnumberedIPv4IDTlv) obj;
+            return Objects.equals(this.nodeID, other.nodeID) && Objects.equals(this.interfaceID, other.interfaceID);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+
+        c.writeInt(nodeID);
+        c.writeInt(interfaceID);
+
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of NexthopUnnumberedIPv4IDTlv.
+     *
+     * @param cb type of channel buffer
+     * @return object of NexthopUnnumberedIPv4IDTlv
+     */
+    public static NexthopUnnumberedIPv4IDTlv read(ChannelBuffer cb) {
+        int nodeID = cb.readInt();
+        int interfaceID = cb.readInt();
+        return new NexthopUnnumberedIPv4IDTlv(nodeID, interfaceID);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("NodeId", nodeID)
+                .add("InterfaceId", interfaceID).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeFlagBitsTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeFlagBitsTlv.java
index 7e0b09c..0b5c0e5 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeFlagBitsTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeFlagBitsTlv.java
@@ -1,229 +1,229 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provide node Flags bits.
- */
-public class NodeFlagBitsTlv implements PcepValueType {
-
-    /* Reference :[I-D.ietf-idr- ls-distribution] /3.3.1.1
-     * 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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TBD21]      |             Length=1         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |O|T|E|B| Reserved|
-     +-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(NodeFlagBitsTlv.class);
-
-    public static final short TYPE = 14;
-    public static final short LENGTH = 1;
-    public static final int SET = 1;
-    public static final byte OFLAG_SET = (byte) 0x80;
-    public static final byte TFLAG_SET = 0x40;
-    public static final byte EFLAG_SET = 0x20;
-    public static final byte BFLAG_SET = 0x10;
-
-    private final byte rawValue;
-    private final boolean bOFlag;
-    private final boolean bTFlag;
-    private final boolean bEFlag;
-    private final boolean bBFlag;
-    private final boolean isRawValueSet;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue of Node Flag Bits TLV
-     */
-    public NodeFlagBitsTlv(byte rawValue) {
-        this.rawValue = rawValue;
-        isRawValueSet = true;
-        byte temp = rawValue;
-        this.bOFlag = (temp & OFLAG_SET) == OFLAG_SET ? true : false;
-        this.bTFlag = (temp & TFLAG_SET) == TFLAG_SET ? true : false;
-        this.bEFlag = (temp & EFLAG_SET) == EFLAG_SET ? true : false;
-        this.bBFlag = (temp & BFLAG_SET) == BFLAG_SET ? true : false;
-    }
-
-    /**
-     * constructor to initialize different Flags.
-     *
-     * @param bOFlag O-flag
-     * @param bTFlag T-flag
-     * @param bEFlag E-flag
-     * @param bBFlag B-flag
-     */
-    public NodeFlagBitsTlv(boolean bOFlag, boolean bTFlag, boolean bEFlag, boolean bBFlag) {
-        this.bOFlag = bOFlag;
-        this.bTFlag = bTFlag;
-        this.bEFlag = bEFlag;
-        this.bBFlag = bBFlag;
-        this.rawValue = 0;
-        this.isRawValueSet = false;
-    }
-
-    /**
-     * Returns newly created NodeFlagBitsTlv object.
-     *
-     * @param raw of Node Flag Bits TLV
-     * @return new object of NodeFlagBitsTlv
-     */
-    public static NodeFlagBitsTlv of(final byte raw) {
-        return new NodeFlagBitsTlv(raw);
-    }
-
-    /**
-     * Returns raw value of NodeFlagBitsTlv.
-     *
-     * @return rawValue raw value
-     */
-    public byte getbyte() {
-        return rawValue;
-    }
-
-    /**
-     * Returns O-flag.
-     *
-     * @return bOFlag O-flag
-     */
-    public boolean getOFlag() {
-        return bOFlag;
-    }
-
-    /**
-     * Returns T-flag.
-     *
-     * @return bTFlag T-flag
-     */
-    public boolean getTFlag() {
-        return bTFlag;
-    }
-
-    /**
-     * Returns E-flag.
-     *
-     * @return bEFlag E-flag
-     */
-    public boolean getEFlag() {
-        return bEFlag;
-    }
-
-    /**
-     * Returns B-flag.
-     *
-     * @return bBFlag B-flag
-     */
-    public boolean getBFlag() {
-        return bBFlag;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        if (isRawValueSet) {
-            return Objects.hash(rawValue);
-        } else {
-            return Objects.hash(bOFlag, bTFlag, bEFlag, bBFlag);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof NodeFlagBitsTlv) {
-            NodeFlagBitsTlv other = (NodeFlagBitsTlv) obj;
-            if (isRawValueSet) {
-                return Objects.equals(this.rawValue, other.rawValue);
-            } else {
-                return Objects.equals(this.bOFlag, other.bOFlag) && Objects.equals(this.bTFlag, other.bTFlag)
-                        && Objects.equals(this.bEFlag, other.bEFlag) && Objects.equals(this.bBFlag, other.bBFlag);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        if (isRawValueSet) {
-            c.writeByte(rawValue);
-        } else {
-            byte temp = 0;
-            if (bOFlag) {
-                temp = (byte) (temp | OFLAG_SET);
-            }
-            if (bTFlag) {
-                temp = (byte) (temp | TFLAG_SET);
-            }
-            if (bEFlag) {
-                temp = (byte) (temp | EFLAG_SET);
-            }
-            if (bBFlag) {
-                temp = (byte) (temp | BFLAG_SET);
-            }
-            c.writeByte(temp);
-        }
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of NodeFlagBitsTlv.
-     *
-     * @param c input channel buffer
-     * @return object of NodeFlagBitsTlv
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-
-        return NodeFlagBitsTlv.of(c.readByte());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH)
-                .add("OFlag", (bOFlag) ? 1 : 0).add("TFlag", (bTFlag) ? 1 : 0).add("EFlag", (bEFlag) ? 1 : 0)
-                .add("BFlag", (bBFlag) ? 1 : 0).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.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provide node Flags bits.
+ */
+public class NodeFlagBitsTlv implements PcepValueType {
+
+    /* Reference :[I-D.ietf-idr- ls-distribution] /3.3.1.1
+     * 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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TBD21]      |             Length=1         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |O|T|E|B| Reserved|
+     +-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(NodeFlagBitsTlv.class);
+
+    public static final short TYPE = 14;
+    public static final short LENGTH = 1;
+    public static final int SET = 1;
+    public static final byte OFLAG_SET = (byte) 0x80;
+    public static final byte TFLAG_SET = 0x40;
+    public static final byte EFLAG_SET = 0x20;
+    public static final byte BFLAG_SET = 0x10;
+
+    private final byte rawValue;
+    private final boolean bOFlag;
+    private final boolean bTFlag;
+    private final boolean bEFlag;
+    private final boolean bBFlag;
+    private final boolean isRawValueSet;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue of Node Flag Bits TLV
+     */
+    public NodeFlagBitsTlv(byte rawValue) {
+        this.rawValue = rawValue;
+        isRawValueSet = true;
+        byte temp = rawValue;
+        this.bOFlag = (temp & OFLAG_SET) == OFLAG_SET ? true : false;
+        this.bTFlag = (temp & TFLAG_SET) == TFLAG_SET ? true : false;
+        this.bEFlag = (temp & EFLAG_SET) == EFLAG_SET ? true : false;
+        this.bBFlag = (temp & BFLAG_SET) == BFLAG_SET ? true : false;
+    }
+
+    /**
+     * constructor to initialize different Flags.
+     *
+     * @param bOFlag O-flag
+     * @param bTFlag T-flag
+     * @param bEFlag E-flag
+     * @param bBFlag B-flag
+     */
+    public NodeFlagBitsTlv(boolean bOFlag, boolean bTFlag, boolean bEFlag, boolean bBFlag) {
+        this.bOFlag = bOFlag;
+        this.bTFlag = bTFlag;
+        this.bEFlag = bEFlag;
+        this.bBFlag = bBFlag;
+        this.rawValue = 0;
+        this.isRawValueSet = false;
+    }
+
+    /**
+     * Returns newly created NodeFlagBitsTlv object.
+     *
+     * @param raw of Node Flag Bits TLV
+     * @return new object of NodeFlagBitsTlv
+     */
+    public static NodeFlagBitsTlv of(final byte raw) {
+        return new NodeFlagBitsTlv(raw);
+    }
+
+    /**
+     * Returns raw value of NodeFlagBitsTlv.
+     *
+     * @return rawValue raw value
+     */
+    public byte getbyte() {
+        return rawValue;
+    }
+
+    /**
+     * Returns O-flag.
+     *
+     * @return bOFlag O-flag
+     */
+    public boolean getOFlag() {
+        return bOFlag;
+    }
+
+    /**
+     * Returns T-flag.
+     *
+     * @return bTFlag T-flag
+     */
+    public boolean getTFlag() {
+        return bTFlag;
+    }
+
+    /**
+     * Returns E-flag.
+     *
+     * @return bEFlag E-flag
+     */
+    public boolean getEFlag() {
+        return bEFlag;
+    }
+
+    /**
+     * Returns B-flag.
+     *
+     * @return bBFlag B-flag
+     */
+    public boolean getBFlag() {
+        return bBFlag;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        if (isRawValueSet) {
+            return Objects.hash(rawValue);
+        } else {
+            return Objects.hash(bOFlag, bTFlag, bEFlag, bBFlag);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NodeFlagBitsTlv) {
+            NodeFlagBitsTlv other = (NodeFlagBitsTlv) obj;
+            if (isRawValueSet) {
+                return Objects.equals(this.rawValue, other.rawValue);
+            } else {
+                return Objects.equals(this.bOFlag, other.bOFlag) && Objects.equals(this.bTFlag, other.bTFlag)
+                        && Objects.equals(this.bEFlag, other.bEFlag) && Objects.equals(this.bBFlag, other.bBFlag);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        if (isRawValueSet) {
+            c.writeByte(rawValue);
+        } else {
+            byte temp = 0;
+            if (bOFlag) {
+                temp = (byte) (temp | OFLAG_SET);
+            }
+            if (bTFlag) {
+                temp = (byte) (temp | TFLAG_SET);
+            }
+            if (bEFlag) {
+                temp = (byte) (temp | EFLAG_SET);
+            }
+            if (bBFlag) {
+                temp = (byte) (temp | BFLAG_SET);
+            }
+            c.writeByte(temp);
+        }
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of NodeFlagBitsTlv.
+     *
+     * @param c input channel buffer
+     * @return object of NodeFlagBitsTlv
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+
+        return NodeFlagBitsTlv.of(c.readByte());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH)
+                .add("OFlag", (bOFlag) ? 1 : 0).add("TFlag", (bTFlag) ? 1 : 0).add("EFlag", (bEFlag) ? 1 : 0)
+                .add("BFlag", (bBFlag) ? 1 : 0).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeNameTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeNameTlv.java
index 010d7b0..e535a35 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeNameTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/NodeNameTlv.java
@@ -1,154 +1,154 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provide the name for the node.
- */
-public class NodeNameTlv implements PcepValueType {
-
-    /* reference :[I-D.ietf-idr-ls-distribution]/3.3.1.3
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TBD23]     |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //                     Node Name (variable)                    //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(NodeNameTlv.class);
-
-    public static final short TYPE = 1007; //TODO:check and change TBD23
-    public final short hLength;
-
-    private final byte[] rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue of Node Name
-     * @param hLength length
-     */
-    public NodeNameTlv(byte[] rawValue, short hLength) {
-        log.debug("NodeNameTlv");
-        this.rawValue = rawValue;
-        if (0 == hLength) {
-            this.hLength = (short) rawValue.length;
-        } else {
-            this.hLength = hLength;
-        }
-    }
-
-    /**
-     * Returns newly created NodeNameTlv object.
-     *
-     * @param raw of NodeName
-     * @param hLength length
-     * @return new object of Node Name Tlv
-     */
-    public static NodeNameTlv of(final byte[] raw, short hLength) {
-        return new NodeNameTlv(raw, hLength);
-    }
-
-    /**
-     * Returns RawValue for NodeName.
-     *
-     * @return rawValue raw value
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof NodeNameTlv) {
-            NodeNameTlv other = (NodeNameTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of NodeNameTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of Node Name TLV
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) {
-        byte[] iNodeName = new byte[hLength];
-        c.readBytes(iNodeName, 0, hLength);
-        return new NodeNameTlv(iNodeName, hLength);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", hLength);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provide the name for the node.
+ */
+public class NodeNameTlv implements PcepValueType {
+
+    /* reference :[I-D.ietf-idr-ls-distribution]/3.3.1.3
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TBD23]     |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //                     Node Name (variable)                    //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(NodeNameTlv.class);
+
+    public static final short TYPE = 1007; //TODO:check and change TBD23
+    public final short hLength;
+
+    private final byte[] rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue of Node Name
+     * @param hLength length
+     */
+    public NodeNameTlv(byte[] rawValue, short hLength) {
+        log.debug("NodeNameTlv");
+        this.rawValue = rawValue;
+        if (0 == hLength) {
+            this.hLength = (short) rawValue.length;
+        } else {
+            this.hLength = hLength;
+        }
+    }
+
+    /**
+     * Returns newly created NodeNameTlv object.
+     *
+     * @param raw of NodeName
+     * @param hLength length
+     * @return new object of Node Name Tlv
+     */
+    public static NodeNameTlv of(final byte[] raw, short hLength) {
+        return new NodeNameTlv(raw, hLength);
+    }
+
+    /**
+     * Returns RawValue for NodeName.
+     *
+     * @return rawValue raw value
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof NodeNameTlv) {
+            NodeNameTlv other = (NodeNameTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of NodeNameTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of Node Name TLV
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) {
+        byte[] iNodeName = new byte[hLength];
+        c.readBytes(iNodeName, 0, hLength);
+        return new NodeNameTlv(iNodeName, hLength);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", hLength);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OSPFareaIDsubTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OSPFareaIDsubTlv.java
index 96a57e9..b876db0 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OSPFareaIDsubTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OSPFareaIDsubTlv.java
@@ -1,132 +1,132 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides area ID for OSPF area.
- */
-public class OSPFareaIDsubTlv implements PcepValueType {
-
-    /* Reference :draft-ietf-idr-ls-distribution-10.
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD12]         |             Length=4         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                    opaque value (32 Bit AS Number)            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(OSPFareaIDsubTlv.class);
-
-    public static final short TYPE = 600; //TODD:change this TBD12
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue area ID for OSPF area.
-     */
-    public OSPFareaIDsubTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created OSPFareaIDsubTlv object.
-     *
-     * @param raw opaque value of AreaID
-     * @return new object of OSPF area ID sub TLV
-     */
-    public static OSPFareaIDsubTlv of(final int raw) {
-        return new OSPFareaIDsubTlv(raw);
-    }
-
-    /**
-     * Returns RawValue opaque value of AreaID.
-     *
-     * @return rawValue Area ID
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof OSPFareaIDsubTlv) {
-            OSPFareaIDsubTlv other = (OSPFareaIDsubTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of OSPFAreaIdSubTlv.
-     *
-     * @param c input channel buffer
-     * @return object of OSPFAreaIdSubTlv
-     */
-    public static OSPFareaIDsubTlv read(ChannelBuffer c) {
-        return OSPFareaIDsubTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides area ID for OSPF area.
+ */
+public class OSPFareaIDsubTlv implements PcepValueType {
+
+    /* Reference :draft-ietf-idr-ls-distribution-10.
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD12]         |             Length=4         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                    opaque value (32 Bit AS Number)            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(OSPFareaIDsubTlv.class);
+
+    public static final short TYPE = 600; //TODD:change this TBD12
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue area ID for OSPF area.
+     */
+    public OSPFareaIDsubTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created OSPFareaIDsubTlv object.
+     *
+     * @param raw opaque value of AreaID
+     * @return new object of OSPF area ID sub TLV
+     */
+    public static OSPFareaIDsubTlv of(final int raw) {
+        return new OSPFareaIDsubTlv(raw);
+    }
+
+    /**
+     * Returns RawValue opaque value of AreaID.
+     *
+     * @return rawValue Area ID
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof OSPFareaIDsubTlv) {
+            OSPFareaIDsubTlv other = (OSPFareaIDsubTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of OSPFAreaIdSubTlv.
+     *
+     * @param c input channel buffer
+     * @return object of OSPFAreaIdSubTlv
+     */
+    public static OSPFareaIDsubTlv read(ChannelBuffer c) {
+        return OSPFareaIDsubTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueLinkAttributeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueLinkAttributeTlv.java
index 2cc5b24..1af332e 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueLinkAttributeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueLinkAttributeTlv.java
@@ -1,155 +1,155 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides Opaque Link Attribute.
- */
-public class OpaqueLinkAttributeTlv implements PcepValueType {
-
-    /*
-     * TLV format.
-     * Reference :[I-D.ietf-idr-attributesls-distribution] /3.3.2.6
-      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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=TBD42       |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //                Opaque link attributes (variable)            //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(OpaqueLinkAttributeTlv.class);
-
-    public static final short TYPE = 1097; //TODO:NEED TO HANDLE TDB42
-    private final short hLength;
-
-    private final byte[] rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue of Opaque Link Attribute
-     * @param hLength length
-     */
-    public OpaqueLinkAttributeTlv(byte[] rawValue, short hLength) {
-        log.debug("OpaqueLinkAttributeTlv");
-        this.rawValue = rawValue;
-        if (0 == hLength) {
-            this.hLength = (short) rawValue.length;
-        } else {
-            this.hLength = hLength;
-        }
-    }
-
-    /**
-     * Returns newly created OpaqueLinkAttributeTlv object.
-     *
-     * @param raw of Opaque Link Attribute
-     * @param hLength length
-     * @return new object of OpaqueLinkAttributeTlv
-     */
-    public static OpaqueLinkAttributeTlv of(final byte[] raw, short hLength) {
-        return new OpaqueLinkAttributeTlv(raw, hLength);
-    }
-
-    /**
-     * Returns raw value of Opaque Link Attribute Tlv.
-     * @return rawValue raw value
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof OpaqueLinkAttributeTlv) {
-            OpaqueLinkAttributeTlv other = (OpaqueLinkAttributeTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of OpaqueLinkAttributeTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of Opaque Link Attribute Tlv
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) {
-        byte[] iOpaqueValue = new byte[hLength];
-        c.readBytes(iOpaqueValue, 0, hLength);
-        return new OpaqueLinkAttributeTlv(iOpaqueValue, hLength);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", hLength);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides Opaque Link Attribute.
+ */
+public class OpaqueLinkAttributeTlv implements PcepValueType {
+
+    /*
+     * TLV format.
+     * Reference :[I-D.ietf-idr-attributesls-distribution] /3.3.2.6
+      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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=TBD42       |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //                Opaque link attributes (variable)            //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(OpaqueLinkAttributeTlv.class);
+
+    public static final short TYPE = 1097; //TODO:NEED TO HANDLE TDB42
+    private final short hLength;
+
+    private final byte[] rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue of Opaque Link Attribute
+     * @param hLength length
+     */
+    public OpaqueLinkAttributeTlv(byte[] rawValue, short hLength) {
+        log.debug("OpaqueLinkAttributeTlv");
+        this.rawValue = rawValue;
+        if (0 == hLength) {
+            this.hLength = (short) rawValue.length;
+        } else {
+            this.hLength = hLength;
+        }
+    }
+
+    /**
+     * Returns newly created OpaqueLinkAttributeTlv object.
+     *
+     * @param raw of Opaque Link Attribute
+     * @param hLength length
+     * @return new object of OpaqueLinkAttributeTlv
+     */
+    public static OpaqueLinkAttributeTlv of(final byte[] raw, short hLength) {
+        return new OpaqueLinkAttributeTlv(raw, hLength);
+    }
+
+    /**
+     * Returns raw value of Opaque Link Attribute Tlv.
+     * @return rawValue raw value
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof OpaqueLinkAttributeTlv) {
+            OpaqueLinkAttributeTlv other = (OpaqueLinkAttributeTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of OpaqueLinkAttributeTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of Opaque Link Attribute Tlv
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) {
+        byte[] iOpaqueValue = new byte[hLength];
+        c.readBytes(iOpaqueValue, 0, hLength);
+        return new OpaqueLinkAttributeTlv(iOpaqueValue, hLength);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", hLength);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueNodeAttributeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueNodeAttributeTlv.java
index d6cc5fe..5aec8c5 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueNodeAttributeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/OpaqueNodeAttributeTlv.java
@@ -1,154 +1,154 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides Opaque node attributes.
- */
-public class OpaqueNodeAttributeTlv implements PcepValueType {
-    /*
-     * Reference [I-D.ietf-idr-Properties ls-distribution] /3.3.1.5
-     * 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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=[TBD22]     |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //               Opaque node attributes (variable)             //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(OpaqueNodeAttributeTlv.class);
-
-    public static final short TYPE = 1001;
-    private final short hLength;
-
-    private final byte[] rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue Opaque Node Attribute
-     * @param hLength length
-     */
-    public OpaqueNodeAttributeTlv(byte[] rawValue, short hLength) {
-
-        this.rawValue = rawValue;
-        if (0 == hLength) {
-            this.hLength = (short) rawValue.length;
-        } else {
-            this.hLength = hLength;
-        }
-    }
-
-    /**
-     * Returns newly created OpaqueNodeAttributeTlv object.
-     *
-     * @param raw value of Opaque Node Attribute
-     * @param hLength length
-     * @return new object of Opaque Node Attribute Tlv
-     */
-    public static OpaqueNodeAttributeTlv of(final byte[] raw, short hLength) {
-        return new OpaqueNodeAttributeTlv(raw, hLength);
-    }
-
-    /**
-     * Returns raw value of Opaque Node Attribute Tlv.
-     *
-     * @return rawValue of Opaque Node Attribute
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof OpaqueLinkAttributeTlv) {
-            OpaqueNodeAttributeTlv other = (OpaqueNodeAttributeTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of Opaque Node Attribute Tlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of OpaqueNodeAttributeTlv
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) {
-        byte[] iOpaqueValue = new byte[hLength];
-        c.readBytes(iOpaqueValue, 0, hLength);
-        return new OpaqueNodeAttributeTlv(iOpaqueValue, hLength);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", hLength);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides Opaque node attributes.
+ */
+public class OpaqueNodeAttributeTlv implements PcepValueType {
+    /*
+     * Reference [I-D.ietf-idr-Properties ls-distribution] /3.3.1.5
+     * 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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=[TBD22]     |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //               Opaque node attributes (variable)             //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(OpaqueNodeAttributeTlv.class);
+
+    public static final short TYPE = 1001;
+    private final short hLength;
+
+    private final byte[] rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue Opaque Node Attribute
+     * @param hLength length
+     */
+    public OpaqueNodeAttributeTlv(byte[] rawValue, short hLength) {
+
+        this.rawValue = rawValue;
+        if (0 == hLength) {
+            this.hLength = (short) rawValue.length;
+        } else {
+            this.hLength = hLength;
+        }
+    }
+
+    /**
+     * Returns newly created OpaqueNodeAttributeTlv object.
+     *
+     * @param raw value of Opaque Node Attribute
+     * @param hLength length
+     * @return new object of Opaque Node Attribute Tlv
+     */
+    public static OpaqueNodeAttributeTlv of(final byte[] raw, short hLength) {
+        return new OpaqueNodeAttributeTlv(raw, hLength);
+    }
+
+    /**
+     * Returns raw value of Opaque Node Attribute Tlv.
+     *
+     * @return rawValue of Opaque Node Attribute
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof OpaqueLinkAttributeTlv) {
+            OpaqueNodeAttributeTlv other = (OpaqueNodeAttributeTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of Opaque Node Attribute Tlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of OpaqueNodeAttributeTlv
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) {
+        byte[] iOpaqueValue = new byte[hLength];
+        c.readBytes(iOpaqueValue, 0, hLength);
+        return new OpaqueNodeAttributeTlv(iOpaqueValue, hLength);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", hLength);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathKeySubObject.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathKeySubObject.java
index 36f5c26..86ad042 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathKeySubObject.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathKeySubObject.java
@@ -1,159 +1,159 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Path Key SubObject: When a PCC needs to expand a path-key in order to expand a CPS, it
- * issues a Path Computation Request (PCReq) to the PCE identified in
- * the PKS in the RSVP-TE ERO that it is processing.  The PCC supplies
- * the PKS to be expanded in a PATH-KEY SubObject in the PCReq message.
- */
-public class PathKeySubObject implements PcepValueType {
-
-    /*
-    Pathkey subobject(RFC 5520):
-     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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |L|    Type     |     Length    |           Path-Key            |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                         PCE ID (4 bytes)                      |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(PathKeySubObject.class);
-
-    public static final byte TYPE = 0x40;
-    public static final byte LENGTH = 8;
-    private final short pathKey;
-    private final int pceID;
-
-    /**
-     * Constructor for Path Key sub Object which initializes pathKey and pceId.
-     *
-     * @param pathKey path key provided by PCC
-     * @param pceID ID for the PCE
-     */
-    public PathKeySubObject(short pathKey, int pceID) {
-        this.pathKey = pathKey;
-        this.pceID = pceID;
-    }
-
-    /**
-     * Creates Path Key sub Object which initializes pathKey and pceId.
-     *
-     * @param pathKey path key provided by PCC
-     * @param pceID PCE id
-     * @return new object of type path key sub object
-     */
-    public static PathKeySubObject of(short pathKey, int pceID) {
-        return new PathKeySubObject(pathKey, pceID);
-    }
-
-    /**
-     * Returns Path Key.
-     *
-     * @return pathKey
-     */
-    public short getPathKey() {
-        return pathKey;
-    }
-
-    /**
-     * Returns pceID.
-     *
-     * @return pceID
-     */
-    public int getPceId() {
-        return pceID;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(pathKey, pceID);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PathKeySubObject) {
-            PathKeySubObject other = (PathKeySubObject) obj;
-            return Objects.equals(this.pathKey, other.pathKey) && Objects.equals(this.pceID, other.pceID);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-
-        c.writeShort(pathKey);
-        c.writeInt(pceID);
-
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns new path key sub objects.
-     *
-     * @param c of type channel buffer
-     * @return object of type path key sub object
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        Short pathKey = c.readShort();
-        int pceID = c.readInt();
-        return new PathKeySubObject(pathKey, pceID);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("Type", TYPE)
-                .add("Length", LENGTH)
-                .add("PathKey", pathKey)
-                .add("PceID", pceID)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Path Key SubObject: When a PCC needs to expand a path-key in order to expand a CPS, it
+ * issues a Path Computation Request (PCReq) to the PCE identified in
+ * the PKS in the RSVP-TE ERO that it is processing.  The PCC supplies
+ * the PKS to be expanded in a PATH-KEY SubObject in the PCReq message.
+ */
+public class PathKeySubObject implements PcepValueType {
+
+    /*
+    Pathkey subobject(RFC 5520):
+     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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |L|    Type     |     Length    |           Path-Key            |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                         PCE ID (4 bytes)                      |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(PathKeySubObject.class);
+
+    public static final byte TYPE = 0x40;
+    public static final byte LENGTH = 8;
+    private final short pathKey;
+    private final int pceID;
+
+    /**
+     * Constructor for Path Key sub Object which initializes pathKey and pceId.
+     *
+     * @param pathKey path key provided by PCC
+     * @param pceID ID for the PCE
+     */
+    public PathKeySubObject(short pathKey, int pceID) {
+        this.pathKey = pathKey;
+        this.pceID = pceID;
+    }
+
+    /**
+     * Creates Path Key sub Object which initializes pathKey and pceId.
+     *
+     * @param pathKey path key provided by PCC
+     * @param pceID PCE id
+     * @return new object of type path key sub object
+     */
+    public static PathKeySubObject of(short pathKey, int pceID) {
+        return new PathKeySubObject(pathKey, pceID);
+    }
+
+    /**
+     * Returns Path Key.
+     *
+     * @return pathKey
+     */
+    public short getPathKey() {
+        return pathKey;
+    }
+
+    /**
+     * Returns pceID.
+     *
+     * @return pceID
+     */
+    public int getPceId() {
+        return pceID;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(pathKey, pceID);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PathKeySubObject) {
+            PathKeySubObject other = (PathKeySubObject) obj;
+            return Objects.equals(this.pathKey, other.pathKey) && Objects.equals(this.pceID, other.pceID);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+
+        c.writeShort(pathKey);
+        c.writeInt(pceID);
+
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns new path key sub objects.
+     *
+     * @param c of type channel buffer
+     * @return object of type path key sub object
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        Short pathKey = c.readShort();
+        int pceID = c.readInt();
+        return new PathKeySubObject(pathKey, pceID);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("Type", TYPE)
+                .add("Length", LENGTH)
+                .add("PathKey", pathKey)
+                .add("PceID", pceID)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathSetupTypeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathSetupTypeTlv.java
index 19e2b5b..7aed1fe 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathSetupTypeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PathSetupTypeTlv.java
@@ -1,146 +1,146 @@
-package org.onosproject.pcepio.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PcepSetup type tlv.
- */
-public class PathSetupTypeTlv implements PcepValueType {
-
-    /*
-       Reference : draft-sivabalan-pce-lsp-setup-type-02.
-
-         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
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         | Type                          | Length                        |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         | Reserved                                      | PST           |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                     Figure 1: PATH-SETUP-TYPE TLV
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PathSetupTypeTlv.class);
-
-    public static final short TYPE = 0; //TODO : need to reassign the value as per RFC
-    public static final short LENGTH = 4;
-
-    private final byte pst;
-    private final int rawValue;
-    private final boolean isRawValueSet;
-
-    /**
-     * Constructor to initialize parameters for path setup type tlv.
-     *
-     * @param rawValue parameter for path setup type tlv
-     */
-    public PathSetupTypeTlv(final int rawValue) {
-        this.rawValue = rawValue;
-        this.isRawValueSet = true;
-        this.pst = (byte) rawValue;
-    }
-
-    /**
-     * Constructor to initialize pst.
-     *
-     * @param pst PST
-     */
-    public PathSetupTypeTlv(byte pst) {
-        this.pst = pst;
-        this.rawValue = 0;
-        this.isRawValueSet = false;
-    }
-
-    /**
-     * Returns Object of path setup type tlv.
-     *
-     * @param raw parameter for path setup type tlv
-     * @return object of PathSetupTypeTlv
-     */
-    public static PathSetupTypeTlv of(final int raw) {
-        return new PathSetupTypeTlv(raw);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    /**
-     * Returns parameters for path setup type tlv.
-     *
-     * @return parameters for path setup type tlv
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    /**
-     * Returns the pst value.
-     *
-     * @return pst value
-     */
-    public byte getPst() {
-        return pst;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(pst);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PathSetupTypeTlv) {
-            PathSetupTypeTlv other = (PathSetupTypeTlv) obj;
-            return Objects.equals(this.pst, other.pst);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(pst);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Returns the object of type PathSetupTypeTlv.
-     *
-     * @param c is type Channel buffer
-     * @return object of PathSetupTypeTlv
-     */
-    public static PathSetupTypeTlv read(ChannelBuffer c) {
-        return PathSetupTypeTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("PST", pst)
-                .toString();
-    }
-}
+package org.onosproject.pcepio.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PcepSetup type tlv.
+ */
+public class PathSetupTypeTlv implements PcepValueType {
+
+    /*
+       Reference : draft-sivabalan-pce-lsp-setup-type-02.
+
+         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
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Type                          | Length                        |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Reserved                                      | PST           |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                     Figure 1: PATH-SETUP-TYPE TLV
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PathSetupTypeTlv.class);
+
+    public static final short TYPE = 0; //TODO : need to reassign the value as per RFC
+    public static final short LENGTH = 4;
+
+    private final byte pst;
+    private final int rawValue;
+    private final boolean isRawValueSet;
+
+    /**
+     * Constructor to initialize parameters for path setup type tlv.
+     *
+     * @param rawValue parameter for path setup type tlv
+     */
+    public PathSetupTypeTlv(final int rawValue) {
+        this.rawValue = rawValue;
+        this.isRawValueSet = true;
+        this.pst = (byte) rawValue;
+    }
+
+    /**
+     * Constructor to initialize pst.
+     *
+     * @param pst PST
+     */
+    public PathSetupTypeTlv(byte pst) {
+        this.pst = pst;
+        this.rawValue = 0;
+        this.isRawValueSet = false;
+    }
+
+    /**
+     * Returns Object of path setup type tlv.
+     *
+     * @param raw parameter for path setup type tlv
+     * @return object of PathSetupTypeTlv
+     */
+    public static PathSetupTypeTlv of(final int raw) {
+        return new PathSetupTypeTlv(raw);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    /**
+     * Returns parameters for path setup type tlv.
+     *
+     * @return parameters for path setup type tlv
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    /**
+     * Returns the pst value.
+     *
+     * @return pst value
+     */
+    public byte getPst() {
+        return pst;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(pst);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PathSetupTypeTlv) {
+            PathSetupTypeTlv other = (PathSetupTypeTlv) obj;
+            return Objects.equals(this.pst, other.pst);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(pst);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Returns the object of type PathSetupTypeTlv.
+     *
+     * @param c is type Channel buffer
+     * @return object of PathSetupTypeTlv
+     */
+    public static PathSetupTypeTlv read(ChannelBuffer c) {
+        return PathSetupTypeTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("PST", pst)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PceccCapabilityTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PceccCapabilityTlv.java
index 6d1ad85..2c55d27 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PceccCapabilityTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PceccCapabilityTlv.java
@@ -1,176 +1,176 @@
-package org.onosproject.pcepio.types;
-
-import java.util.Objects;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides PceccCapabilityTlv.
- */
-public class PceccCapabilityTlv implements PcepValueType {
-
-    /*          PCECC CAPABILITY TLV
-     * Reference : draft-zhao-pce-pcep-extension-for-pce-controller-01, section-7.1.1
-
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |               Type=32         |            Length=4           |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                             Flags                         |G|L|
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PceccCapabilityTlv.class);
-
-    public static final short TYPE = 32;
-    public static final short LENGTH = 4;
-    public static final int SET = 1;
-    public static final byte LFLAG_CHECK = 0x01;
-    public static final byte GFLAG_CHECK = 0x02;
-
-    private final boolean bGFlag;
-    private final boolean bLFlag;
-
-    private final int rawValue;
-    private final boolean isRawValueSet;
-
-    /**
-     * Constructor to initialize raw Value.
-     *
-     * @param rawValue raw value
-     */
-    public PceccCapabilityTlv(final int rawValue) {
-        this.rawValue = rawValue;
-        this.isRawValueSet = true;
-
-        bLFlag = (rawValue & LFLAG_CHECK) == LFLAG_CHECK ? true : false;
-        bGFlag = (rawValue & GFLAG_CHECK) == GFLAG_CHECK ? true : false;
-    }
-
-    /**
-     * Constructor to initialize G-flag L-flag.
-     * @param bGFlag G-flag
-     * @param bLFlag L-flag
-     */
-    public PceccCapabilityTlv(boolean bGFlag, boolean bLFlag) {
-        this.bGFlag = bGFlag;
-        this.bLFlag = bLFlag;
-        this.rawValue = 0;
-        this.isRawValueSet = false;
-    }
-
-    /**
-     * Returns newly created PceccCapabilityTlv object.
-     *
-     * @param raw value
-     * @return object of Pcecc Capability Tlv
-     */
-    public static PceccCapabilityTlv of(final int raw) {
-        return new PceccCapabilityTlv(raw);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    /**
-     * Returns G-flag.
-     * @return bGFlag G-flag
-     */
-    public boolean getGFlag() {
-        return bGFlag;
-    }
-
-    /**
-     * Returns L-flag.
-     * @return bLFlag L-flag
-     */
-    public boolean getLFlag() {
-        return bLFlag;
-    }
-
-    /**
-     * Returns the raw value.
-     * @return rawValue Flags
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        if (isRawValueSet) {
-            return Objects.hash(rawValue);
-        } else {
-            return Objects.hash(bLFlag, bGFlag);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PceccCapabilityTlv) {
-            PceccCapabilityTlv other = (PceccCapabilityTlv) obj;
-            if (isRawValueSet) {
-                return Objects.equals(this.rawValue, other.rawValue);
-            } else {
-                return Objects.equals(this.bGFlag, other.bGFlag) && Objects.equals(this.bLFlag, other.bLFlag);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        int temp = 0;
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        if (isRawValueSet) {
-            c.writeInt(rawValue);
-        } else {
-            if (bGFlag) {
-                temp = temp | GFLAG_CHECK;
-            }
-            if (bLFlag) {
-                temp = temp | LFLAG_CHECK;
-            }
-            c.writeInt(temp);
-        }
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads channel buffer and returns object of PceccCapabilityTlv.
-     *
-     * @param c input channel buffer
-     * @return object of PceccCapabilityTlv
-     */
-    public static PceccCapabilityTlv read(ChannelBuffer c) {
-        return PceccCapabilityTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .toString();
-    }
-}
+package org.onosproject.pcepio.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides PceccCapabilityTlv.
+ */
+public class PceccCapabilityTlv implements PcepValueType {
+
+    /*          PCECC CAPABILITY TLV
+     * Reference : draft-zhao-pce-pcep-extension-for-pce-controller-01, section-7.1.1
+
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |               Type=32         |            Length=4           |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                             Flags                         |G|L|
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PceccCapabilityTlv.class);
+
+    public static final short TYPE = 32;
+    public static final short LENGTH = 4;
+    public static final int SET = 1;
+    public static final byte LFLAG_CHECK = 0x01;
+    public static final byte GFLAG_CHECK = 0x02;
+
+    private final boolean bGFlag;
+    private final boolean bLFlag;
+
+    private final int rawValue;
+    private final boolean isRawValueSet;
+
+    /**
+     * Constructor to initialize raw Value.
+     *
+     * @param rawValue raw value
+     */
+    public PceccCapabilityTlv(final int rawValue) {
+        this.rawValue = rawValue;
+        this.isRawValueSet = true;
+
+        bLFlag = (rawValue & LFLAG_CHECK) == LFLAG_CHECK ? true : false;
+        bGFlag = (rawValue & GFLAG_CHECK) == GFLAG_CHECK ? true : false;
+    }
+
+    /**
+     * Constructor to initialize G-flag L-flag.
+     * @param bGFlag G-flag
+     * @param bLFlag L-flag
+     */
+    public PceccCapabilityTlv(boolean bGFlag, boolean bLFlag) {
+        this.bGFlag = bGFlag;
+        this.bLFlag = bLFlag;
+        this.rawValue = 0;
+        this.isRawValueSet = false;
+    }
+
+    /**
+     * Returns newly created PceccCapabilityTlv object.
+     *
+     * @param raw value
+     * @return object of Pcecc Capability Tlv
+     */
+    public static PceccCapabilityTlv of(final int raw) {
+        return new PceccCapabilityTlv(raw);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    /**
+     * Returns G-flag.
+     * @return bGFlag G-flag
+     */
+    public boolean getGFlag() {
+        return bGFlag;
+    }
+
+    /**
+     * Returns L-flag.
+     * @return bLFlag L-flag
+     */
+    public boolean getLFlag() {
+        return bLFlag;
+    }
+
+    /**
+     * Returns the raw value.
+     * @return rawValue Flags
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        if (isRawValueSet) {
+            return Objects.hash(rawValue);
+        } else {
+            return Objects.hash(bLFlag, bGFlag);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PceccCapabilityTlv) {
+            PceccCapabilityTlv other = (PceccCapabilityTlv) obj;
+            if (isRawValueSet) {
+                return Objects.equals(this.rawValue, other.rawValue);
+            } else {
+                return Objects.equals(this.bGFlag, other.bGFlag) && Objects.equals(this.bLFlag, other.bLFlag);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        int temp = 0;
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        if (isRawValueSet) {
+            c.writeInt(rawValue);
+        } else {
+            if (bGFlag) {
+                temp = temp | GFLAG_CHECK;
+            }
+            if (bLFlag) {
+                temp = temp | LFLAG_CHECK;
+            }
+            c.writeInt(temp);
+        }
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads channel buffer and returns object of PceccCapabilityTlv.
+     *
+     * @param c input channel buffer
+     * @return object of PceccCapabilityTlv
+     */
+    public static PceccCapabilityTlv read(ChannelBuffer c) {
+        return PceccCapabilityTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java
index 4941b47..83a6210 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepErrorDetailInfo.java
@@ -1,83 +1,83 @@
-/*
- * 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.types;
-
-/**
- * Provide the PCEP Error Info Details.
- */
-public final class PcepErrorDetailInfo {
-
-    private PcepErrorDetailInfo() {
-    }
-
-    // Error Types
-    /**
-    Error-  Meaning                                           Reference:RFC 5440
-    Type
-    1     PCEP session establishment failure
-        Error-value=1: reception of an invalid Open message or a non Open message.
-        Error-value=2: no Open message received before the expiration of the OpenWait timer
-        Error-value=3: unacceptable and non-negotiable session characteristics
-        Error-value=4: unacceptable but negotiable session characteristics
-        Error-value=5: reception of a second Open message with still unacceptable session characteristics
-        Error-value=6: reception of a PCErr message proposing unacceptable session characteristics
-        Error-value=7: No Keepalive or PCErr message received before the expiration of the KeepWait timer
-        Error-value=8: PCEP version not supported
-    2     Capability not supported
-    3     Unknown Object
-         Error-value=1: Unrecognized object class
-         Error-value=2: Unrecognized object Type
-    4     Not supported object
-         Error-value=1: Not supported object class
-         Error-value=2: Not supported object Type
-    5     Policy violation
-         Error-value=1: C bit of the METRIC object set (request rejected)
-         Error-value=2: O bit of the RP object cleared (request rejected)
-    6     Mandatory Object missing
-         Error-value=1: RP object missing
-         Error-value=2: RRO missing for a re-optimization request (R bit of the RP object set)
-         Error-value=3: END-POINTS object missing
-    7     Synchronized path computation request missing
-    8     Unknown request reference
-    9     Attempt to establish a second PCEP session
-    10     Reception of an invalid object
-         Error-value=1: reception of an object with P flag not set although the P flag must be
-                        set according to this specification.
-     */
-    public static final byte ERROR_TYPE_1 = 1;
-    public static final byte ERROR_TYPE_2 = 2;
-    public static final byte ERROR_TYPE_3 = 3;
-    public static final byte ERROR_TYPE_4 = 4;
-    public static final byte ERROR_TYPE_5 = 5;
-    public static final byte ERROR_TYPE_6 = 6;
-    public static final byte ERROR_TYPE_7 = 7;
-    public static final byte ERROR_TYPE_8 = 8;
-    public static final byte ERROR_TYPE_9 = 9;
-    public static final byte ERROR_TYPE_10 = 10;
-
-    // Error Values
-    public static final byte ERROR_VALUE_1 = 1;
-    public static final byte ERROR_VALUE_2 = 2;
-    public static final byte ERROR_VALUE_3 = 3;
-    public static final byte ERROR_VALUE_4 = 4;
-    public static final byte ERROR_VALUE_5 = 5;
-    public static final byte ERROR_VALUE_6 = 6;
-    public static final byte ERROR_VALUE_7 = 7;
-    public static final byte ERROR_VALUE_8 = 8;
-    public static final byte ERROR_VALUE_9 = 9;
-    public static final byte ERROR_VALUE_10 = 10;
-}
+/*
+ * 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.types;
+
+/**
+ * Provide the PCEP Error Info Details.
+ */
+public final class PcepErrorDetailInfo {
+
+    private PcepErrorDetailInfo() {
+    }
+
+    // Error Types
+    /**
+    Error-  Meaning                                           Reference:RFC 5440
+    Type
+    1     PCEP session establishment failure
+        Error-value=1: reception of an invalid Open message or a non Open message.
+        Error-value=2: no Open message received before the expiration of the OpenWait timer
+        Error-value=3: unacceptable and non-negotiable session characteristics
+        Error-value=4: unacceptable but negotiable session characteristics
+        Error-value=5: reception of a second Open message with still unacceptable session characteristics
+        Error-value=6: reception of a PCErr message proposing unacceptable session characteristics
+        Error-value=7: No Keepalive or PCErr message received before the expiration of the KeepWait timer
+        Error-value=8: PCEP version not supported
+    2     Capability not supported
+    3     Unknown Object
+         Error-value=1: Unrecognized object class
+         Error-value=2: Unrecognized object Type
+    4     Not supported object
+         Error-value=1: Not supported object class
+         Error-value=2: Not supported object Type
+    5     Policy violation
+         Error-value=1: C bit of the METRIC object set (request rejected)
+         Error-value=2: O bit of the RP object cleared (request rejected)
+    6     Mandatory Object missing
+         Error-value=1: RP object missing
+         Error-value=2: RRO missing for a re-optimization request (R bit of the RP object set)
+         Error-value=3: END-POINTS object missing
+    7     Synchronized path computation request missing
+    8     Unknown request reference
+    9     Attempt to establish a second PCEP session
+    10     Reception of an invalid object
+         Error-value=1: reception of an object with P flag not set although the P flag must be
+                        set according to this specification.
+     */
+    public static final byte ERROR_TYPE_1 = 1;
+    public static final byte ERROR_TYPE_2 = 2;
+    public static final byte ERROR_TYPE_3 = 3;
+    public static final byte ERROR_TYPE_4 = 4;
+    public static final byte ERROR_TYPE_5 = 5;
+    public static final byte ERROR_TYPE_6 = 6;
+    public static final byte ERROR_TYPE_7 = 7;
+    public static final byte ERROR_TYPE_8 = 8;
+    public static final byte ERROR_TYPE_9 = 9;
+    public static final byte ERROR_TYPE_10 = 10;
+
+    // Error Values
+    public static final byte ERROR_VALUE_1 = 1;
+    public static final byte ERROR_VALUE_2 = 2;
+    public static final byte ERROR_VALUE_3 = 3;
+    public static final byte ERROR_VALUE_4 = 4;
+    public static final byte ERROR_VALUE_5 = 5;
+    public static final byte ERROR_VALUE_6 = 6;
+    public static final byte ERROR_VALUE_7 = 7;
+    public static final byte ERROR_VALUE_8 = 8;
+    public static final byte ERROR_VALUE_9 = 9;
+    public static final byte ERROR_VALUE_10 = 10;
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepLabelDbVerTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepLabelDbVerTlv.java
index f79cfc4..b37be99 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepLabelDbVerTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepLabelDbVerTlv.java
@@ -1,119 +1,119 @@
-package org.onosproject.pcepio.types;
-
-import java.util.Objects;
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides CEP LABEL DB VERSION TLV which contains LSP State DB Version  (32 Bit ).
- */
-public class PcepLabelDbVerTlv implements PcepValueType {
-
-    /*                  PCEP LABEL DB VERSION TLV format
-
-    Reference : draft-ietf-pce-stateful-sync-optimizations-02, section 3.3.1
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |           Type=23             |            Length=8           |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                      LSP State DB Version                     |
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(PcepLabelDbVerTlv.class);
-
-    public static final short TYPE = 34;
-    public static final short LENGTH = 8;
-    private final long rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue of Pcep Label Db Version Tlv
-     */
-    public PcepLabelDbVerTlv(final long rawValue) {
-        log.debug("PcepLabelDbVerTlv");
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created PcepLabelDbVerTlv object.
-     *
-     * @param raw LSP State DB Version
-     * @return object of PcepLabelDbVerTlv
-     */
-    public static PcepLabelDbVerTlv of(final long raw) {
-        return new PcepLabelDbVerTlv(raw);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    /**
-     * Returns LSP State DB Version.
-     * @return raw value
-     */
-    public long getLong() {
-        return rawValue;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PceccCapabilityTlv) {
-            PcepLabelDbVerTlv other = (PcepLabelDbVerTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeLong(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of PcepLabelDbVerTlv.
-     *
-     * @param c input channel buffer
-     * @return object of PcepLabelDbVerTlv
-     */
-    public static PcepLabelDbVerTlv read(ChannelBuffer c) {
-        return PcepLabelDbVerTlv.of(c.readLong());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .toString();
-    }
-}
+package org.onosproject.pcepio.types;
+
+import java.util.Objects;
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides CEP LABEL DB VERSION TLV which contains LSP State DB Version  (32 Bit ).
+ */
+public class PcepLabelDbVerTlv implements PcepValueType {
+
+    /*                  PCEP LABEL DB VERSION TLV format
+
+    Reference : draft-ietf-pce-stateful-sync-optimizations-02, section 3.3.1
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |           Type=23             |            Length=8           |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                      LSP State DB Version                     |
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(PcepLabelDbVerTlv.class);
+
+    public static final short TYPE = 34;
+    public static final short LENGTH = 8;
+    private final long rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue of Pcep Label Db Version Tlv
+     */
+    public PcepLabelDbVerTlv(final long rawValue) {
+        log.debug("PcepLabelDbVerTlv");
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created PcepLabelDbVerTlv object.
+     *
+     * @param raw LSP State DB Version
+     * @return object of PcepLabelDbVerTlv
+     */
+    public static PcepLabelDbVerTlv of(final long raw) {
+        return new PcepLabelDbVerTlv(raw);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    /**
+     * Returns LSP State DB Version.
+     * @return raw value
+     */
+    public long getLong() {
+        return rawValue;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PceccCapabilityTlv) {
+            PcepLabelDbVerTlv other = (PcepLabelDbVerTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeLong(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of PcepLabelDbVerTlv.
+     *
+     * @param c input channel buffer
+     * @return object of PcepLabelDbVerTlv
+     */
+    public static PcepLabelDbVerTlv read(ChannelBuffer c) {
+        return PcepLabelDbVerTlv.of(c.readLong());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4Adjacency.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4Adjacency.java
index 5108f9c..1ed0ab1 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4Adjacency.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4Adjacency.java
@@ -1,107 +1,107 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepNai;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Nai Ipv4 Adjacency.
- */
-public class PcepNaiIpv4Adjacency implements PcepNai {
-
-    public static final byte ST_TYPE = 0x03;
-    private final int localIpv4Addr;
-    private final int remoteIpv4Addr;
-
-    /**
-     * Constructor to initialize variables.
-     *
-     * @param localIpv4 local ipv4 address
-     * @param remoteIpv4 remote ipv4 address
-     */
-    public PcepNaiIpv4Adjacency(int localIpv4, int remoteIpv4) {
-        this.localIpv4Addr = localIpv4;
-        this.remoteIpv4Addr = remoteIpv4;
-    }
-
-    /**
-     * Returns Object of Pcep nai Ipv4 Adjacency.
-     *
-     * @param localIpv4Addr local ipv4 address
-     * @param remoteIpv4Addr remote ipv4 address
-     * @return Object of Pcep nai Ipv4 Adjacency
-     */
-    public static PcepNaiIpv4Adjacency of(int localIpv4Addr, int remoteIpv4Addr) {
-        return new PcepNaiIpv4Adjacency(localIpv4Addr, remoteIpv4Addr);
-    }
-
-    @Override
-    public byte getType() {
-        return ST_TYPE;
-    }
-
-    @Override
-    public int write(ChannelBuffer bb) {
-        int iLenStartIndex = bb.writerIndex();
-        bb.writeInt(localIpv4Addr);
-        bb.writeInt(remoteIpv4Addr);
-        return bb.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of PcepNAIIpv4AdjacencyVer1.
-     *
-     * @param cb of channel buffer
-     * @return object of PcepNAIIpv4Adjacency
-     */
-    public static PcepNaiIpv4Adjacency read(ChannelBuffer cb) {
-        int localIpv4 = cb.readInt();
-        int remoteIpv4 = cb.readInt();
-        return new PcepNaiIpv4Adjacency(localIpv4, remoteIpv4);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(localIpv4Addr, remoteIpv4Addr);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PcepNaiIpv4Adjacency) {
-            PcepNaiIpv4Adjacency other = (PcepNaiIpv4Adjacency) obj;
-            return Objects.equals(this.localIpv4Addr, other.localIpv4Addr)
-                    && Objects.equals(this.remoteIpv4Addr, other.remoteIpv4Addr);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("localIPv4Address", localIpv4Addr)
-                .add("remoteIPv4Address", remoteIpv4Addr)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepNai;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Nai Ipv4 Adjacency.
+ */
+public class PcepNaiIpv4Adjacency implements PcepNai {
+
+    public static final byte ST_TYPE = 0x03;
+    private final int localIpv4Addr;
+    private final int remoteIpv4Addr;
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param localIpv4 local ipv4 address
+     * @param remoteIpv4 remote ipv4 address
+     */
+    public PcepNaiIpv4Adjacency(int localIpv4, int remoteIpv4) {
+        this.localIpv4Addr = localIpv4;
+        this.remoteIpv4Addr = remoteIpv4;
+    }
+
+    /**
+     * Returns Object of Pcep nai Ipv4 Adjacency.
+     *
+     * @param localIpv4Addr local ipv4 address
+     * @param remoteIpv4Addr remote ipv4 address
+     * @return Object of Pcep nai Ipv4 Adjacency
+     */
+    public static PcepNaiIpv4Adjacency of(int localIpv4Addr, int remoteIpv4Addr) {
+        return new PcepNaiIpv4Adjacency(localIpv4Addr, remoteIpv4Addr);
+    }
+
+    @Override
+    public byte getType() {
+        return ST_TYPE;
+    }
+
+    @Override
+    public int write(ChannelBuffer bb) {
+        int iLenStartIndex = bb.writerIndex();
+        bb.writeInt(localIpv4Addr);
+        bb.writeInt(remoteIpv4Addr);
+        return bb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of PcepNAIIpv4AdjacencyVer1.
+     *
+     * @param cb of channel buffer
+     * @return object of PcepNAIIpv4Adjacency
+     */
+    public static PcepNaiIpv4Adjacency read(ChannelBuffer cb) {
+        int localIpv4 = cb.readInt();
+        int remoteIpv4 = cb.readInt();
+        return new PcepNaiIpv4Adjacency(localIpv4, remoteIpv4);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(localIpv4Addr, remoteIpv4Addr);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PcepNaiIpv4Adjacency) {
+            PcepNaiIpv4Adjacency other = (PcepNaiIpv4Adjacency) obj;
+            return Objects.equals(this.localIpv4Addr, other.localIpv4Addr)
+                    && Objects.equals(this.remoteIpv4Addr, other.remoteIpv4Addr);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("localIPv4Address", localIpv4Addr)
+                .add("remoteIPv4Address", remoteIpv4Addr)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4NodeId.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4NodeId.java
index 4b989b7..aecace0 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4NodeId.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv4NodeId.java
@@ -1,97 +1,97 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepNai;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Nai Ipv4 Node Id.
- */
-public class PcepNaiIpv4NodeId implements PcepNai {
-
-    public static final byte ST_TYPE = 0x01;
-
-    private final int ipv4NodeId;
-
-    /**
-     * Constructor to initialize ipv4NodeId.
-     *
-     * @param value ipv4 node id
-     */
-    public PcepNaiIpv4NodeId(int value) {
-        this.ipv4NodeId = value;
-    }
-
-    /**
-     * Returns an object of PcepNaiIpv4NodeId.
-     *
-     * @param value ipv4 node id
-     * @return object of PcepNaiIpv4NodeId
-     */
-    public static PcepNaiIpv4NodeId of(int value) {
-        return new PcepNaiIpv4NodeId(value);
-    }
-
-    @Override
-    public byte getType() {
-        return ST_TYPE;
-    }
-
-    @Override
-    public int write(ChannelBuffer bb) {
-        int iLenStartIndex = bb.writerIndex();
-        bb.writeInt(ipv4NodeId);
-        return bb.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads from the channel buffer and returns object of PcepNAIIpv4NodeIdVer1.
-     *
-     * @param bb of channel buffer.
-     * @return object of PcepNAIIpv4NodeIdVer1
-     */
-    public static PcepNaiIpv4NodeId read(ChannelBuffer bb) {
-        return new PcepNaiIpv4NodeId(bb.readInt());
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(ipv4NodeId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PcepNaiIpv4NodeId) {
-            PcepNaiIpv4NodeId other = (PcepNaiIpv4NodeId) obj;
-            return Objects.equals(this.ipv4NodeId, other.ipv4NodeId);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("IPv4NodeId", ipv4NodeId).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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepNai;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Nai Ipv4 Node Id.
+ */
+public class PcepNaiIpv4NodeId implements PcepNai {
+
+    public static final byte ST_TYPE = 0x01;
+
+    private final int ipv4NodeId;
+
+    /**
+     * Constructor to initialize ipv4NodeId.
+     *
+     * @param value ipv4 node id
+     */
+    public PcepNaiIpv4NodeId(int value) {
+        this.ipv4NodeId = value;
+    }
+
+    /**
+     * Returns an object of PcepNaiIpv4NodeId.
+     *
+     * @param value ipv4 node id
+     * @return object of PcepNaiIpv4NodeId
+     */
+    public static PcepNaiIpv4NodeId of(int value) {
+        return new PcepNaiIpv4NodeId(value);
+    }
+
+    @Override
+    public byte getType() {
+        return ST_TYPE;
+    }
+
+    @Override
+    public int write(ChannelBuffer bb) {
+        int iLenStartIndex = bb.writerIndex();
+        bb.writeInt(ipv4NodeId);
+        return bb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads from the channel buffer and returns object of PcepNAIIpv4NodeIdVer1.
+     *
+     * @param bb of channel buffer.
+     * @return object of PcepNAIIpv4NodeIdVer1
+     */
+    public static PcepNaiIpv4NodeId read(ChannelBuffer bb) {
+        return new PcepNaiIpv4NodeId(bb.readInt());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipv4NodeId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PcepNaiIpv4NodeId) {
+            PcepNaiIpv4NodeId other = (PcepNaiIpv4NodeId) obj;
+            return Objects.equals(this.ipv4NodeId, other.ipv4NodeId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("IPv4NodeId", ipv4NodeId).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6Adjacency.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6Adjacency.java
index e0761be..3a177d9 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6Adjacency.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6Adjacency.java
@@ -1,113 +1,113 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepNai;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Nai Ipv6 Adjacency.
- */
-public class PcepNaiIpv6Adjacency implements PcepNai {
-
-    public static final byte ST_TYPE = 0x04;
-    public static final byte IPV6_LEN = 0x10;
-
-    private final byte[] localIpv6Addr;
-    private final byte[] remoteIpv6Addr;
-
-    /**
-     * Constructor to initialize local ipv6 and remote ipv6.
-     *
-     * @param localIpv6 local ipv6 address
-     * @param remoteIpv6 remote ipv6 address
-     */
-    public PcepNaiIpv6Adjacency(byte[] localIpv6, byte[] remoteIpv6) {
-        this.localIpv6Addr = localIpv6;
-        this.remoteIpv6Addr = remoteIpv6;
-    }
-
-    @Override
-    public byte getType() {
-        return ST_TYPE;
-    }
-
-    @Override
-    public int write(ChannelBuffer bb) {
-        int iLenStartIndex = bb.writerIndex();
-        bb.writeBytes(localIpv6Addr);
-        bb.writeBytes(remoteIpv6Addr);
-        return bb.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of PcepNAIIpv6AdjacencyVer1.
-     *
-     * @param bb of type channel buffer
-     * @return object of PcepNAIIpv6AdjacencyVer1
-     */
-    public static PcepNaiIpv6Adjacency read(ChannelBuffer bb) {
-        byte[] localIpv6 = new byte[IPV6_LEN];
-        bb.readBytes(localIpv6, 0, IPV6_LEN);
-        byte[] remoteIpv6 = new byte[IPV6_LEN];
-        bb.readBytes(remoteIpv6, 0, IPV6_LEN);
-        return new PcepNaiIpv6Adjacency(localIpv6, remoteIpv6);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(localIpv6Addr, remoteIpv6Addr);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PcepNaiIpv6Adjacency) {
-            PcepNaiIpv6Adjacency other = (PcepNaiIpv6Adjacency) obj;
-            return Objects.equals(this.localIpv6Addr, other.localIpv6Addr)
-                    && Objects.equals(this.remoteIpv6Addr, other.remoteIpv6Addr);
-        }
-        return false;
-    }
-
-    /**
-     * Creates object of PcepNaiIpv6Adjacency with local ipv6 address and remote ipv6 address.
-     *
-     * @param localIpv6Addr local ipv6 address
-     * @param remoteIpv6Addr remote ipv6 address
-     * @return object of PcepNaiIpv6Adjacency
-     */
-
-    public static PcepNaiIpv6Adjacency of(final byte[] localIpv6Addr, final byte[] remoteIpv6Addr) {
-        return new PcepNaiIpv6Adjacency(localIpv6Addr, remoteIpv6Addr);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("localIPV6Address", localIpv6Addr)
-                .add("remoteIPV6Address", remoteIpv6Addr)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepNai;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Nai Ipv6 Adjacency.
+ */
+public class PcepNaiIpv6Adjacency implements PcepNai {
+
+    public static final byte ST_TYPE = 0x04;
+    public static final byte IPV6_LEN = 0x10;
+
+    private final byte[] localIpv6Addr;
+    private final byte[] remoteIpv6Addr;
+
+    /**
+     * Constructor to initialize local ipv6 and remote ipv6.
+     *
+     * @param localIpv6 local ipv6 address
+     * @param remoteIpv6 remote ipv6 address
+     */
+    public PcepNaiIpv6Adjacency(byte[] localIpv6, byte[] remoteIpv6) {
+        this.localIpv6Addr = localIpv6;
+        this.remoteIpv6Addr = remoteIpv6;
+    }
+
+    @Override
+    public byte getType() {
+        return ST_TYPE;
+    }
+
+    @Override
+    public int write(ChannelBuffer bb) {
+        int iLenStartIndex = bb.writerIndex();
+        bb.writeBytes(localIpv6Addr);
+        bb.writeBytes(remoteIpv6Addr);
+        return bb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of PcepNAIIpv6AdjacencyVer1.
+     *
+     * @param bb of type channel buffer
+     * @return object of PcepNAIIpv6AdjacencyVer1
+     */
+    public static PcepNaiIpv6Adjacency read(ChannelBuffer bb) {
+        byte[] localIpv6 = new byte[IPV6_LEN];
+        bb.readBytes(localIpv6, 0, IPV6_LEN);
+        byte[] remoteIpv6 = new byte[IPV6_LEN];
+        bb.readBytes(remoteIpv6, 0, IPV6_LEN);
+        return new PcepNaiIpv6Adjacency(localIpv6, remoteIpv6);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(localIpv6Addr, remoteIpv6Addr);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PcepNaiIpv6Adjacency) {
+            PcepNaiIpv6Adjacency other = (PcepNaiIpv6Adjacency) obj;
+            return Objects.equals(this.localIpv6Addr, other.localIpv6Addr)
+                    && Objects.equals(this.remoteIpv6Addr, other.remoteIpv6Addr);
+        }
+        return false;
+    }
+
+    /**
+     * Creates object of PcepNaiIpv6Adjacency with local ipv6 address and remote ipv6 address.
+     *
+     * @param localIpv6Addr local ipv6 address
+     * @param remoteIpv6Addr remote ipv6 address
+     * @return object of PcepNaiIpv6Adjacency
+     */
+
+    public static PcepNaiIpv6Adjacency of(final byte[] localIpv6Addr, final byte[] remoteIpv6Addr) {
+        return new PcepNaiIpv6Adjacency(localIpv6Addr, remoteIpv6Addr);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("localIPV6Address", localIpv6Addr)
+                .add("remoteIPV6Address", remoteIpv6Addr)
+                .toString();
+    }
+
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6NodeId.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6NodeId.java
index e22ef94..9d4be45 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6NodeId.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiIpv6NodeId.java
@@ -1,100 +1,100 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepNai;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Nai Ipv6 Node Id.
- */
-public class PcepNaiIpv6NodeId implements PcepNai {
-
-    public static final byte ST_TYPE = 0x02;
-    public static final byte IPV6_LEN = 0x10;
-
-    private final byte[] ipv6NodeId;
-
-    /**
-     * Constructor to initialize ipv6NodeId.
-     *
-     * @param value ipv6 node id
-     */
-    public PcepNaiIpv6NodeId(byte[] value) {
-        this.ipv6NodeId = value;
-    }
-
-    /**
-     * Return object of Pcep Nai Ipv6 Node ID.
-     *
-     * @param ipv6NodeId Ipv6 node ID.
-     * @return object of Pcep Nai Ipv6 Node ID.
-     */
-    public static PcepNaiIpv6NodeId of(byte[] ipv6NodeId) {
-        return new PcepNaiIpv6NodeId(ipv6NodeId);
-    }
-
-    @Override
-    public byte getType() {
-        return ST_TYPE;
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) {
-        int iLenStartIndex = cb.writerIndex();
-        cb.writeBytes(ipv6NodeId);
-        return cb.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads from the channel buffer and returns object of PcepNAIIpv6NodeId.
-     *
-     * @param cb of type channel buffer.
-     * @return object of PcepNAIIpv6NodeId
-     */
-    public static PcepNaiIpv6NodeId read(ChannelBuffer cb) {
-        byte[] ipv6NodeId = new byte[IPV6_LEN];
-        cb.readBytes(ipv6NodeId, 0, IPV6_LEN);
-        return new PcepNaiIpv6NodeId(ipv6NodeId);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(ipv6NodeId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PcepNaiIpv6NodeId) {
-            PcepNaiIpv6NodeId other = (PcepNaiIpv6NodeId) obj;
-            return Objects.equals(this.ipv6NodeId, other.ipv6NodeId);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("IPV6NodeID", ipv6NodeId).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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepNai;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Nai Ipv6 Node Id.
+ */
+public class PcepNaiIpv6NodeId implements PcepNai {
+
+    public static final byte ST_TYPE = 0x02;
+    public static final byte IPV6_LEN = 0x10;
+
+    private final byte[] ipv6NodeId;
+
+    /**
+     * Constructor to initialize ipv6NodeId.
+     *
+     * @param value ipv6 node id
+     */
+    public PcepNaiIpv6NodeId(byte[] value) {
+        this.ipv6NodeId = value;
+    }
+
+    /**
+     * Return object of Pcep Nai Ipv6 Node ID.
+     *
+     * @param ipv6NodeId Ipv6 node ID.
+     * @return object of Pcep Nai Ipv6 Node ID.
+     */
+    public static PcepNaiIpv6NodeId of(byte[] ipv6NodeId) {
+        return new PcepNaiIpv6NodeId(ipv6NodeId);
+    }
+
+    @Override
+    public byte getType() {
+        return ST_TYPE;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        int iLenStartIndex = cb.writerIndex();
+        cb.writeBytes(ipv6NodeId);
+        return cb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads from the channel buffer and returns object of PcepNAIIpv6NodeId.
+     *
+     * @param cb of type channel buffer.
+     * @return object of PcepNAIIpv6NodeId
+     */
+    public static PcepNaiIpv6NodeId read(ChannelBuffer cb) {
+        byte[] ipv6NodeId = new byte[IPV6_LEN];
+        cb.readBytes(ipv6NodeId, 0, IPV6_LEN);
+        return new PcepNaiIpv6NodeId(ipv6NodeId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipv6NodeId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PcepNaiIpv6NodeId) {
+            PcepNaiIpv6NodeId other = (PcepNaiIpv6NodeId) obj;
+            return Objects.equals(this.ipv6NodeId, other.ipv6NodeId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("IPV6NodeID", ipv6NodeId).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiUnnumberedAdjacencyIpv4.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiUnnumberedAdjacencyIpv4.java
index 84106de..5342f41 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiUnnumberedAdjacencyIpv4.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepNaiUnnumberedAdjacencyIpv4.java
@@ -1,116 +1,116 @@
-package org.onosproject.pcepio.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepNai;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Nai Unnumbered Adjacency Ipv4.
- */
-public class PcepNaiUnnumberedAdjacencyIpv4 implements PcepNai {
-    /**
-     * draft-ietf-pce-segment-routing-03 section    5.3.2.
-     */
-    public static final byte ST_TYPE = 0x05;
-
-    private final int localNodeId;
-    private final int localInterfaceId;
-    private final int remoteNodeId;
-    private final int remoteInterfaceId;
-
-    /**
-     * Constructor to initialize all the member variables.
-     *
-     * @param localNodeId local node id
-     * @param localInterfaceId local interface id
-     * @param remoteNodeId remote node id
-     * @param remoteInterfaceId remote interface id
-     */
-    public PcepNaiUnnumberedAdjacencyIpv4(int localNodeId, int localInterfaceId, int remoteNodeId,
-            int remoteInterfaceId) {
-        this.localNodeId = localNodeId;
-        this.localInterfaceId = localInterfaceId;
-        this.remoteNodeId = remoteNodeId;
-        this.remoteInterfaceId = remoteInterfaceId;
-    }
-
-    /**
-     * Returns PCEP Nai Unnumbered Adjacency Ipv4 object.
-     *
-     * @param localNodeId local node id
-     * @param localInterfaceId local interface if
-     * @param remoteNodeId remote node id
-     * @param remoteInterfaceId remote interface id
-     * @return PCEP Nai Unnumbered Adjacency Ipv4 object
-     */
-    public static PcepNaiUnnumberedAdjacencyIpv4 of(int localNodeId, int localInterfaceId, int remoteNodeId,
-            int remoteInterfaceId) {
-        return new PcepNaiUnnumberedAdjacencyIpv4(localNodeId, localInterfaceId, remoteNodeId, remoteInterfaceId);
-    }
-
-    @Override
-    public byte getType() {
-        return ST_TYPE;
-    }
-
-    @Override
-    public int write(ChannelBuffer bb) {
-        int iLenStartIndex = bb.writerIndex();
-        bb.writeInt(localNodeId);
-        bb.writeInt(localInterfaceId);
-        bb.writeInt(remoteNodeId);
-        bb.writeInt(remoteInterfaceId);
-        return bb.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads from channel buffer and return object of PcepNAIUnnumberedAdjacencyIpv4.
-     *
-     * @param bb of type channel buffer
-     * @return object of PcepNAIUnnumberedAdjacencyIpv4
-     */
-    public static PcepNaiUnnumberedAdjacencyIpv4 read(ChannelBuffer bb) {
-        int localNodeId;
-        int localInterfaceId;
-        int remoteNodeId;
-        int remoteInterfaceId;
-        localNodeId = bb.readInt();
-        localInterfaceId = bb.readInt();
-        remoteNodeId = bb.readInt();
-        remoteInterfaceId = bb.readInt();
-        return new PcepNaiUnnumberedAdjacencyIpv4(localNodeId, localInterfaceId, remoteNodeId, remoteInterfaceId);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(localNodeId, localInterfaceId, remoteNodeId, remoteInterfaceId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PcepNaiUnnumberedAdjacencyIpv4) {
-            PcepNaiUnnumberedAdjacencyIpv4 other = (PcepNaiUnnumberedAdjacencyIpv4) obj;
-            return Objects.equals(this.localNodeId, other.localNodeId)
-                    && Objects.equals(this.localInterfaceId, other.localInterfaceId)
-                    && Objects.equals(this.remoteNodeId, other.remoteNodeId)
-                    && Objects.equals(this.remoteInterfaceId, other.remoteInterfaceId);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("localNodeId", localNodeId)
-                .add("localInterfaceId", localInterfaceId)
-                .add("remoteNodeId", remoteNodeId)
-                .add("remoteInterfaceId:", remoteInterfaceId)
-                .toString();
-    }
-}
+package org.onosproject.pcepio.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepNai;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Nai Unnumbered Adjacency Ipv4.
+ */
+public class PcepNaiUnnumberedAdjacencyIpv4 implements PcepNai {
+    /**
+     * draft-ietf-pce-segment-routing-03 section    5.3.2.
+     */
+    public static final byte ST_TYPE = 0x05;
+
+    private final int localNodeId;
+    private final int localInterfaceId;
+    private final int remoteNodeId;
+    private final int remoteInterfaceId;
+
+    /**
+     * Constructor to initialize all the member variables.
+     *
+     * @param localNodeId local node id
+     * @param localInterfaceId local interface id
+     * @param remoteNodeId remote node id
+     * @param remoteInterfaceId remote interface id
+     */
+    public PcepNaiUnnumberedAdjacencyIpv4(int localNodeId, int localInterfaceId, int remoteNodeId,
+            int remoteInterfaceId) {
+        this.localNodeId = localNodeId;
+        this.localInterfaceId = localInterfaceId;
+        this.remoteNodeId = remoteNodeId;
+        this.remoteInterfaceId = remoteInterfaceId;
+    }
+
+    /**
+     * Returns PCEP Nai Unnumbered Adjacency Ipv4 object.
+     *
+     * @param localNodeId local node id
+     * @param localInterfaceId local interface if
+     * @param remoteNodeId remote node id
+     * @param remoteInterfaceId remote interface id
+     * @return PCEP Nai Unnumbered Adjacency Ipv4 object
+     */
+    public static PcepNaiUnnumberedAdjacencyIpv4 of(int localNodeId, int localInterfaceId, int remoteNodeId,
+            int remoteInterfaceId) {
+        return new PcepNaiUnnumberedAdjacencyIpv4(localNodeId, localInterfaceId, remoteNodeId, remoteInterfaceId);
+    }
+
+    @Override
+    public byte getType() {
+        return ST_TYPE;
+    }
+
+    @Override
+    public int write(ChannelBuffer bb) {
+        int iLenStartIndex = bb.writerIndex();
+        bb.writeInt(localNodeId);
+        bb.writeInt(localInterfaceId);
+        bb.writeInt(remoteNodeId);
+        bb.writeInt(remoteInterfaceId);
+        return bb.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads from channel buffer and return object of PcepNAIUnnumberedAdjacencyIpv4.
+     *
+     * @param bb of type channel buffer
+     * @return object of PcepNAIUnnumberedAdjacencyIpv4
+     */
+    public static PcepNaiUnnumberedAdjacencyIpv4 read(ChannelBuffer bb) {
+        int localNodeId;
+        int localInterfaceId;
+        int remoteNodeId;
+        int remoteInterfaceId;
+        localNodeId = bb.readInt();
+        localInterfaceId = bb.readInt();
+        remoteNodeId = bb.readInt();
+        remoteInterfaceId = bb.readInt();
+        return new PcepNaiUnnumberedAdjacencyIpv4(localNodeId, localInterfaceId, remoteNodeId, remoteInterfaceId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(localNodeId, localInterfaceId, remoteNodeId, remoteInterfaceId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PcepNaiUnnumberedAdjacencyIpv4) {
+            PcepNaiUnnumberedAdjacencyIpv4 other = (PcepNaiUnnumberedAdjacencyIpv4) obj;
+            return Objects.equals(this.localNodeId, other.localNodeId)
+                    && Objects.equals(this.localInterfaceId, other.localInterfaceId)
+                    && Objects.equals(this.remoteNodeId, other.remoteNodeId)
+                    && Objects.equals(this.remoteInterfaceId, other.remoteInterfaceId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("localNodeId", localNodeId)
+                .add("localInterfaceId", localInterfaceId)
+                .add("remoteNodeId", remoteNodeId)
+                .add("remoteInterfaceId:", remoteInterfaceId)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpErrorSpec.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpErrorSpec.java
index bc416cb..8d3c67a 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpErrorSpec.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpErrorSpec.java
@@ -1,46 +1,46 @@
-/*
- * 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.types;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-
-/**
- * Abstraction of an entity which provides PCPE RSVP error spec.
- */
-public interface PcepRsvpErrorSpec extends PcepValueType {
-
-    /**
-     *  To write the object information to channelBuffer.
-     *
-     *  @param cb of type channel buffer
-     */
-    @Override
-    int write(ChannelBuffer cb);
-
-    /**
-     * Returns class number.
-     *
-     * @return class number
-     */
-    byte getClassNum();
-
-    /**
-     * Returns class type.
-     *
-     * @return class type
-     */
-    byte getClassType();
-}
+/*
+ * 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.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+
+/**
+ * Abstraction of an entity which provides PCPE RSVP error spec.
+ */
+public interface PcepRsvpErrorSpec extends PcepValueType {
+
+    /**
+     *  To write the object information to channelBuffer.
+     *
+     *  @param cb of type channel buffer
+     */
+    @Override
+    int write(ChannelBuffer cb);
+
+    /**
+     * Returns class number.
+     *
+     * @return class number
+     */
+    byte getClassNum();
+
+    /**
+     * Returns class type.
+     *
+     * @return class type
+     */
+    byte getClassType();
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv4ErrorSpec.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv4ErrorSpec.java
index 870179d..3620578 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv4ErrorSpec.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv4ErrorSpec.java
@@ -1,160 +1,160 @@
-/*
- * 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.types;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Rsvp Ipv4 Error Spec.
- */
-public class PcepRsvpIpv4ErrorSpec implements PcepRsvpErrorSpec {
-
-    /*
-       RSVP error spec object header.
-        0             1              2             3
-    +-------------+-------------+-------------+-------------+
-    |       Length (bytes)      |  Class-Num  |   C-Type    |
-    +-------------+-------------+-------------+-------------+
-    |                                                       |
-    //                  (Object contents)                   //
-    |                                                       |
-    +-------------+-------------+-------------+-------------+
-
-    Ref :  ERROR_SPEC @ RFC2205
-
-    IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
-    +-------------+-------------+-------------+-------------+
-    |            IPv4 Error Node Address (4 bytes)          |
-    +-------------+-------------+-------------+-------------+
-    |    Flags    |  Error Code |        Error Value        |
-    +-------------+-------------+-------------+-------------+
-
-     */
-
-    PcepRsvpSpecObjHeader objHeader;
-    public static final byte CLASS_NUM = 0x06;
-    public static final byte CLASS_TYPE = 0x01;
-    public static final byte CLASS_LENGTH = 0x0c;
-    private int ipv4Addr;
-    private byte flags;
-    private byte errCode;
-    private short errValue;
-
-    /**
-     * Constructor to initialize obj header, ipv4 addr, flags, err code and err value.
-     *
-     * @param objHeader rsvp ipv4 error spec object header
-     * @param ipv4Addr ipv4 address
-     * @param flags flags value
-     * @param errCode error code value
-     * @param errValue error value
-     */
-    public PcepRsvpIpv4ErrorSpec(PcepRsvpSpecObjHeader objHeader, int ipv4Addr, byte flags, byte errCode,
-            short errValue) {
-        this.objHeader = objHeader;
-        this.ipv4Addr = ipv4Addr;
-        this.flags = flags;
-        this.errCode = errCode;
-        this.errValue = errValue;
-    }
-
-    /**
-     * Constructor to initialize ipv4 address, flags, err code and err value.
-     *
-     * @param ipv4Addr ipv4 address
-     * @param flags flags value
-     * @param errCode error code
-     * @param errValue error value
-     */
-    public PcepRsvpIpv4ErrorSpec(int ipv4Addr, byte flags, byte errCode, short errValue) {
-        this.objHeader = new PcepRsvpSpecObjHeader(CLASS_LENGTH, CLASS_NUM, CLASS_TYPE);
-        this.ipv4Addr = ipv4Addr;
-        this.flags = flags;
-        this.errCode = errCode;
-        this.errValue = errValue;
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) {
-        int objLenIndex = objHeader.write(cb);
-        cb.writeInt(ipv4Addr);
-        cb.writeByte(flags);
-        cb.writeByte(errCode);
-        cb.writeShort(errValue);
-        short objLen = (short) (cb.writerIndex() - objLenIndex);
-        cb.setShort(objLenIndex, objLen);
-        return objLen;
-    }
-
-    /**
-     * Reads PCPE RSVP error spec from channel buffer and returns PCEP rsvp IPv4 error spec object.
-     *
-     * @param cb channel buffer
-     * @return PCEP rsvp IPv4 error spec object
-     */
-    public static PcepRsvpErrorSpec read(ChannelBuffer cb) {
-        PcepRsvpSpecObjHeader objHeader;
-        int ipv4Addr;
-        byte flags;
-        byte errCode;
-        short errValue;
-
-        objHeader = PcepRsvpSpecObjHeader.read(cb);
-        ipv4Addr = cb.readInt();
-        flags = cb.readByte();
-        errCode = cb.readByte();
-        errValue = cb.readShort();
-        return new PcepRsvpIpv4ErrorSpec(objHeader, ipv4Addr, flags, errCode, errValue);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return StatefulRsvpErrorSpecTlv.TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return CLASS_LENGTH;
-    }
-
-    @Override
-    public byte getClassNum() {
-        return CLASS_NUM;
-    }
-
-    @Override
-    public byte getClassType() {
-        return CLASS_TYPE;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("IPv4Address:", ipv4Addr)
-                .add("flags:", flags)
-                .add("errorCode:", errCode)
-                .add("errorValue:", errValue)
-                .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.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Rsvp Ipv4 Error Spec.
+ */
+public class PcepRsvpIpv4ErrorSpec implements PcepRsvpErrorSpec {
+
+    /*
+       RSVP error spec object header.
+        0             1              2             3
+    +-------------+-------------+-------------+-------------+
+    |       Length (bytes)      |  Class-Num  |   C-Type    |
+    +-------------+-------------+-------------+-------------+
+    |                                                       |
+    //                  (Object contents)                   //
+    |                                                       |
+    +-------------+-------------+-------------+-------------+
+
+    Ref :  ERROR_SPEC @ RFC2205
+
+    IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
+    +-------------+-------------+-------------+-------------+
+    |            IPv4 Error Node Address (4 bytes)          |
+    +-------------+-------------+-------------+-------------+
+    |    Flags    |  Error Code |        Error Value        |
+    +-------------+-------------+-------------+-------------+
+
+     */
+
+    PcepRsvpSpecObjHeader objHeader;
+    public static final byte CLASS_NUM = 0x06;
+    public static final byte CLASS_TYPE = 0x01;
+    public static final byte CLASS_LENGTH = 0x0c;
+    private int ipv4Addr;
+    private byte flags;
+    private byte errCode;
+    private short errValue;
+
+    /**
+     * Constructor to initialize obj header, ipv4 addr, flags, err code and err value.
+     *
+     * @param objHeader rsvp ipv4 error spec object header
+     * @param ipv4Addr ipv4 address
+     * @param flags flags value
+     * @param errCode error code value
+     * @param errValue error value
+     */
+    public PcepRsvpIpv4ErrorSpec(PcepRsvpSpecObjHeader objHeader, int ipv4Addr, byte flags, byte errCode,
+            short errValue) {
+        this.objHeader = objHeader;
+        this.ipv4Addr = ipv4Addr;
+        this.flags = flags;
+        this.errCode = errCode;
+        this.errValue = errValue;
+    }
+
+    /**
+     * Constructor to initialize ipv4 address, flags, err code and err value.
+     *
+     * @param ipv4Addr ipv4 address
+     * @param flags flags value
+     * @param errCode error code
+     * @param errValue error value
+     */
+    public PcepRsvpIpv4ErrorSpec(int ipv4Addr, byte flags, byte errCode, short errValue) {
+        this.objHeader = new PcepRsvpSpecObjHeader(CLASS_LENGTH, CLASS_NUM, CLASS_TYPE);
+        this.ipv4Addr = ipv4Addr;
+        this.flags = flags;
+        this.errCode = errCode;
+        this.errValue = errValue;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        int objLenIndex = objHeader.write(cb);
+        cb.writeInt(ipv4Addr);
+        cb.writeByte(flags);
+        cb.writeByte(errCode);
+        cb.writeShort(errValue);
+        short objLen = (short) (cb.writerIndex() - objLenIndex);
+        cb.setShort(objLenIndex, objLen);
+        return objLen;
+    }
+
+    /**
+     * Reads PCPE RSVP error spec from channel buffer and returns PCEP rsvp IPv4 error spec object.
+     *
+     * @param cb channel buffer
+     * @return PCEP rsvp IPv4 error spec object
+     */
+    public static PcepRsvpErrorSpec read(ChannelBuffer cb) {
+        PcepRsvpSpecObjHeader objHeader;
+        int ipv4Addr;
+        byte flags;
+        byte errCode;
+        short errValue;
+
+        objHeader = PcepRsvpSpecObjHeader.read(cb);
+        ipv4Addr = cb.readInt();
+        flags = cb.readByte();
+        errCode = cb.readByte();
+        errValue = cb.readShort();
+        return new PcepRsvpIpv4ErrorSpec(objHeader, ipv4Addr, flags, errCode, errValue);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return StatefulRsvpErrorSpecTlv.TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return CLASS_LENGTH;
+    }
+
+    @Override
+    public byte getClassNum() {
+        return CLASS_NUM;
+    }
+
+    @Override
+    public byte getClassType() {
+        return CLASS_TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("IPv4Address:", ipv4Addr)
+                .add("flags:", flags)
+                .add("errorCode:", errCode)
+                .add("errorValue:", errValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv6ErrorSpec.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv6ErrorSpec.java
index 745d4fd..d1e52f9 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv6ErrorSpec.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpIpv6ErrorSpec.java
@@ -1,150 +1,150 @@
-package org.onosproject.pcepio.types;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Rsvp Ipv6 Error Spec.
- */
-public class PcepRsvpIpv6ErrorSpec implements PcepRsvpErrorSpec {
-
-    /*
-        0             1              2             3
-    +-------------+-------------+-------------+-------------+
-    |       Length (bytes)      |  Class-Num  |   C-Type    |
-    +-------------+-------------+-------------+-------------+
-    |                                                       |
-    //                  (Object contents)                   //
-    |                                                       |
-    +-------------+-------------+-------------+-------------+
-
-    Ref :  ERROR_SPEC @ RFC2205
-
-    IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
-    +-------------+-------------+-------------+-------------+
-    |                                                       |
-    +                                                       +
-    |                                                       |
-    +           IPv6 Error Node Address (16 bytes)          +
-    |                                                       |
-    +                                                       +
-    |                                                       |
-    +-------------+-------------+-------------+-------------+
-    |    Flags    |  Error Code |        Error Value        |
-    +-------------+-------------+-------------+-------------+     */
-
-    PcepRsvpSpecObjHeader objHeader;
-    public static final byte CLASS_NUM = 0x06;
-    public static final byte CLASS_TYPE = 0x02;
-    public static final byte CLASS_LENGTH = 0x18;
-    public static final byte IPV6_LEN = 0x10;
-
-    private byte[] ipv6Addr;
-    private byte flags;
-    private byte errCode;
-    private short errValue;
-
-    /**
-     * Constructor to initialize obj header, ipv6 addr, flags, err code and err value.
-     *
-     * @param objHeader rsvp ipv6 error spec object header
-     * @param ipv6Addr ipv6 address
-     * @param flags flags value
-     * @param errCode error code
-     * @param errValue error value
-     */
-    public PcepRsvpIpv6ErrorSpec(PcepRsvpSpecObjHeader objHeader, byte[] ipv6Addr, byte flags, byte errCode,
-            short errValue) {
-        this.objHeader = objHeader;
-        this.ipv6Addr = ipv6Addr;
-        this.flags = flags;
-        this.errCode = errCode;
-        this.errValue = errValue;
-    }
-
-    /**
-     * Constructor to initialize ipv6 addr, flags, err code and err value.
-     *
-     * @param ipv6Addr ipv6 address
-     * @param flags flags value
-     * @param errCode error code
-     * @param errValue error value
-     */
-    public PcepRsvpIpv6ErrorSpec(byte[] ipv6Addr, byte flags, byte errCode, short errValue) {
-        this.objHeader = new PcepRsvpSpecObjHeader(CLASS_LENGTH, CLASS_NUM, CLASS_TYPE);
-        this.ipv6Addr = ipv6Addr;
-        this.flags = flags;
-        this.errCode = errCode;
-        this.errValue = errValue;
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) {
-        int objLenIndex = objHeader.write(cb);
-        cb.writeBytes(ipv6Addr);
-        cb.writeByte(flags);
-        cb.writeByte(errCode);
-        cb.writeShort(errValue);
-        short objLen = (short) (cb.writerIndex() - objLenIndex);
-        cb.setShort(objLenIndex, objLen);
-        return objLen;
-    }
-
-    /**
-     * Returns PCEP rsvp IPv6 error spce object.
-     *
-     * @param cb channel buffer
-     * @return PCEP rsvp IPv6 error spce object
-     */
-    public static PcepRsvpErrorSpec read(ChannelBuffer cb) {
-        PcepRsvpSpecObjHeader objHeader;
-        byte[] ipv6Addr = new byte[IPV6_LEN];
-        byte flags;
-        byte errCode;
-        short errValue;
-
-        objHeader = PcepRsvpSpecObjHeader.read(cb);
-        cb.readBytes(ipv6Addr, 0, IPV6_LEN);
-        flags = cb.readByte();
-        errCode = cb.readByte();
-        errValue = cb.readShort();
-        return new PcepRsvpIpv6ErrorSpec(objHeader, ipv6Addr, flags, errCode, errValue);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return StatefulRsvpErrorSpecTlv.TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return CLASS_LENGTH;
-    }
-
-    @Override
-    public byte getClassNum() {
-        return CLASS_NUM;
-    }
-
-    @Override
-    public byte getClassType() {
-        return CLASS_TYPE;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("IPv6Address:", ipv6Addr)
-                .add("flags:", flags)
-                .add("errorCode:", errCode)
-                .add("errorValue:", errValue)
-                .toString();
-    }
-}
+package org.onosproject.pcepio.types;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Rsvp Ipv6 Error Spec.
+ */
+public class PcepRsvpIpv6ErrorSpec implements PcepRsvpErrorSpec {
+
+    /*
+        0             1              2             3
+    +-------------+-------------+-------------+-------------+
+    |       Length (bytes)      |  Class-Num  |   C-Type    |
+    +-------------+-------------+-------------+-------------+
+    |                                                       |
+    //                  (Object contents)                   //
+    |                                                       |
+    +-------------+-------------+-------------+-------------+
+
+    Ref :  ERROR_SPEC @ RFC2205
+
+    IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
+    +-------------+-------------+-------------+-------------+
+    |                                                       |
+    +                                                       +
+    |                                                       |
+    +           IPv6 Error Node Address (16 bytes)          +
+    |                                                       |
+    +                                                       +
+    |                                                       |
+    +-------------+-------------+-------------+-------------+
+    |    Flags    |  Error Code |        Error Value        |
+    +-------------+-------------+-------------+-------------+     */
+
+    PcepRsvpSpecObjHeader objHeader;
+    public static final byte CLASS_NUM = 0x06;
+    public static final byte CLASS_TYPE = 0x02;
+    public static final byte CLASS_LENGTH = 0x18;
+    public static final byte IPV6_LEN = 0x10;
+
+    private byte[] ipv6Addr;
+    private byte flags;
+    private byte errCode;
+    private short errValue;
+
+    /**
+     * Constructor to initialize obj header, ipv6 addr, flags, err code and err value.
+     *
+     * @param objHeader rsvp ipv6 error spec object header
+     * @param ipv6Addr ipv6 address
+     * @param flags flags value
+     * @param errCode error code
+     * @param errValue error value
+     */
+    public PcepRsvpIpv6ErrorSpec(PcepRsvpSpecObjHeader objHeader, byte[] ipv6Addr, byte flags, byte errCode,
+            short errValue) {
+        this.objHeader = objHeader;
+        this.ipv6Addr = ipv6Addr;
+        this.flags = flags;
+        this.errCode = errCode;
+        this.errValue = errValue;
+    }
+
+    /**
+     * Constructor to initialize ipv6 addr, flags, err code and err value.
+     *
+     * @param ipv6Addr ipv6 address
+     * @param flags flags value
+     * @param errCode error code
+     * @param errValue error value
+     */
+    public PcepRsvpIpv6ErrorSpec(byte[] ipv6Addr, byte flags, byte errCode, short errValue) {
+        this.objHeader = new PcepRsvpSpecObjHeader(CLASS_LENGTH, CLASS_NUM, CLASS_TYPE);
+        this.ipv6Addr = ipv6Addr;
+        this.flags = flags;
+        this.errCode = errCode;
+        this.errValue = errValue;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        int objLenIndex = objHeader.write(cb);
+        cb.writeBytes(ipv6Addr);
+        cb.writeByte(flags);
+        cb.writeByte(errCode);
+        cb.writeShort(errValue);
+        short objLen = (short) (cb.writerIndex() - objLenIndex);
+        cb.setShort(objLenIndex, objLen);
+        return objLen;
+    }
+
+    /**
+     * Returns PCEP rsvp IPv6 error spce object.
+     *
+     * @param cb channel buffer
+     * @return PCEP rsvp IPv6 error spce object
+     */
+    public static PcepRsvpErrorSpec read(ChannelBuffer cb) {
+        PcepRsvpSpecObjHeader objHeader;
+        byte[] ipv6Addr = new byte[IPV6_LEN];
+        byte flags;
+        byte errCode;
+        short errValue;
+
+        objHeader = PcepRsvpSpecObjHeader.read(cb);
+        cb.readBytes(ipv6Addr, 0, IPV6_LEN);
+        flags = cb.readByte();
+        errCode = cb.readByte();
+        errValue = cb.readShort();
+        return new PcepRsvpIpv6ErrorSpec(objHeader, ipv6Addr, flags, errCode, errValue);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return StatefulRsvpErrorSpecTlv.TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return CLASS_LENGTH;
+    }
+
+    @Override
+    public byte getClassNum() {
+        return CLASS_NUM;
+    }
+
+    @Override
+    public byte getClassType() {
+        return CLASS_TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("IPv6Address:", ipv6Addr)
+                .add("flags:", flags)
+                .add("errorCode:", errCode)
+                .add("errorValue:", errValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpUserErrorSpec.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpUserErrorSpec.java
index ac3fe1a..80fedd8 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpUserErrorSpec.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/PcepRsvpUserErrorSpec.java
@@ -1,220 +1,220 @@
-/*
- * 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.types;
-
-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.PcepVersion;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Pcep Rsvp User Error Spec.
- */
-public class PcepRsvpUserErrorSpec implements PcepRsvpErrorSpec {
-
-    /*
-        RSVP error spec object header.
-        0             1              2             3
-    +-------------+-------------+-------------+-------------+
-    |       Length (bytes)      |  Class-Num  |   C-Type    |
-    +-------------+-------------+-------------+-------------+
-    |                                                       |
-    //                  (Object contents)                   //
-    |                                                       |
-    +-------------+-------------+-------------+-------------+
-
-    Ref : USER_ERROR_SPEC @ RFC5284.
-    USER_ERROR_SPEC object: Class = 194, C-Type = 1
-
-    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
-    +---------------+---------------+---------------+---------------+
-    |                       Enterprise Number                       |
-    +---------------+---------------+---------------+---------------+
-    |    Sub Org    |  Err Desc Len |        User Error Value       |
-    +---------------+---------------+---------------+---------------+
-    |                                                               |
-    ~                       Error Description                       ~
-    |                                                               |
-    +---------------+---------------+---------------+---------------+
-    |                                                               |
-    ~                     User-Defined Subobjects                   ~
-    |                                                               |
-    +---------------+---------------+---------------+---------------+
-     */
-
-    public static final byte CLASS_NUM = (byte) 0xc2;
-    public static final byte CLASS_TYPE = 0x01;
-
-    private PcepRsvpSpecObjHeader objHeader;
-    private int enterpriseNum;
-    private byte subOrg;
-    private byte errDescLen;
-    private short userErrorValue;
-    private byte[] errDesc;
-    private LinkedList<PcepValueType> llRsvpUserSpecSubObj;
-
-    /**
-     * Default constructor.
-     *
-     * @param objHeader pcep rsvp spec object header
-     * @param enterpriseNum enterprise number
-     * @param subOrg organization identifier value
-     * @param errDescLen error description length
-     * @param userErrorValue user error value
-     * @param errDesc error description
-     * @param llRsvpUserSpecSubObj list of subobjects
-     */
-    public PcepRsvpUserErrorSpec(PcepRsvpSpecObjHeader objHeader, int enterpriseNum, byte subOrg, byte errDescLen,
-            short userErrorValue, byte[] errDesc, LinkedList<PcepValueType> llRsvpUserSpecSubObj) {
-        this.objHeader = objHeader;
-        this.enterpriseNum = enterpriseNum;
-        this.subOrg = subOrg;
-        this.errDescLen = errDescLen;
-        this.userErrorValue = userErrorValue;
-        this.errDesc = errDesc;
-        this.llRsvpUserSpecSubObj = llRsvpUserSpecSubObj;
-    }
-
-    @Override
-    public int write(ChannelBuffer cb) {
-        int objLenIndex = objHeader.write(cb);
-        cb.writeInt(enterpriseNum);
-        cb.writeByte(subOrg);
-        cb.writeByte(errDescLen);
-        cb.writeShort(userErrorValue);
-        cb.writeBytes(errDesc);
-
-        if (null != llRsvpUserSpecSubObj) {
-
-            ListIterator<PcepValueType> listIterator = llRsvpUserSpecSubObj.listIterator();
-
-            while (listIterator.hasNext()) {
-                PcepValueType tlv = listIterator.next();
-                if (null == tlv) {
-                    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);
-                    }
-                }
-            }
-        }
-        short objLen = (short) (cb.writerIndex() - objLenIndex);
-        cb.setShort(objLenIndex, objLen);
-        return objLen;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of PcepRsvpErrorSpec.
-     *
-     * @param cb of type channel buffer
-     * @return object of PcepRsvpErrorSpec
-     * @throws PcepParseException when expected object is not received
-     */
-    public static PcepRsvpErrorSpec read(ChannelBuffer cb) throws PcepParseException {
-        PcepRsvpSpecObjHeader objHeader;
-        int enterpriseNum;
-        byte subOrg;
-        byte errDescLen;
-        short userErrorValue;
-        byte[] errDesc;
-        LinkedList<PcepValueType> llRsvpUserSpecSubObj = null;
-
-        objHeader = PcepRsvpSpecObjHeader.read(cb);
-
-        if (CLASS_NUM != objHeader.getObjClassNum() || CLASS_TYPE != objHeader.getObjClassType()) {
-            throw new PcepParseException("Expected PcepRsvpUserErrorSpec object.");
-        }
-        enterpriseNum = cb.readInt();
-        subOrg = cb.readByte();
-        errDescLen = cb.readByte();
-        userErrorValue = cb.readShort();
-        errDesc = new byte[errDescLen];
-        cb.readBytes(errDesc, 0, errDescLen);
-
-        llRsvpUserSpecSubObj = parseErrSpecSubObj(cb);
-
-        return new PcepRsvpUserErrorSpec(objHeader, enterpriseNum, subOrg, errDescLen, userErrorValue, errDesc,
-                llRsvpUserSpecSubObj);
-    }
-
-    private static LinkedList<PcepValueType> parseErrSpecSubObj(ChannelBuffer cb) throws PcepParseException {
-        LinkedList<PcepValueType> llRsvpUserSpecSubObj = new LinkedList<PcepValueType>();
-        while (0 < cb.readableBytes()) {
-            PcepValueType tlv = null;
-            short hType = cb.readShort();
-            int iValue = 0;
-            //short hLength = cb.readShort();
-            switch (hType) {
-            case AutonomousSystemTlv.TYPE:
-                iValue = cb.readInt();
-                tlv = new AutonomousSystemTlv(iValue);
-                break;
-            default:
-                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
-            }
-            llRsvpUserSpecSubObj.add(tlv);
-        }
-        return llRsvpUserSpecSubObj;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return StatefulRsvpErrorSpecTlv.TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return objHeader.getObjLen();
-    }
-
-    @Override
-    public byte getClassNum() {
-        return CLASS_NUM;
-    }
-
-    @Override
-    public byte getClassType() {
-        return CLASS_TYPE;
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("enterpriseNumber:", enterpriseNum)
-                .add("subOrganization:", subOrg)
-                .add("errDescLength:", errDescLen)
-                .add("userErrorValue:", userErrorValue)
-                .add("errDesc:", errDesc)
-                .add("RsvpUserSpecSubObject:", llRsvpUserSpecSubObj)
-                .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.types;
+
+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.PcepVersion;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Pcep Rsvp User Error Spec.
+ */
+public class PcepRsvpUserErrorSpec implements PcepRsvpErrorSpec {
+
+    /*
+        RSVP error spec object header.
+        0             1              2             3
+    +-------------+-------------+-------------+-------------+
+    |       Length (bytes)      |  Class-Num  |   C-Type    |
+    +-------------+-------------+-------------+-------------+
+    |                                                       |
+    //                  (Object contents)                   //
+    |                                                       |
+    +-------------+-------------+-------------+-------------+
+
+    Ref : USER_ERROR_SPEC @ RFC5284.
+    USER_ERROR_SPEC object: Class = 194, C-Type = 1
+
+    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
+    +---------------+---------------+---------------+---------------+
+    |                       Enterprise Number                       |
+    +---------------+---------------+---------------+---------------+
+    |    Sub Org    |  Err Desc Len |        User Error Value       |
+    +---------------+---------------+---------------+---------------+
+    |                                                               |
+    ~                       Error Description                       ~
+    |                                                               |
+    +---------------+---------------+---------------+---------------+
+    |                                                               |
+    ~                     User-Defined Subobjects                   ~
+    |                                                               |
+    +---------------+---------------+---------------+---------------+
+     */
+
+    public static final byte CLASS_NUM = (byte) 0xc2;
+    public static final byte CLASS_TYPE = 0x01;
+
+    private PcepRsvpSpecObjHeader objHeader;
+    private int enterpriseNum;
+    private byte subOrg;
+    private byte errDescLen;
+    private short userErrorValue;
+    private byte[] errDesc;
+    private LinkedList<PcepValueType> llRsvpUserSpecSubObj;
+
+    /**
+     * Default constructor.
+     *
+     * @param objHeader pcep rsvp spec object header
+     * @param enterpriseNum enterprise number
+     * @param subOrg organization identifier value
+     * @param errDescLen error description length
+     * @param userErrorValue user error value
+     * @param errDesc error description
+     * @param llRsvpUserSpecSubObj list of subobjects
+     */
+    public PcepRsvpUserErrorSpec(PcepRsvpSpecObjHeader objHeader, int enterpriseNum, byte subOrg, byte errDescLen,
+            short userErrorValue, byte[] errDesc, LinkedList<PcepValueType> llRsvpUserSpecSubObj) {
+        this.objHeader = objHeader;
+        this.enterpriseNum = enterpriseNum;
+        this.subOrg = subOrg;
+        this.errDescLen = errDescLen;
+        this.userErrorValue = userErrorValue;
+        this.errDesc = errDesc;
+        this.llRsvpUserSpecSubObj = llRsvpUserSpecSubObj;
+    }
+
+    @Override
+    public int write(ChannelBuffer cb) {
+        int objLenIndex = objHeader.write(cb);
+        cb.writeInt(enterpriseNum);
+        cb.writeByte(subOrg);
+        cb.writeByte(errDescLen);
+        cb.writeShort(userErrorValue);
+        cb.writeBytes(errDesc);
+
+        if (null != llRsvpUserSpecSubObj) {
+
+            ListIterator<PcepValueType> listIterator = llRsvpUserSpecSubObj.listIterator();
+
+            while (listIterator.hasNext()) {
+                PcepValueType tlv = listIterator.next();
+                if (null == tlv) {
+                    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);
+                    }
+                }
+            }
+        }
+        short objLen = (short) (cb.writerIndex() - objLenIndex);
+        cb.setShort(objLenIndex, objLen);
+        return objLen;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of PcepRsvpErrorSpec.
+     *
+     * @param cb of type channel buffer
+     * @return object of PcepRsvpErrorSpec
+     * @throws PcepParseException when expected object is not received
+     */
+    public static PcepRsvpErrorSpec read(ChannelBuffer cb) throws PcepParseException {
+        PcepRsvpSpecObjHeader objHeader;
+        int enterpriseNum;
+        byte subOrg;
+        byte errDescLen;
+        short userErrorValue;
+        byte[] errDesc;
+        LinkedList<PcepValueType> llRsvpUserSpecSubObj = null;
+
+        objHeader = PcepRsvpSpecObjHeader.read(cb);
+
+        if (CLASS_NUM != objHeader.getObjClassNum() || CLASS_TYPE != objHeader.getObjClassType()) {
+            throw new PcepParseException("Expected PcepRsvpUserErrorSpec object.");
+        }
+        enterpriseNum = cb.readInt();
+        subOrg = cb.readByte();
+        errDescLen = cb.readByte();
+        userErrorValue = cb.readShort();
+        errDesc = new byte[errDescLen];
+        cb.readBytes(errDesc, 0, errDescLen);
+
+        llRsvpUserSpecSubObj = parseErrSpecSubObj(cb);
+
+        return new PcepRsvpUserErrorSpec(objHeader, enterpriseNum, subOrg, errDescLen, userErrorValue, errDesc,
+                llRsvpUserSpecSubObj);
+    }
+
+    private static LinkedList<PcepValueType> parseErrSpecSubObj(ChannelBuffer cb) throws PcepParseException {
+        LinkedList<PcepValueType> llRsvpUserSpecSubObj = new LinkedList<PcepValueType>();
+        while (0 < cb.readableBytes()) {
+            PcepValueType tlv = null;
+            short hType = cb.readShort();
+            int iValue = 0;
+            //short hLength = cb.readShort();
+            switch (hType) {
+            case AutonomousSystemTlv.TYPE:
+                iValue = cb.readInt();
+                tlv = new AutonomousSystemTlv(iValue);
+                break;
+            default:
+                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
+            }
+            llRsvpUserSpecSubObj.add(tlv);
+        }
+        return llRsvpUserSpecSubObj;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return StatefulRsvpErrorSpecTlv.TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return objHeader.getObjLen();
+    }
+
+    @Override
+    public byte getClassNum() {
+        return CLASS_NUM;
+    }
+
+    @Override
+    public byte getClassType() {
+        return CLASS_TYPE;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("enterpriseNumber:", enterpriseNum)
+                .add("subOrganization:", subOrg)
+                .add("errDescLength:", errDescLen)
+                .add("userErrorValue:", userErrorValue)
+                .add("errDesc:", errDesc)
+                .add("RsvpUserSpecSubObject:", llRsvpUserSpecSubObj)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RemoteTENodeDescriptorsTLV.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RemoteTENodeDescriptorsTLV.java
index 39ec987..8afa23d 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RemoteTENodeDescriptorsTLV.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RemoteTENodeDescriptorsTLV.java
@@ -1,246 +1,246 @@
-/*
- * 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.types;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Remote TE Node Descriptors TLV.
- */
-public class RemoteTENodeDescriptorsTLV implements PcepValueType {
-
-    /* Reference :PCEP Extension for Transporting TE Data
-        draft-dhodylee-pce-pcep-te-data-extn-02
-     *
-          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
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |           Type=[TBD9]         |             Length            |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |                                                               |
-         //              Node Descriptor Sub-TLVs (variable)            //
-         |                                                               |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(RemoteTENodeDescriptorsTLV.class);
-
-    public static final short TYPE = 1003; //TODD:change this TBD9
-    public short hLength;
-
-    public static final int TLV_HEADER_LENGTH = 4;
-    // Node Descriptor Sub-TLVs (variable)
-    private LinkedList<PcepValueType> llRemoteTENodeDescriptorSubTLVs;
-
-    /**
-     * Constructor to initialize llRemoteTENodeDescriptorSubTLVs.
-     *
-     * @param llRemoteTENodeDescriptorSubTLVs LinkedList of PcepValueType
-     */
-    public RemoteTENodeDescriptorsTLV(LinkedList<PcepValueType> llRemoteTENodeDescriptorSubTLVs) {
-        this.llRemoteTENodeDescriptorSubTLVs = llRemoteTENodeDescriptorSubTLVs;
-    }
-
-    /**
-     * Returns object of Remote TE Node Descriptors TLV.
-     *
-     * @param llRemoteTENodeDescriptorSubTLVs LinkedList of PcepValueType
-     * @return object of RemoteTENodeDescriptorsTLV
-     */
-    public static RemoteTENodeDescriptorsTLV of(final LinkedList<PcepValueType> llRemoteTENodeDescriptorSubTLVs) {
-        return new RemoteTENodeDescriptorsTLV(llRemoteTENodeDescriptorSubTLVs);
-    }
-
-    /**
-     * Returns Remote TE Node Descriptor Sub TLVs.
-     *
-     * @return llRemoteTENodeDescriptorSubTLVs
-     */
-    public LinkedList<PcepValueType> getllRemoteTENodeDescriptorSubTLVs() {
-        return llRemoteTENodeDescriptorSubTLVs;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(llRemoteTENodeDescriptorSubTLVs.hashCode());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        /*
-         * Here we have a list of Tlv so to compare each sub tlv between the object
-         * we have to take a list iterator so one by one we can get each sub tlv object
-         * and can compare them.
-         * it may be possible that the size of 2 lists is not equal so we have to first check
-         * the size, if both are same then we should check for the subtlv objects otherwise
-         * we should return false.
-         */
-        if (obj instanceof RemoteTENodeDescriptorsTLV) {
-            int countObjSubTlv = 0;
-            int countOtherSubTlv = 0;
-            boolean isCommonSubTlv = true;
-            RemoteTENodeDescriptorsTLV other = (RemoteTENodeDescriptorsTLV) obj;
-            Iterator<PcepValueType> objListIterator = ((RemoteTENodeDescriptorsTLV) obj).llRemoteTENodeDescriptorSubTLVs
-                    .iterator();
-            countObjSubTlv = ((RemoteTENodeDescriptorsTLV) obj).llRemoteTENodeDescriptorSubTLVs.size();
-            countOtherSubTlv = other.llRemoteTENodeDescriptorSubTLVs.size();
-            if (countObjSubTlv != countOtherSubTlv) {
-                return false;
-            } else {
-                while (objListIterator.hasNext() && isCommonSubTlv) {
-                    PcepValueType subTlv = objListIterator.next();
-                    isCommonSubTlv = Objects.equals(llRemoteTENodeDescriptorSubTLVs.contains(subTlv),
-                            other.llRemoteTENodeDescriptorSubTLVs.contains(subTlv));
-                }
-                return isCommonSubTlv;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-
-        int tlvStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        int tlvLenIndex = c.writerIndex();
-        hLength = 0;
-        c.writeShort(hLength);
-
-        ListIterator<PcepValueType> listIterator = llRemoteTENodeDescriptorSubTLVs.listIterator();
-
-        while (listIterator.hasNext()) {
-            PcepValueType tlv = listIterator.next();
-
-            if (null == tlv) {
-                log.debug("TLV is null from subTlv list");
-                continue;
-            }
-            tlv.write(c);
-
-            // need to take care of padding
-            int pad = tlv.getLength() % 4;
-
-            if (0 != pad) {
-                pad = 4 - pad;
-                for (int i = 0; i < pad; ++i) {
-                    c.writeByte((byte) 0);
-                }
-            }
-        }
-
-        hLength = (short) (c.writerIndex() - tlvStartIndex);
-        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
-
-        return c.writerIndex() - tlvStartIndex;
-    }
-
-    /**
-     * Reads channel buffer and returns object of Remote TE Node Descriptors TLV.
-     *
-     * @param c input channel buffer
-     * @return object of RemoteTENodeDescriptorsTLV
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public static PcepValueType read(ChannelBuffer c , short length) throws PcepParseException {
-
-        // Node Descriptor Sub-TLVs (variable)
-        LinkedList<PcepValueType> llRemoteTENodeDescriptorSubTLVs = new LinkedList<PcepValueType>();
-
-        ChannelBuffer tempCb = c.readBytes(length);
-
-        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
-
-            PcepValueType tlv;
-            short hType = tempCb.readShort();
-            int iValue = 0;
-            short hLength = tempCb.readShort();
-            switch (hType) {
-
-            case AutonomousSystemTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new AutonomousSystemTlv(iValue);
-                break;
-            case BGPLSidentifierTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new BGPLSidentifierTlv(iValue);
-                break;
-            case OSPFareaIDsubTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new OSPFareaIDsubTlv(iValue);
-                break;
-            case RouterIDSubTlv.TYPE:
-                tlv = RouterIDSubTlv.read(tempCb, hLength);
-                break;
-
-            default:
-                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
-            }
-
-            // Check for the padding
-            int pad = hLength % 4;
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= tempCb.readableBytes()) {
-                    tempCb.skipBytes(pad);
-                }
-            }
-
-            llRemoteTENodeDescriptorSubTLVs.add(tlv);
-        }
-
-        if (0 < tempCb.readableBytes()) {
-
-            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
-        }
-        return new RemoteTENodeDescriptorsTLV(llRemoteTENodeDescriptorSubTLVs);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
-                .add("RemoteTeNodeDescriptorSubTLVs", llRemoteTENodeDescriptorSubTLVs).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.types;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Remote TE Node Descriptors TLV.
+ */
+public class RemoteTENodeDescriptorsTLV implements PcepValueType {
+
+    /* Reference :PCEP Extension for Transporting TE Data
+        draft-dhodylee-pce-pcep-te-data-extn-02
+     *
+          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
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |           Type=[TBD9]         |             Length            |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               |
+         //              Node Descriptor Sub-TLVs (variable)            //
+         |                                                               |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(RemoteTENodeDescriptorsTLV.class);
+
+    public static final short TYPE = 1003; //TODD:change this TBD9
+    public short hLength;
+
+    public static final int TLV_HEADER_LENGTH = 4;
+    // Node Descriptor Sub-TLVs (variable)
+    private LinkedList<PcepValueType> llRemoteTENodeDescriptorSubTLVs;
+
+    /**
+     * Constructor to initialize llRemoteTENodeDescriptorSubTLVs.
+     *
+     * @param llRemoteTENodeDescriptorSubTLVs LinkedList of PcepValueType
+     */
+    public RemoteTENodeDescriptorsTLV(LinkedList<PcepValueType> llRemoteTENodeDescriptorSubTLVs) {
+        this.llRemoteTENodeDescriptorSubTLVs = llRemoteTENodeDescriptorSubTLVs;
+    }
+
+    /**
+     * Returns object of Remote TE Node Descriptors TLV.
+     *
+     * @param llRemoteTENodeDescriptorSubTLVs LinkedList of PcepValueType
+     * @return object of RemoteTENodeDescriptorsTLV
+     */
+    public static RemoteTENodeDescriptorsTLV of(final LinkedList<PcepValueType> llRemoteTENodeDescriptorSubTLVs) {
+        return new RemoteTENodeDescriptorsTLV(llRemoteTENodeDescriptorSubTLVs);
+    }
+
+    /**
+     * Returns Remote TE Node Descriptor Sub TLVs.
+     *
+     * @return llRemoteTENodeDescriptorSubTLVs
+     */
+    public LinkedList<PcepValueType> getllRemoteTENodeDescriptorSubTLVs() {
+        return llRemoteTENodeDescriptorSubTLVs;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(llRemoteTENodeDescriptorSubTLVs.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        /*
+         * Here we have a list of Tlv so to compare each sub tlv between the object
+         * we have to take a list iterator so one by one we can get each sub tlv object
+         * and can compare them.
+         * it may be possible that the size of 2 lists is not equal so we have to first check
+         * the size, if both are same then we should check for the subtlv objects otherwise
+         * we should return false.
+         */
+        if (obj instanceof RemoteTENodeDescriptorsTLV) {
+            int countObjSubTlv = 0;
+            int countOtherSubTlv = 0;
+            boolean isCommonSubTlv = true;
+            RemoteTENodeDescriptorsTLV other = (RemoteTENodeDescriptorsTLV) obj;
+            Iterator<PcepValueType> objListIterator = ((RemoteTENodeDescriptorsTLV) obj).llRemoteTENodeDescriptorSubTLVs
+                    .iterator();
+            countObjSubTlv = ((RemoteTENodeDescriptorsTLV) obj).llRemoteTENodeDescriptorSubTLVs.size();
+            countOtherSubTlv = other.llRemoteTENodeDescriptorSubTLVs.size();
+            if (countObjSubTlv != countOtherSubTlv) {
+                return false;
+            } else {
+                while (objListIterator.hasNext() && isCommonSubTlv) {
+                    PcepValueType subTlv = objListIterator.next();
+                    isCommonSubTlv = Objects.equals(llRemoteTENodeDescriptorSubTLVs.contains(subTlv),
+                            other.llRemoteTENodeDescriptorSubTLVs.contains(subTlv));
+                }
+                return isCommonSubTlv;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+
+        int tlvStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        int tlvLenIndex = c.writerIndex();
+        hLength = 0;
+        c.writeShort(hLength);
+
+        ListIterator<PcepValueType> listIterator = llRemoteTENodeDescriptorSubTLVs.listIterator();
+
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            if (null == tlv) {
+                log.debug("TLV is null from subTlv list");
+                continue;
+            }
+            tlv.write(c);
+
+            // need to take care of padding
+            int pad = tlv.getLength() % 4;
+
+            if (0 != pad) {
+                pad = 4 - pad;
+                for (int i = 0; i < pad; ++i) {
+                    c.writeByte((byte) 0);
+                }
+            }
+        }
+
+        hLength = (short) (c.writerIndex() - tlvStartIndex);
+        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
+
+        return c.writerIndex() - tlvStartIndex;
+    }
+
+    /**
+     * Reads channel buffer and returns object of Remote TE Node Descriptors TLV.
+     *
+     * @param c input channel buffer
+     * @return object of RemoteTENodeDescriptorsTLV
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepValueType read(ChannelBuffer c , short length) throws PcepParseException {
+
+        // Node Descriptor Sub-TLVs (variable)
+        LinkedList<PcepValueType> llRemoteTENodeDescriptorSubTLVs = new LinkedList<PcepValueType>();
+
+        ChannelBuffer tempCb = c.readBytes(length);
+
+        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
+
+            PcepValueType tlv;
+            short hType = tempCb.readShort();
+            int iValue = 0;
+            short hLength = tempCb.readShort();
+            switch (hType) {
+
+            case AutonomousSystemTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new AutonomousSystemTlv(iValue);
+                break;
+            case BGPLSidentifierTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new BGPLSidentifierTlv(iValue);
+                break;
+            case OSPFareaIDsubTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new OSPFareaIDsubTlv(iValue);
+                break;
+            case RouterIDSubTlv.TYPE:
+                tlv = RouterIDSubTlv.read(tempCb, hLength);
+                break;
+
+            default:
+                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
+            }
+
+            // Check for the padding
+            int pad = hLength % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= tempCb.readableBytes()) {
+                    tempCb.skipBytes(pad);
+                }
+            }
+
+            llRemoteTENodeDescriptorSubTLVs.add(tlv);
+        }
+
+        if (0 < tempCb.readableBytes()) {
+
+            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
+        }
+        return new RemoteTENodeDescriptorsTLV(llRemoteTENodeDescriptorSubTLVs);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
+                .add("RemoteTeNodeDescriptorSubTLVs", llRemoteTENodeDescriptorSubTLVs).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RouterIDSubTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RouterIDSubTlv.java
index e061d63..9b27ce1 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RouterIDSubTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RouterIDSubTlv.java
@@ -1,154 +1,154 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides router id.
- */
-public class RouterIDSubTlv implements PcepValueType {
-
-    /* reference :I-D.ietf-idr-ls-distribution.
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD13]         |             Length           |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                    opaque value                               |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(RouterIDSubTlv.class);
-
-    public static final short TYPE = 1000; //TODD:change this TBD13
-    private final short hLength;
-
-    private final byte[] rawValue;
-
-    /**
-     * constructor to initialize rawValue.
-     *
-     * @param rawValue raw value
-     * @param hLength length
-     */
-    public RouterIDSubTlv(byte[] rawValue, short hLength) {
-        this.rawValue = rawValue;
-        if (0 == hLength) {
-            this.hLength = (short) rawValue.length;
-        } else {
-            this.hLength = hLength;
-        }
-    }
-
-    /**
-     * Returns object of Router ID Sub Tlv.
-     *
-     * @param raw value
-     * @param hLength length
-     * @return object of Router ID Sub Tlv
-     */
-    public static RouterIDSubTlv of(final byte[] raw, short hLength) {
-        return new RouterIDSubTlv(raw, hLength);
-    }
-
-    /**
-     * Returns raw value.
-     *
-     * @return rawValue value
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof RouterIDSubTlv) {
-            RouterIDSubTlv other = (RouterIDSubTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads channel buffer and returns object of RouterIDSubTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of RouterIDSubTlv
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) {
-        byte[] iOpaqueValue = new byte[hLength];
-        c.readBytes(iOpaqueValue, 0, hLength);
-        return new RouterIDSubTlv(iOpaqueValue, hLength);
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", hLength);
-
-        StringBuffer result = new StringBuffer();
-        for (byte b : rawValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides router id.
+ */
+public class RouterIDSubTlv implements PcepValueType {
+
+    /* reference :I-D.ietf-idr-ls-distribution.
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD13]         |             Length           |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                    opaque value                               |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(RouterIDSubTlv.class);
+
+    public static final short TYPE = 1000; //TODD:change this TBD13
+    private final short hLength;
+
+    private final byte[] rawValue;
+
+    /**
+     * constructor to initialize rawValue.
+     *
+     * @param rawValue raw value
+     * @param hLength length
+     */
+    public RouterIDSubTlv(byte[] rawValue, short hLength) {
+        this.rawValue = rawValue;
+        if (0 == hLength) {
+            this.hLength = (short) rawValue.length;
+        } else {
+            this.hLength = hLength;
+        }
+    }
+
+    /**
+     * Returns object of Router ID Sub Tlv.
+     *
+     * @param raw value
+     * @param hLength length
+     * @return object of Router ID Sub Tlv
+     */
+    public static RouterIDSubTlv of(final byte[] raw, short hLength) {
+        return new RouterIDSubTlv(raw, hLength);
+    }
+
+    /**
+     * Returns raw value.
+     *
+     * @return rawValue value
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof RouterIDSubTlv) {
+            RouterIDSubTlv other = (RouterIDSubTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads channel buffer and returns object of RouterIDSubTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of RouterIDSubTlv
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) {
+        byte[] iOpaqueValue = new byte[hLength];
+        c.readBytes(iOpaqueValue, 0, hLength);
+        return new RouterIDSubTlv(iOpaqueValue, hLength);
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", hLength);
+
+        StringBuffer result = new StringBuffer();
+        for (byte b : rawValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RoutingUniverseTLV.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RoutingUniverseTLV.java
index 09fcafd..bf553a4 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RoutingUniverseTLV.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/RoutingUniverseTLV.java
@@ -1,144 +1,144 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides RoutingUniverseTLV identifiers.
- */
-public class RoutingUniverseTLV implements PcepValueType {
-
-    /*
-     * Reference : draft-dhodylee-pce-pcep-te-data-extn-02, section 9.2.1.
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD7]         |           Length=8            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                           Identifier                          |
-     |                                                               |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     *
-     *
-     *             +------------+---------------------+
-                   | Identifier | Routing Universe    |
-                   +------------+---------------------+
-                   |     0      | L3 packet topology  |
-                   |     1      | L1 optical topology |
-                   +------------+---------------------+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(RoutingUniverseTLV.class);
-
-    public static final short TYPE = 14; // TODO:need to change TBD7
-    public static final short LENGTH = 8;
-
-    private final long rawValue;
-
-    /**
-     * Constructor to initialize raw value.
-     *
-     * @param rawValue raw value
-     */
-    public RoutingUniverseTLV(long rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns object of RoutingUniverseTLV.
-     *
-     * @param raw value
-     * @return object of RoutingUniverseTLV
-     */
-    public static RoutingUniverseTLV of(final long raw) {
-        return new RoutingUniverseTLV(raw);
-    }
-
-    /**
-     * Returns raw value as Identifier.
-     *
-     * @return rawValue Identifier
-     */
-    public long getLong() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof RoutingUniverseTLV) {
-            RoutingUniverseTLV other = (RoutingUniverseTLV) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeLong(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of RoutingUniverseTLV.
-     *
-     * @param c input channel buffer
-     * @return object of RoutingUniverseTLV
-     */
-    public static RoutingUniverseTLV read(ChannelBuffer c) {
-        return RoutingUniverseTLV.of(c.readLong());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides RoutingUniverseTLV identifiers.
+ */
+public class RoutingUniverseTLV implements PcepValueType {
+
+    /*
+     * Reference : draft-dhodylee-pce-pcep-te-data-extn-02, section 9.2.1.
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD7]         |           Length=8            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                           Identifier                          |
+     |                                                               |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     *
+     *
+     *             +------------+---------------------+
+                   | Identifier | Routing Universe    |
+                   +------------+---------------------+
+                   |     0      | L3 packet topology  |
+                   |     1      | L1 optical topology |
+                   +------------+---------------------+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(RoutingUniverseTLV.class);
+
+    public static final short TYPE = 14; // TODO:need to change TBD7
+    public static final short LENGTH = 8;
+
+    private final long rawValue;
+
+    /**
+     * Constructor to initialize raw value.
+     *
+     * @param rawValue raw value
+     */
+    public RoutingUniverseTLV(long rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns object of RoutingUniverseTLV.
+     *
+     * @param raw value
+     * @return object of RoutingUniverseTLV
+     */
+    public static RoutingUniverseTLV of(final long raw) {
+        return new RoutingUniverseTLV(raw);
+    }
+
+    /**
+     * Returns raw value as Identifier.
+     *
+     * @return rawValue Identifier
+     */
+    public long getLong() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof RoutingUniverseTLV) {
+            RoutingUniverseTLV other = (RoutingUniverseTLV) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeLong(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of RoutingUniverseTLV.
+     *
+     * @param c input channel buffer
+     * @return object of RoutingUniverseTLV
+     */
+    public static RoutingUniverseTLV read(ChannelBuffer c) {
+        return RoutingUniverseTLV.of(c.readLong());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SharedRiskLinkGroupTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SharedRiskLinkGroupTlv.java
index b05a01a..70c15ee 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SharedRiskLinkGroupTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SharedRiskLinkGroupTlv.java
@@ -1,167 +1,167 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides SharedRiskLinkGroupTlv.
- */
-public class SharedRiskLinkGroupTlv implements PcepValueType {
-
-    /*
-     * Reference :[I-D.ietf-idr- Group ls-distribution] /3.3.2.5
-     *
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type =TDB41      |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                  Shared Risk Link Group Value                 |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //                         ............                        //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                  Shared Risk Link Group Value                 |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(SharedRiskLinkGroupTlv.class);
-
-    public static final short TYPE = 1096; //TODO:NEED TO HANDLE TDB41
-
-    private final short hLength;
-
-    private final int[] srlgValue;
-
-    /**
-     * Constructor to initialize SRLG value.
-     *
-     * @param srlgValue Shared Risk Link Group Value
-     * @param hLength length
-     */
-    public SharedRiskLinkGroupTlv(int[] srlgValue, short hLength) {
-        this.srlgValue = srlgValue;
-        if (0 == hLength) {
-            this.hLength = (short) ((srlgValue.length) * 4);
-        } else {
-            this.hLength = hLength;
-        }
-    }
-
-    /**
-     * Returns object of SharedRiskLinkGroupTlv.
-     *
-     * @param raw value
-     * @param hLength length
-     * @return object of SharedRiskLinkGroupTlv
-     */
-    public static SharedRiskLinkGroupTlv of(final int[] raw, short hLength) {
-        return new SharedRiskLinkGroupTlv(raw, hLength);
-    }
-
-    /**
-     * Returns SRLG Value.
-     *
-     * @return srlgValue
-     */
-    public int[] getValue() {
-        return srlgValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(srlgValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof SharedRiskLinkGroupTlv) {
-            SharedRiskLinkGroupTlv other = (SharedRiskLinkGroupTlv) obj;
-            return Objects.equals(this.srlgValue, other.srlgValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        for (int b : srlgValue) {
-            c.writeInt(b);
-        }
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of SharedRiskLinkGroupTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of SharedRiskLinkGroupTlv
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) {
-        int iLength = hLength / 4;
-        int[] iSharedRiskLinkGroup = new int[iLength];
-        for (int i = 0; i < iLength; i++) {
-            iSharedRiskLinkGroup[i] = c.readInt();
-        }
-        return new SharedRiskLinkGroupTlv(iSharedRiskLinkGroup, hLength);
-    }
-
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        toStrHelper.add("Type", TYPE);
-        toStrHelper.add("Length", hLength);
-
-        StringBuffer result = new StringBuffer();
-        for (int b : srlgValue) {
-            result.append(String.format("%02X ", b));
-        }
-        toStrHelper.add("Value", result);
-
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides SharedRiskLinkGroupTlv.
+ */
+public class SharedRiskLinkGroupTlv implements PcepValueType {
+
+    /*
+     * Reference :[I-D.ietf-idr- Group ls-distribution] /3.3.2.5
+     *
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type =TDB41      |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                  Shared Risk Link Group Value                 |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //                         ............                        //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                  Shared Risk Link Group Value                 |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(SharedRiskLinkGroupTlv.class);
+
+    public static final short TYPE = 1096; //TODO:NEED TO HANDLE TDB41
+
+    private final short hLength;
+
+    private final int[] srlgValue;
+
+    /**
+     * Constructor to initialize SRLG value.
+     *
+     * @param srlgValue Shared Risk Link Group Value
+     * @param hLength length
+     */
+    public SharedRiskLinkGroupTlv(int[] srlgValue, short hLength) {
+        this.srlgValue = srlgValue;
+        if (0 == hLength) {
+            this.hLength = (short) ((srlgValue.length) * 4);
+        } else {
+            this.hLength = hLength;
+        }
+    }
+
+    /**
+     * Returns object of SharedRiskLinkGroupTlv.
+     *
+     * @param raw value
+     * @param hLength length
+     * @return object of SharedRiskLinkGroupTlv
+     */
+    public static SharedRiskLinkGroupTlv of(final int[] raw, short hLength) {
+        return new SharedRiskLinkGroupTlv(raw, hLength);
+    }
+
+    /**
+     * Returns SRLG Value.
+     *
+     * @return srlgValue
+     */
+    public int[] getValue() {
+        return srlgValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(srlgValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof SharedRiskLinkGroupTlv) {
+            SharedRiskLinkGroupTlv other = (SharedRiskLinkGroupTlv) obj;
+            return Objects.equals(this.srlgValue, other.srlgValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        for (int b : srlgValue) {
+            c.writeInt(b);
+        }
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of SharedRiskLinkGroupTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of SharedRiskLinkGroupTlv
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) {
+        int iLength = hLength / 4;
+        int[] iSharedRiskLinkGroup = new int[iLength];
+        for (int i = 0; i < iLength; i++) {
+            iSharedRiskLinkGroup[i] = c.readInt();
+        }
+        return new SharedRiskLinkGroupTlv(iSharedRiskLinkGroup, hLength);
+    }
+
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        toStrHelper.add("Type", TYPE);
+        toStrHelper.add("Length", hLength);
+
+        StringBuffer result = new StringBuffer();
+        for (int b : srlgValue) {
+            result.append(String.format("%02X ", b));
+        }
+        toStrHelper.add("Value", result);
+
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SrEroSubObject.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SrEroSubObject.java
index 28618b2..43a6244 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SrEroSubObject.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SrEroSubObject.java
@@ -1,324 +1,324 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepNai;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides SrEroSubObject.
- */
-public class SrEroSubObject implements PcepValueType {
-    /*
-    SR-ERO subobject: (draft-ietf-pce-segment-routing-00)
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |L|    Type     |     Length    |  ST   |     Flags     |F|S|C|M|
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                              SID                              |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    //                        NAI (variable)                       //
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-
-
-    NAI
-
-          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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                      Local IPv4 address                       |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                     Remote IPv4 address                       |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                        NAI for IPv4 Adjacency
-
-           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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //               Local IPv6 address (16 bytes)                 //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     //               Remote IPv6 address (16 bytes)                //
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-                       NAI for IPv6 adjacency
-
-           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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                      Local Node-ID                            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                    Local Interface ID                         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                      Remote Node-ID                           |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                   Remote Interface ID                         |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-           NAI for Unnumbered adjacency with IPv4 Node IDs
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(SrEroSubObject.class);
-
-    public static final short TYPE = 0x60; //TODO : type to be defined
-    public static final short LENGTH = 12;
-    public static final short VALUE_LENGTH = 10;
-    public static final int SET = 1;
-    public static final byte MFLAG_SET = 0x01;
-    public static final byte CFLAG_SET = 0x02;
-    public static final byte SFLAG_SET = 0x04;
-    public static final byte FFLAG_SET = 0x08;
-    public static final byte SHIFT_ST = 12;
-
-    private final boolean bFFlag;
-    private final boolean bSFlag;
-    private final boolean bCFlag;
-    private final boolean bMFlag;
-    private final byte st;
-
-    private final int sID;
-    private final PcepNai nai;
-
-    /**
-     * Constructor to initialize member variables.
-     *
-     * @param st SID type
-     * @param bFFlag F flag
-     * @param bSFlag S flag
-     * @param bCFlag C flag
-     * @param bMFlag M flag
-     * @param sID segment identifier value
-     * @param nai NAI associated with SID
-     */
-    public SrEroSubObject(byte st, boolean bFFlag, boolean bSFlag, boolean bCFlag, boolean bMFlag, int sID,
-            PcepNai nai) {
-        this.st = st;
-        this.bFFlag = bFFlag;
-        this.bSFlag = bSFlag;
-        this.bCFlag = bCFlag;
-        this.bMFlag = bMFlag;
-        this.sID = sID;
-        this.nai = nai;
-    }
-
-    /**
-     * Creates object of SrEroSubObject.
-     *
-     * @param st SID type
-     * @param bFFlag F flag
-     * @param bSFlag S flag
-     * @param bCFlag C flag
-     * @param bMFlag M flag
-     * @param sID segment identifier value
-     * @param nai NAI associated with SID
-     * @return object of SrEroSubObject
-     */
-    public static SrEroSubObject of(byte st, boolean bFFlag, boolean bSFlag, boolean bCFlag, boolean bMFlag, int sID,
-            PcepNai nai) {
-        return new SrEroSubObject(st, bFFlag, bSFlag, bCFlag, bMFlag, sID, nai);
-    }
-
-    /**
-     * Returns SID type.
-     * @return st sid type
-     */
-    public byte getSt() {
-        return st;
-    }
-
-    /**
-     * Returns bFFlag.
-     * @return bFFlag
-     */
-    public boolean getFFlag() {
-        return bFFlag;
-    }
-
-    /**
-     * Returns bSFlag.
-     * @return bSFlag
-     */
-    public boolean getSFlag() {
-        return bSFlag;
-    }
-
-    /**
-     * Returns bCFlag.
-     * @return bCFlag
-     */
-    public boolean getCFlag() {
-        return bCFlag;
-    }
-
-    /**
-     * Returns bMFlag.
-     * @return bMFlag
-     */
-    public boolean getMFlag() {
-        return bMFlag;
-    }
-
-    /**
-     * Returns sID.
-     * @return sID
-     */
-    public int getSID() {
-        return sID;
-    }
-
-    /**
-     * Returns nai.
-     * @return nai
-     */
-    public PcepNai getNai() {
-        return nai;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(st, bFFlag, bSFlag, bCFlag, bMFlag, sID, nai);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof SrEroSubObject) {
-            SrEroSubObject other = (SrEroSubObject) obj;
-            return Objects.equals(this.st, other.st) && Objects.equals(this.bFFlag, other.bFFlag)
-                    && Objects.equals(this.bSFlag, other.bSFlag) && Objects.equals(this.bCFlag, other.bCFlag)
-                    && Objects.equals(this.bMFlag, other.bMFlag) && Objects.equals(this.sID, other.sID)
-                    && Objects.equals(this.nai, other.nai);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-
-        short temp = 0;
-        if (bMFlag) {
-            temp = (short) (temp | MFLAG_SET);
-        }
-        if (bCFlag) {
-            temp = (short) (temp | CFLAG_SET);
-        }
-        if (bSFlag) {
-            temp = (short) (temp | SFLAG_SET);
-        }
-        if (bFFlag) {
-            temp = (short) (temp | FFLAG_SET);
-        }
-        short tempST = (short) (st << SHIFT_ST);
-        temp = (short) (temp | tempST);
-        c.writeShort(temp);
-        c.writeInt(sID);
-        nai.write(c);
-
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of SrEroSubObject.
-     * @param c of type channel buffer
-     * @return object of SrEroSubObject
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        short temp = c.readShort();
-        boolean bMFlag;
-        boolean bCFlag;
-        boolean bSFlag;
-        boolean bFFlag;
-        byte st;
-        PcepNai nai = null;
-
-        bMFlag = (temp & MFLAG_SET) == MFLAG_SET ? true : false;
-        bCFlag = (temp & CFLAG_SET) == CFLAG_SET ? true : false;
-        bSFlag = (temp & SFLAG_SET) == SFLAG_SET ? true : false;
-        bFFlag = (temp & FFLAG_SET) == FFLAG_SET ? true : false;
-
-        st = (byte) (temp >> SHIFT_ST);
-
-        int sID = c.readInt();
-        switch (st) {
-        case 0x01:
-            nai = PcepNaiIpv4NodeId.read(c);
-            break;
-        case 0x02:
-            nai = PcepNaiIpv6NodeId.read(c);
-            break;
-        case 0x03:
-            nai = PcepNaiIpv4Adjacency.read(c);
-            break;
-        case 0x04:
-            nai = PcepNaiIpv6Adjacency.read(c);
-            break;
-        case 0x05:
-            nai = PcepNaiUnnumberedAdjacencyIpv4.read(c);
-            break;
-        default:
-            nai = null;
-            break;
-        }
-
-        return new SrEroSubObject(st, bFFlag, bSFlag, bCFlag, bMFlag, sID, nai);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("Type", TYPE)
-                .add("Length", LENGTH)
-                .add("st", st)
-                .add("bFflag", bFFlag)
-                .add("bSFlag", bSFlag)
-                .add("bCFlag", bCFlag)
-                .add("bMFlag", bMFlag)
-                .add("sID", sID)
-                .add("nAI", nai)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepNai;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides SrEroSubObject.
+ */
+public class SrEroSubObject implements PcepValueType {
+    /*
+    SR-ERO subobject: (draft-ietf-pce-segment-routing-00)
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |L|    Type     |     Length    |  ST   |     Flags     |F|S|C|M|
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                              SID                              |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    //                        NAI (variable)                       //
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+
+    NAI
+
+          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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                      Local IPv4 address                       |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                     Remote IPv4 address                       |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                        NAI for IPv4 Adjacency
+
+           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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //               Local IPv6 address (16 bytes)                 //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     //               Remote IPv6 address (16 bytes)                //
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+                       NAI for IPv6 adjacency
+
+           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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                      Local Node-ID                            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                    Local Interface ID                         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                      Remote Node-ID                           |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                   Remote Interface ID                         |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+           NAI for Unnumbered adjacency with IPv4 Node IDs
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(SrEroSubObject.class);
+
+    public static final short TYPE = 0x60; //TODO : type to be defined
+    public static final short LENGTH = 12;
+    public static final short VALUE_LENGTH = 10;
+    public static final int SET = 1;
+    public static final byte MFLAG_SET = 0x01;
+    public static final byte CFLAG_SET = 0x02;
+    public static final byte SFLAG_SET = 0x04;
+    public static final byte FFLAG_SET = 0x08;
+    public static final byte SHIFT_ST = 12;
+
+    private final boolean bFFlag;
+    private final boolean bSFlag;
+    private final boolean bCFlag;
+    private final boolean bMFlag;
+    private final byte st;
+
+    private final int sID;
+    private final PcepNai nai;
+
+    /**
+     * Constructor to initialize member variables.
+     *
+     * @param st SID type
+     * @param bFFlag F flag
+     * @param bSFlag S flag
+     * @param bCFlag C flag
+     * @param bMFlag M flag
+     * @param sID segment identifier value
+     * @param nai NAI associated with SID
+     */
+    public SrEroSubObject(byte st, boolean bFFlag, boolean bSFlag, boolean bCFlag, boolean bMFlag, int sID,
+            PcepNai nai) {
+        this.st = st;
+        this.bFFlag = bFFlag;
+        this.bSFlag = bSFlag;
+        this.bCFlag = bCFlag;
+        this.bMFlag = bMFlag;
+        this.sID = sID;
+        this.nai = nai;
+    }
+
+    /**
+     * Creates object of SrEroSubObject.
+     *
+     * @param st SID type
+     * @param bFFlag F flag
+     * @param bSFlag S flag
+     * @param bCFlag C flag
+     * @param bMFlag M flag
+     * @param sID segment identifier value
+     * @param nai NAI associated with SID
+     * @return object of SrEroSubObject
+     */
+    public static SrEroSubObject of(byte st, boolean bFFlag, boolean bSFlag, boolean bCFlag, boolean bMFlag, int sID,
+            PcepNai nai) {
+        return new SrEroSubObject(st, bFFlag, bSFlag, bCFlag, bMFlag, sID, nai);
+    }
+
+    /**
+     * Returns SID type.
+     * @return st sid type
+     */
+    public byte getSt() {
+        return st;
+    }
+
+    /**
+     * Returns bFFlag.
+     * @return bFFlag
+     */
+    public boolean getFFlag() {
+        return bFFlag;
+    }
+
+    /**
+     * Returns bSFlag.
+     * @return bSFlag
+     */
+    public boolean getSFlag() {
+        return bSFlag;
+    }
+
+    /**
+     * Returns bCFlag.
+     * @return bCFlag
+     */
+    public boolean getCFlag() {
+        return bCFlag;
+    }
+
+    /**
+     * Returns bMFlag.
+     * @return bMFlag
+     */
+    public boolean getMFlag() {
+        return bMFlag;
+    }
+
+    /**
+     * Returns sID.
+     * @return sID
+     */
+    public int getSID() {
+        return sID;
+    }
+
+    /**
+     * Returns nai.
+     * @return nai
+     */
+    public PcepNai getNai() {
+        return nai;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(st, bFFlag, bSFlag, bCFlag, bMFlag, sID, nai);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof SrEroSubObject) {
+            SrEroSubObject other = (SrEroSubObject) obj;
+            return Objects.equals(this.st, other.st) && Objects.equals(this.bFFlag, other.bFFlag)
+                    && Objects.equals(this.bSFlag, other.bSFlag) && Objects.equals(this.bCFlag, other.bCFlag)
+                    && Objects.equals(this.bMFlag, other.bMFlag) && Objects.equals(this.sID, other.sID)
+                    && Objects.equals(this.nai, other.nai);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+
+        short temp = 0;
+        if (bMFlag) {
+            temp = (short) (temp | MFLAG_SET);
+        }
+        if (bCFlag) {
+            temp = (short) (temp | CFLAG_SET);
+        }
+        if (bSFlag) {
+            temp = (short) (temp | SFLAG_SET);
+        }
+        if (bFFlag) {
+            temp = (short) (temp | FFLAG_SET);
+        }
+        short tempST = (short) (st << SHIFT_ST);
+        temp = (short) (temp | tempST);
+        c.writeShort(temp);
+        c.writeInt(sID);
+        nai.write(c);
+
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of SrEroSubObject.
+     * @param c of type channel buffer
+     * @return object of SrEroSubObject
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        short temp = c.readShort();
+        boolean bMFlag;
+        boolean bCFlag;
+        boolean bSFlag;
+        boolean bFFlag;
+        byte st;
+        PcepNai nai = null;
+
+        bMFlag = (temp & MFLAG_SET) == MFLAG_SET ? true : false;
+        bCFlag = (temp & CFLAG_SET) == CFLAG_SET ? true : false;
+        bSFlag = (temp & SFLAG_SET) == SFLAG_SET ? true : false;
+        bFFlag = (temp & FFLAG_SET) == FFLAG_SET ? true : false;
+
+        st = (byte) (temp >> SHIFT_ST);
+
+        int sID = c.readInt();
+        switch (st) {
+        case 0x01:
+            nai = PcepNaiIpv4NodeId.read(c);
+            break;
+        case 0x02:
+            nai = PcepNaiIpv6NodeId.read(c);
+            break;
+        case 0x03:
+            nai = PcepNaiIpv4Adjacency.read(c);
+            break;
+        case 0x04:
+            nai = PcepNaiIpv6Adjacency.read(c);
+            break;
+        case 0x05:
+            nai = PcepNaiUnnumberedAdjacencyIpv4.read(c);
+            break;
+        default:
+            nai = null;
+            break;
+        }
+
+        return new SrEroSubObject(st, bFFlag, bSFlag, bCFlag, bMFlag, sID, nai);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("Type", TYPE)
+                .add("Length", LENGTH)
+                .add("st", st)
+                .add("bFflag", bFFlag)
+                .add("bSFlag", bSFlag)
+                .add("bCFlag", bCFlag)
+                .add("bMFlag", bMFlag)
+                .add("sID", sID)
+                .add("nAI", nai)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulIPv4LspIdentidiersTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulIPv4LspIdentidiersTlv.java
index 863698f..020d31d 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulIPv4LspIdentidiersTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulIPv4LspIdentidiersTlv.java
@@ -1,210 +1,210 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides StatefulIPv4LspIdentidiersTlv.
- */
-public class StatefulIPv4LspIdentidiersTlv implements PcepValueType {
-
-    /*             IPV4-LSP-IDENTIFIERS TLV format
-     *
-     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
-     *
-
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |           Type=18             |           Length=16           |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                   IPv4 Tunnel Sender Address                  |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |             LSP ID            |           Tunnel ID           |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                        Extended Tunnel ID                     |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |               IPv4 Tunnel Endpoint Address                    |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(StatefulIPv4LspIdentidiersTlv.class);
-
-    public static final short TYPE = 18;
-    public static final short LENGTH = 16;
-    public static final int VALUE_LENGTH = 16;
-    private final int ipv4IngressAddress;
-    private final short lspId;
-    private final short tunnelId;
-    private final int extendedTunnelId;
-    private final int ipv4EgressAddress;
-
-    /**
-     * Constructor to initialize member variables.
-     *
-     * @param ipv4IngressAddress ingress ipv4 address
-     * @param lspId lsp id
-     * @param tunnelId tunnel id
-     * @param extendedTunnelId extended tunnel id
-     * @param ipv4EgressAddress egress ipv4 address
-     */
-    public StatefulIPv4LspIdentidiersTlv(int ipv4IngressAddress, short lspId, short tunnelId, int extendedTunnelId,
-            int ipv4EgressAddress) {
-
-        this.ipv4IngressAddress = ipv4IngressAddress;
-        this.lspId = lspId;
-        this.tunnelId = tunnelId;
-        this.extendedTunnelId = extendedTunnelId;
-        this.ipv4EgressAddress = ipv4EgressAddress;
-    }
-
-    /**
-     * Creates object of StatefulIPv4LspIdentidiersTlv.
-     *
-     * @param ipv4IngressAddress ingress ipv4 address
-     * @param lspId lsp id
-     * @param tunnelId tunnel id
-     * @param extendedTunnelId extended tunnel id
-     * @param ipv4EgressAddress egress ipv4 address
-     * @return object of StatefulIPv4LspIdentidiersTlv
-     */
-    public static StatefulIPv4LspIdentidiersTlv of(int ipv4IngressAddress, short lspId, short tunnelId,
-            int extendedTunnelId, int ipv4EgressAddress) {
-        return new StatefulIPv4LspIdentidiersTlv(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId,
-                ipv4EgressAddress);
-    }
-
-    /**
-     * Returns tunnel id.
-     *
-     * @return tunnelId
-     */
-    public short getTunnelId() {
-        return this.tunnelId;
-    }
-
-    /**
-     * Returns extendedTunnelId.
-     *
-     * @return extendedTunnelId
-     */
-    public int getextendedTunnelId() {
-        return this.extendedTunnelId;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    /**
-     * Returns ipv4IngressAddress.
-     *
-     * @return ipv4IngressAddress
-     */
-    public int getIpv4IngressAddress() {
-        return ipv4IngressAddress;
-    }
-
-    /**
-     * Returns ipv4EgressAddress.
-     *
-     * @return ipv4EgressAddress
-     */
-    public int getIpv4EgressAddress() {
-        return ipv4EgressAddress;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId, ipv4EgressAddress);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof StatefulIPv4LspIdentidiersTlv) {
-            StatefulIPv4LspIdentidiersTlv other = (StatefulIPv4LspIdentidiersTlv) obj;
-            return Objects.equals(this.ipv4IngressAddress, other.ipv4IngressAddress)
-                    && Objects.equals(this.lspId, other.lspId) && Objects.equals(this.tunnelId, other.tunnelId)
-                    && Objects.equals(this.extendedTunnelId, other.extendedTunnelId)
-                    && Objects.equals(this.ipv4EgressAddress, other.ipv4EgressAddress);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(ipv4IngressAddress);
-        c.writeShort(lspId);
-        c.writeShort(tunnelId);
-        c.writeInt(extendedTunnelId);
-        c.writeInt(ipv4EgressAddress);
-
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of StatefulIPv4LspIdentidiersTlv.
-     *
-     * @param c of type channel buffer
-     * @return object of StatefulIPv4LspIdentidiersTlv
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        int ipv4IngressAddress = c.readInt();
-        short lspId = c.readShort();
-        short tunnelId = c.readShort();
-        int extendedTunnelId = c.readInt();
-        int ipv4EgressAddress = c.readInt();
-        return new StatefulIPv4LspIdentidiersTlv(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId,
-                ipv4EgressAddress);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass())
-                .add("Type:", TYPE)
-                .add("Length:", LENGTH)
-                .add("Ipv4IngressAddress:", ipv4IngressAddress)
-                .add("LspId:", lspId).add("TunnelId:", tunnelId)
-                .add("ExtendedTunnelId:", extendedTunnelId)
-                .add("Ipv4EgressAddress:", ipv4EgressAddress).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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides StatefulIPv4LspIdentidiersTlv.
+ */
+public class StatefulIPv4LspIdentidiersTlv implements PcepValueType {
+
+    /*             IPV4-LSP-IDENTIFIERS TLV format
+     *
+     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
+     *
+
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |           Type=18             |           Length=16           |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                   IPv4 Tunnel Sender Address                  |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |             LSP ID            |           Tunnel ID           |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                        Extended Tunnel ID                     |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |               IPv4 Tunnel Endpoint Address                    |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(StatefulIPv4LspIdentidiersTlv.class);
+
+    public static final short TYPE = 18;
+    public static final short LENGTH = 16;
+    public static final int VALUE_LENGTH = 16;
+    private final int ipv4IngressAddress;
+    private final short lspId;
+    private final short tunnelId;
+    private final int extendedTunnelId;
+    private final int ipv4EgressAddress;
+
+    /**
+     * Constructor to initialize member variables.
+     *
+     * @param ipv4IngressAddress ingress ipv4 address
+     * @param lspId lsp id
+     * @param tunnelId tunnel id
+     * @param extendedTunnelId extended tunnel id
+     * @param ipv4EgressAddress egress ipv4 address
+     */
+    public StatefulIPv4LspIdentidiersTlv(int ipv4IngressAddress, short lspId, short tunnelId, int extendedTunnelId,
+            int ipv4EgressAddress) {
+
+        this.ipv4IngressAddress = ipv4IngressAddress;
+        this.lspId = lspId;
+        this.tunnelId = tunnelId;
+        this.extendedTunnelId = extendedTunnelId;
+        this.ipv4EgressAddress = ipv4EgressAddress;
+    }
+
+    /**
+     * Creates object of StatefulIPv4LspIdentidiersTlv.
+     *
+     * @param ipv4IngressAddress ingress ipv4 address
+     * @param lspId lsp id
+     * @param tunnelId tunnel id
+     * @param extendedTunnelId extended tunnel id
+     * @param ipv4EgressAddress egress ipv4 address
+     * @return object of StatefulIPv4LspIdentidiersTlv
+     */
+    public static StatefulIPv4LspIdentidiersTlv of(int ipv4IngressAddress, short lspId, short tunnelId,
+            int extendedTunnelId, int ipv4EgressAddress) {
+        return new StatefulIPv4LspIdentidiersTlv(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId,
+                ipv4EgressAddress);
+    }
+
+    /**
+     * Returns tunnel id.
+     *
+     * @return tunnelId
+     */
+    public short getTunnelId() {
+        return this.tunnelId;
+    }
+
+    /**
+     * Returns extendedTunnelId.
+     *
+     * @return extendedTunnelId
+     */
+    public int getextendedTunnelId() {
+        return this.extendedTunnelId;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    /**
+     * Returns ipv4IngressAddress.
+     *
+     * @return ipv4IngressAddress
+     */
+    public int getIpv4IngressAddress() {
+        return ipv4IngressAddress;
+    }
+
+    /**
+     * Returns ipv4EgressAddress.
+     *
+     * @return ipv4EgressAddress
+     */
+    public int getIpv4EgressAddress() {
+        return ipv4EgressAddress;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId, ipv4EgressAddress);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof StatefulIPv4LspIdentidiersTlv) {
+            StatefulIPv4LspIdentidiersTlv other = (StatefulIPv4LspIdentidiersTlv) obj;
+            return Objects.equals(this.ipv4IngressAddress, other.ipv4IngressAddress)
+                    && Objects.equals(this.lspId, other.lspId) && Objects.equals(this.tunnelId, other.tunnelId)
+                    && Objects.equals(this.extendedTunnelId, other.extendedTunnelId)
+                    && Objects.equals(this.ipv4EgressAddress, other.ipv4EgressAddress);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(ipv4IngressAddress);
+        c.writeShort(lspId);
+        c.writeShort(tunnelId);
+        c.writeInt(extendedTunnelId);
+        c.writeInt(ipv4EgressAddress);
+
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of StatefulIPv4LspIdentidiersTlv.
+     *
+     * @param c of type channel buffer
+     * @return object of StatefulIPv4LspIdentidiersTlv
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        int ipv4IngressAddress = c.readInt();
+        short lspId = c.readShort();
+        short tunnelId = c.readShort();
+        int extendedTunnelId = c.readInt();
+        int ipv4EgressAddress = c.readInt();
+        return new StatefulIPv4LspIdentidiersTlv(ipv4IngressAddress, lspId, tunnelId, extendedTunnelId,
+                ipv4EgressAddress);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass())
+                .add("Type:", TYPE)
+                .add("Length:", LENGTH)
+                .add("Ipv4IngressAddress:", ipv4IngressAddress)
+                .add("LspId:", lspId).add("TunnelId:", tunnelId)
+                .add("ExtendedTunnelId:", extendedTunnelId)
+                .add("Ipv4EgressAddress:", ipv4EgressAddress).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspDbVerTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspDbVerTlv.java
index 9677e99..8679b26 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspDbVerTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspDbVerTlv.java
@@ -1,139 +1,139 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides StatefulLspDbVerTlv.
- */
-public class StatefulLspDbVerTlv implements PcepValueType {
-
-    /*                  LSP-DB-VERSION TLV format
-     *
-     * Reference : Optimizations of Label Switched Path State Synchronization Procedures
-                           for a Stateful PCE draft-ietf-pce-stateful-sync-optimizations-02
-     *
-     *
-
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |           Type=23             |            Length=8           |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                      LSP State DB Version                     |
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(StatefulLspDbVerTlv.class);
-
-    public static final short TYPE = 23;
-    public static final short LENGTH = 8;
-    private final long rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue value
-     */
-    public StatefulLspDbVerTlv(final long rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns object of StatefulLspDbVerTlv.
-     *
-     * @param raw is LSP State DB Version
-     * @return object of StatefulLspDbVerTlv
-     */
-    public static StatefulLspDbVerTlv of(final long raw) {
-        return new StatefulLspDbVerTlv(raw);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    /**
-     * Returns LSP State DB Version.
-     *
-     * @return rawValue value
-     */
-    public long getLong() {
-        return rawValue;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof StatefulLspDbVerTlv) {
-            StatefulLspDbVerTlv other = (StatefulLspDbVerTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeLong(rawValue);
-        return c.writerIndex();
-    }
-
-    /**
-     * Reads the channel buffer and returns object of StatefulLspDbVerTlv.
-     *
-     * @param c input channel buffer
-     * @return object of StatefulLspDbVerTlv
-     */
-    public static StatefulLspDbVerTlv read(ChannelBuffer c) {
-        return StatefulLspDbVerTlv.of(c.readLong());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides StatefulLspDbVerTlv.
+ */
+public class StatefulLspDbVerTlv implements PcepValueType {
+
+    /*                  LSP-DB-VERSION TLV format
+     *
+     * Reference : Optimizations of Label Switched Path State Synchronization Procedures
+                           for a Stateful PCE draft-ietf-pce-stateful-sync-optimizations-02
+     *
+     *
+
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |           Type=23             |            Length=8           |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                      LSP State DB Version                     |
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(StatefulLspDbVerTlv.class);
+
+    public static final short TYPE = 23;
+    public static final short LENGTH = 8;
+    private final long rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue value
+     */
+    public StatefulLspDbVerTlv(final long rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns object of StatefulLspDbVerTlv.
+     *
+     * @param raw is LSP State DB Version
+     * @return object of StatefulLspDbVerTlv
+     */
+    public static StatefulLspDbVerTlv of(final long raw) {
+        return new StatefulLspDbVerTlv(raw);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    /**
+     * Returns LSP State DB Version.
+     *
+     * @return rawValue value
+     */
+    public long getLong() {
+        return rawValue;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof StatefulLspDbVerTlv) {
+            StatefulLspDbVerTlv other = (StatefulLspDbVerTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeLong(rawValue);
+        return c.writerIndex();
+    }
+
+    /**
+     * Reads the channel buffer and returns object of StatefulLspDbVerTlv.
+     *
+     * @param c input channel buffer
+     * @return object of StatefulLspDbVerTlv
+     */
+    public static StatefulLspDbVerTlv read(ChannelBuffer c) {
+        return StatefulLspDbVerTlv.of(c.readLong());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspErrorCodeTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspErrorCodeTlv.java
index 3239294..3d0515a 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspErrorCodeTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulLspErrorCodeTlv.java
@@ -1,139 +1,139 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides StatefulLspErrorCodeTlv.
- */
-public class StatefulLspErrorCodeTlv implements PcepValueType {
-
-    /*                  LSP-ERROR-CODE TLV format
-     *
-     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
-     *
-
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |           Type=20             |            Length=4           |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                          LSP Error Code                       |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(StatefulLspErrorCodeTlv.class);
-
-    public static final short TYPE = 20;
-    public static final short LENGTH = 4;
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize raw Value.
-     *
-     * @param rawValue lsp error code value
-     */
-    public StatefulLspErrorCodeTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Creates object of StatefulLspErrorCodeTlv.
-     *
-     * @param raw lsp error code value
-     * @return object of StatefulLspErrorCodeTlv
-     */
-    public static StatefulLspErrorCodeTlv of(int raw) {
-        return new StatefulLspErrorCodeTlv(raw);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    /**
-     * Returns lsp error code value.
-     *
-     * @return lsp error code value
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof StatefulLspErrorCodeTlv) {
-            StatefulLspErrorCodeTlv other = (StatefulLspErrorCodeTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of StatefulLspErrorCodeTlv.
-     *
-     * @param c of type channel buffer
-     * @return object of StatefulLspErrorCodeTlv
-     */
-    public static StatefulLspErrorCodeTlv read(ChannelBuffer c) {
-        return StatefulLspErrorCodeTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides StatefulLspErrorCodeTlv.
+ */
+public class StatefulLspErrorCodeTlv implements PcepValueType {
+
+    /*                  LSP-ERROR-CODE TLV format
+     *
+     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
+     *
+
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |           Type=20             |            Length=4           |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                          LSP Error Code                       |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(StatefulLspErrorCodeTlv.class);
+
+    public static final short TYPE = 20;
+    public static final short LENGTH = 4;
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize raw Value.
+     *
+     * @param rawValue lsp error code value
+     */
+    public StatefulLspErrorCodeTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Creates object of StatefulLspErrorCodeTlv.
+     *
+     * @param raw lsp error code value
+     * @return object of StatefulLspErrorCodeTlv
+     */
+    public static StatefulLspErrorCodeTlv of(int raw) {
+        return new StatefulLspErrorCodeTlv(raw);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    /**
+     * Returns lsp error code value.
+     *
+     * @return lsp error code value
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof StatefulLspErrorCodeTlv) {
+            StatefulLspErrorCodeTlv other = (StatefulLspErrorCodeTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of StatefulLspErrorCodeTlv.
+     *
+     * @param c of type channel buffer
+     * @return object of StatefulLspErrorCodeTlv
+     */
+    public static StatefulLspErrorCodeTlv read(ChannelBuffer c) {
+        return StatefulLspErrorCodeTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulPceCapabilityTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulPceCapabilityTlv.java
index 56fc4de..65e66dd 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulPceCapabilityTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulPceCapabilityTlv.java
@@ -1,262 +1,262 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides StatefulPceCapabilityTlv.
- */
-public class StatefulPceCapabilityTlv implements PcepValueType {
-
-    /*             STATEFUL-PCE-CAPABILITY TLV format
-     *
-     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
-
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |               Type=16         |            Length=4           |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                             Flags                   |D|T|I|S|U|
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(StatefulPceCapabilityTlv.class);
-
-    public static final short TYPE = 16;
-    public static final short LENGTH = 4;
-    public static final byte UFLAG_SET = 0x01;
-    public static final byte SFLAG_SET = 0x02;
-    public static final byte IFLAG_SET = 0x04;
-    public static final byte TFLAG_SET = 0x08;
-    public static final byte DFLAG_SET = 0x10;
-    public static final int SET = 1;
-
-    private final int rawValue;
-    private final boolean bDFlag;
-    private final boolean bTFlag;
-    private final boolean bIFlag;
-    private final boolean bSFlag;
-    private final boolean bUFlag;
-    private final boolean isRawValueSet;
-
-    /**
-     * Constructor to initialize variables.
-     *
-     * @param rawValue Flags
-     */
-    public StatefulPceCapabilityTlv(int rawValue) {
-        this.rawValue = rawValue;
-        isRawValueSet = true;
-        this.bUFlag = (rawValue & UFLAG_SET) == UFLAG_SET ? true : false;
-        this.bSFlag = (rawValue & SFLAG_SET) == SFLAG_SET ? true : false;
-        this.bIFlag = (rawValue & IFLAG_SET) == IFLAG_SET ? true : false;
-        this.bTFlag = (rawValue & TFLAG_SET) == TFLAG_SET ? true : false;
-        this.bDFlag = (rawValue & DFLAG_SET) == DFLAG_SET ? true : false;
-    }
-
-    /**
-     * Constructor to initialize variables.
-     *
-     * @param bDFlag D-flag
-     * @param bTFlag T-flag
-     * @param bIFlag I-flag
-     * @param bSFlag S-flag
-     * @param bUFlag U-flag
-     */
-    public StatefulPceCapabilityTlv(boolean bDFlag, boolean bTFlag, boolean bIFlag, boolean bSFlag, boolean bUFlag) {
-        this.bDFlag = bDFlag;
-        this.bTFlag = bTFlag;
-        this.bIFlag = bIFlag;
-        this.bSFlag = bSFlag;
-        this.bUFlag = bUFlag;
-        this.rawValue = 0;
-        isRawValueSet = false;
-    }
-
-    /**
-     * Returns object of StatefulPceCapabilityTlv.
-     *
-     * @param raw value Flags
-     * @return object of StatefulPceCapabilityTlv
-     */
-    public static StatefulPceCapabilityTlv of(final int raw) {
-        return new StatefulPceCapabilityTlv(raw);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    /**
-     * Returns D-flag.
-     *
-     * @return bDFlag D-flag
-     */
-    public boolean getDFlag() {
-        return bDFlag;
-    }
-
-    /**
-     * Returns T-flag.
-     *
-     * @return bTFlag T-flag
-     */
-    public boolean getTFlag() {
-        return bTFlag;
-    }
-
-    /**
-     * Returns I-flag.
-     *
-     * @return bIFlag I-flag
-     */
-    public boolean getIFlag() {
-        return bIFlag;
-    }
-
-    /**
-     * Returns S-flag.
-     *
-     * @return bSFlag S-flag
-     */
-    public boolean getSFlag() {
-        return bSFlag;
-    }
-
-    /**
-     * Returns U-flag.
-     *
-     * @return bUFlag U-flag
-     */
-    public boolean getUFlag() {
-        return bUFlag;
-    }
-
-    /**
-     * Returns raw value Flags.
-     *
-     * @return rawValue Flags
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        if (isRawValueSet) {
-            return Objects.hash(rawValue);
-        } else {
-            return Objects.hash(bDFlag, bTFlag, bIFlag, bSFlag, bUFlag);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof StatefulPceCapabilityTlv) {
-            StatefulPceCapabilityTlv other = (StatefulPceCapabilityTlv) obj;
-            if (isRawValueSet) {
-                return Objects.equals(this.rawValue, other.rawValue);
-            } else {
-                return Objects.equals(this.bDFlag, other.bDFlag) && Objects.equals(this.bTFlag, other.bTFlag)
-                        && Objects.equals(this.bIFlag, other.bIFlag) && Objects.equals(this.bSFlag, other.bSFlag)
-                        && Objects.equals(this.bUFlag, other.bUFlag);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        if (isRawValueSet) {
-            c.writeInt(rawValue);
-        } else {
-            int temp = 0;
-            if (bUFlag) {
-                temp = temp | UFLAG_SET;
-            }
-            if (bSFlag) {
-                temp = temp | SFLAG_SET;
-            }
-            if (bIFlag) {
-                temp = temp | IFLAG_SET;
-            }
-            if (bTFlag) {
-                temp = temp | TFLAG_SET;
-            }
-            if (bDFlag) {
-                temp = temp | DFLAG_SET;
-            }
-            c.writeInt(temp);
-        }
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads from channel buffer and returns object of StatefulPceCapabilityTlv.
-     *
-     * @param c input channel buffer
-     * @return object of StatefulPceCapabilityTlv
-     */
-    public static PcepValueType read(ChannelBuffer c) {
-        int temp = c.readInt();
-        boolean bDFlag;
-        boolean bTFlag;
-        boolean bIFlag;
-        boolean bSFlag;
-        boolean bUFlag;
-
-        bUFlag = (temp & UFLAG_SET) == UFLAG_SET ? true : false;
-        bSFlag = (temp & SFLAG_SET) == SFLAG_SET ? true : false;
-        bIFlag = (temp & IFLAG_SET) == IFLAG_SET ? true : false;
-        bTFlag = (temp & TFLAG_SET) == TFLAG_SET ? true : false;
-        bDFlag = (temp & DFLAG_SET) == DFLAG_SET ? true : false;
-
-        return new StatefulPceCapabilityTlv(bDFlag, bTFlag, bIFlag, bSFlag, bUFlag);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("type", TYPE).add("Length", LENGTH).add("DFlag", bDFlag)
-                .add("TFlag", bTFlag).add("IFlag", bIFlag).add("SFlag", bSFlag).add("UFlag", bUFlag).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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides StatefulPceCapabilityTlv.
+ */
+public class StatefulPceCapabilityTlv implements PcepValueType {
+
+    /*             STATEFUL-PCE-CAPABILITY TLV format
+     *
+     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
+
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |               Type=16         |            Length=4           |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                             Flags                   |D|T|I|S|U|
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(StatefulPceCapabilityTlv.class);
+
+    public static final short TYPE = 16;
+    public static final short LENGTH = 4;
+    public static final byte UFLAG_SET = 0x01;
+    public static final byte SFLAG_SET = 0x02;
+    public static final byte IFLAG_SET = 0x04;
+    public static final byte TFLAG_SET = 0x08;
+    public static final byte DFLAG_SET = 0x10;
+    public static final int SET = 1;
+
+    private final int rawValue;
+    private final boolean bDFlag;
+    private final boolean bTFlag;
+    private final boolean bIFlag;
+    private final boolean bSFlag;
+    private final boolean bUFlag;
+    private final boolean isRawValueSet;
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param rawValue Flags
+     */
+    public StatefulPceCapabilityTlv(int rawValue) {
+        this.rawValue = rawValue;
+        isRawValueSet = true;
+        this.bUFlag = (rawValue & UFLAG_SET) == UFLAG_SET ? true : false;
+        this.bSFlag = (rawValue & SFLAG_SET) == SFLAG_SET ? true : false;
+        this.bIFlag = (rawValue & IFLAG_SET) == IFLAG_SET ? true : false;
+        this.bTFlag = (rawValue & TFLAG_SET) == TFLAG_SET ? true : false;
+        this.bDFlag = (rawValue & DFLAG_SET) == DFLAG_SET ? true : false;
+    }
+
+    /**
+     * Constructor to initialize variables.
+     *
+     * @param bDFlag D-flag
+     * @param bTFlag T-flag
+     * @param bIFlag I-flag
+     * @param bSFlag S-flag
+     * @param bUFlag U-flag
+     */
+    public StatefulPceCapabilityTlv(boolean bDFlag, boolean bTFlag, boolean bIFlag, boolean bSFlag, boolean bUFlag) {
+        this.bDFlag = bDFlag;
+        this.bTFlag = bTFlag;
+        this.bIFlag = bIFlag;
+        this.bSFlag = bSFlag;
+        this.bUFlag = bUFlag;
+        this.rawValue = 0;
+        isRawValueSet = false;
+    }
+
+    /**
+     * Returns object of StatefulPceCapabilityTlv.
+     *
+     * @param raw value Flags
+     * @return object of StatefulPceCapabilityTlv
+     */
+    public static StatefulPceCapabilityTlv of(final int raw) {
+        return new StatefulPceCapabilityTlv(raw);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    /**
+     * Returns D-flag.
+     *
+     * @return bDFlag D-flag
+     */
+    public boolean getDFlag() {
+        return bDFlag;
+    }
+
+    /**
+     * Returns T-flag.
+     *
+     * @return bTFlag T-flag
+     */
+    public boolean getTFlag() {
+        return bTFlag;
+    }
+
+    /**
+     * Returns I-flag.
+     *
+     * @return bIFlag I-flag
+     */
+    public boolean getIFlag() {
+        return bIFlag;
+    }
+
+    /**
+     * Returns S-flag.
+     *
+     * @return bSFlag S-flag
+     */
+    public boolean getSFlag() {
+        return bSFlag;
+    }
+
+    /**
+     * Returns U-flag.
+     *
+     * @return bUFlag U-flag
+     */
+    public boolean getUFlag() {
+        return bUFlag;
+    }
+
+    /**
+     * Returns raw value Flags.
+     *
+     * @return rawValue Flags
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        if (isRawValueSet) {
+            return Objects.hash(rawValue);
+        } else {
+            return Objects.hash(bDFlag, bTFlag, bIFlag, bSFlag, bUFlag);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof StatefulPceCapabilityTlv) {
+            StatefulPceCapabilityTlv other = (StatefulPceCapabilityTlv) obj;
+            if (isRawValueSet) {
+                return Objects.equals(this.rawValue, other.rawValue);
+            } else {
+                return Objects.equals(this.bDFlag, other.bDFlag) && Objects.equals(this.bTFlag, other.bTFlag)
+                        && Objects.equals(this.bIFlag, other.bIFlag) && Objects.equals(this.bSFlag, other.bSFlag)
+                        && Objects.equals(this.bUFlag, other.bUFlag);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        if (isRawValueSet) {
+            c.writeInt(rawValue);
+        } else {
+            int temp = 0;
+            if (bUFlag) {
+                temp = temp | UFLAG_SET;
+            }
+            if (bSFlag) {
+                temp = temp | SFLAG_SET;
+            }
+            if (bIFlag) {
+                temp = temp | IFLAG_SET;
+            }
+            if (bTFlag) {
+                temp = temp | TFLAG_SET;
+            }
+            if (bDFlag) {
+                temp = temp | DFLAG_SET;
+            }
+            c.writeInt(temp);
+        }
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads from channel buffer and returns object of StatefulPceCapabilityTlv.
+     *
+     * @param c input channel buffer
+     * @return object of StatefulPceCapabilityTlv
+     */
+    public static PcepValueType read(ChannelBuffer c) {
+        int temp = c.readInt();
+        boolean bDFlag;
+        boolean bTFlag;
+        boolean bIFlag;
+        boolean bSFlag;
+        boolean bUFlag;
+
+        bUFlag = (temp & UFLAG_SET) == UFLAG_SET ? true : false;
+        bSFlag = (temp & SFLAG_SET) == SFLAG_SET ? true : false;
+        bIFlag = (temp & IFLAG_SET) == IFLAG_SET ? true : false;
+        bTFlag = (temp & TFLAG_SET) == TFLAG_SET ? true : false;
+        bDFlag = (temp & DFLAG_SET) == DFLAG_SET ? true : false;
+
+        return new StatefulPceCapabilityTlv(bDFlag, bTFlag, bIFlag, bSFlag, bUFlag);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("type", TYPE).add("Length", LENGTH).add("DFlag", bDFlag)
+                .add("TFlag", bTFlag).add("IFlag", bIFlag).add("SFlag", bSFlag).add("UFlag", bUFlag).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulRsvpErrorSpecTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulRsvpErrorSpecTlv.java
index d89904e..0eba814 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulRsvpErrorSpecTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/StatefulRsvpErrorSpecTlv.java
@@ -1,219 +1,219 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-
-/**
- * Provides StatefulRsvpErrorSpecTlv.
- */
-public class StatefulRsvpErrorSpecTlv implements PcepValueType {
-
-    protected static final Logger log = LoggerFactory.getLogger(StatefulRsvpErrorSpecTlv.class);
-
-    /*                  RSVP-ERROR-SPEC TLV format
-     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
-     *
-     *
-
-    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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |           Type=21             |            Length (variable)  |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                                                               |
-    +                RSVP ERROR_SPEC or USER_ERROR_SPEC Object      +
-    |                                                               |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-        0             1              2             3
-    +-------------+-------------+-------------+-------------+
-    |       Length (bytes)      |  Class-Num  |   C-Type    |
-    +-------------+-------------+-------------+-------------+
-    |                                                       |
-    //                  (Object contents)                   //
-    |                                                       |
-    +-------------+-------------+-------------+-------------+
-
-    Ref :  ERROR_SPEC @ RFC2205
-
-    IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
-    +-------------+-------------+-------------+-------------+
-    |            IPv4 Error Node Address (4 bytes)          |
-    +-------------+-------------+-------------+-------------+
-    |    Flags    |  Error Code |        Error Value        |
-    +-------------+-------------+-------------+-------------+
-
-
-    IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
-    +-------------+-------------+-------------+-------------+
-    |                                                       |
-    +                                                       +
-    |                                                       |
-    +           IPv6 Error Node Address (16 bytes)          +
-    |                                                       |
-    +                                                       +
-    |                                                       |
-    +-------------+-------------+-------------+-------------+
-    |    Flags    |  Error Code |        Error Value        |
-    +-------------+-------------+-------------+-------------+
-
-
-    Ref : USER_ERROR_SPEC @ RFC5284
-    USER_ERROR_SPEC object: Class = 194, C-Type = 1
-    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
-    +---------------+---------------+---------------+---------------+
-    |                       Enterprise Number                       |
-    +---------------+---------------+---------------+---------------+
-    |    Sub Org    |  Err Desc Len |        User Error Value       |
-    +---------------+---------------+---------------+---------------+
-    |                                                               |
-    ~                       Error Description                       ~
-    |                                                               |
-    +---------------+---------------+---------------+---------------+
-    |                                                               |
-    ~                     User-Defined Subobjects                   ~
-    |                                                               |
-    +---------------+---------------+---------------+---------------+
-
-     */
-
-    public static final short TYPE = 21;
-    public static final int OBJECT_HEADER_LENGTH = 4;
-    private short hLength;
-
-    private final PcepRsvpErrorSpec rsvpErrSpecObj;
-    private final boolean isErrSpceObjSet;
-
-    /**
-     * Constructor to initialize errSpecObj.
-     *
-     * @param rsvpErrSpecObj Rsvp error spec object
-     */
-    public StatefulRsvpErrorSpecTlv(PcepRsvpErrorSpec rsvpErrSpecObj) {
-        this.rsvpErrSpecObj = rsvpErrSpecObj;
-        this.isErrSpceObjSet = true;
-    }
-
-    /**
-     * Returns PcepRsvpErrorSpecObject.
-     *
-     * @return rsvpErrSpecObj
-     */
-    public PcepRsvpErrorSpec getPcepRsvpErrorSpec() {
-        return this.rsvpErrSpecObj;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    /**
-     * Reads channel buffer and returns object of StatefulRsvpErrorSpecTlv.
-     *
-     * @param cb of type channel buffer
-     * @return object of StatefulRsvpErrorSpecTlv
-     * @throws PcepParseException while parsing this tlv from channel buffer
-     */
-    public static PcepValueType read(ChannelBuffer cb) throws PcepParseException {
-
-        PcepRsvpErrorSpec rsvpErrSpecObj = null;
-        PcepRsvpSpecObjHeader rsvpErrSpecObjHeader;
-
-        cb.markReaderIndex();
-        rsvpErrSpecObjHeader = PcepRsvpSpecObjHeader.read(cb);
-        cb.resetReaderIndex();
-
-        if (PcepRsvpIpv4ErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
-                && PcepRsvpIpv4ErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
-            rsvpErrSpecObj = PcepRsvpIpv4ErrorSpec.read(cb);
-        } else if (PcepRsvpIpv6ErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
-                && PcepRsvpIpv6ErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
-            rsvpErrSpecObj = PcepRsvpIpv6ErrorSpec.read(cb);
-        } else if (PcepRsvpUserErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
-                && PcepRsvpUserErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
-            rsvpErrSpecObj = PcepRsvpUserErrorSpec.read(cb);
-        }
-        return new StatefulRsvpErrorSpecTlv(rsvpErrSpecObj);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rsvpErrSpecObj.hashCode());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof StatefulRsvpErrorSpecTlv) {
-            StatefulRsvpErrorSpecTlv other = (StatefulRsvpErrorSpecTlv) obj;
-            return Objects.equals(this.rsvpErrSpecObj, other.rsvpErrSpecObj);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        int tlvLenIndex = c.writerIndex();
-        hLength = 0;
-        c.writeShort(hLength);
-        if (isErrSpceObjSet) {
-            rsvpErrSpecObj.write(c);
-        }
-        hLength = (short) (c.writerIndex() - iStartIndex);
-        c.setShort(tlvLenIndex, (hLength - OBJECT_HEADER_LENGTH));
-
-        return c.writerIndex() - iStartIndex;
-    }
-
-    @Override
-    public String toString() {
-        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
-
-        if (!isErrSpceObjSet) {
-            toStrHelper.add("Type", TYPE).add("Length", hLength);
-        } else {
-            toStrHelper.add("Type", TYPE).add("Length", hLength).add("RSVPErrorSpecObject", rsvpErrSpecObj);
-        }
-        return toStrHelper.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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.MoreObjects.ToStringHelper;
+
+/**
+ * Provides StatefulRsvpErrorSpecTlv.
+ */
+public class StatefulRsvpErrorSpecTlv implements PcepValueType {
+
+    protected static final Logger log = LoggerFactory.getLogger(StatefulRsvpErrorSpecTlv.class);
+
+    /*                  RSVP-ERROR-SPEC TLV format
+     * Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
+     *
+     *
+
+    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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |           Type=21             |            Length (variable)  |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                                                               |
+    +                RSVP ERROR_SPEC or USER_ERROR_SPEC Object      +
+    |                                                               |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+        0             1              2             3
+    +-------------+-------------+-------------+-------------+
+    |       Length (bytes)      |  Class-Num  |   C-Type    |
+    +-------------+-------------+-------------+-------------+
+    |                                                       |
+    //                  (Object contents)                   //
+    |                                                       |
+    +-------------+-------------+-------------+-------------+
+
+    Ref :  ERROR_SPEC @ RFC2205
+
+    IPv4 ERROR_SPEC object: Class = 6, C-Type = 1
+    +-------------+-------------+-------------+-------------+
+    |            IPv4 Error Node Address (4 bytes)          |
+    +-------------+-------------+-------------+-------------+
+    |    Flags    |  Error Code |        Error Value        |
+    +-------------+-------------+-------------+-------------+
+
+
+    IPv6 ERROR_SPEC object: Class = 6, C-Type = 2
+    +-------------+-------------+-------------+-------------+
+    |                                                       |
+    +                                                       +
+    |                                                       |
+    +           IPv6 Error Node Address (16 bytes)          +
+    |                                                       |
+    +                                                       +
+    |                                                       |
+    +-------------+-------------+-------------+-------------+
+    |    Flags    |  Error Code |        Error Value        |
+    +-------------+-------------+-------------+-------------+
+
+
+    Ref : USER_ERROR_SPEC @ RFC5284
+    USER_ERROR_SPEC object: Class = 194, C-Type = 1
+    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
+    +---------------+---------------+---------------+---------------+
+    |                       Enterprise Number                       |
+    +---------------+---------------+---------------+---------------+
+    |    Sub Org    |  Err Desc Len |        User Error Value       |
+    +---------------+---------------+---------------+---------------+
+    |                                                               |
+    ~                       Error Description                       ~
+    |                                                               |
+    +---------------+---------------+---------------+---------------+
+    |                                                               |
+    ~                     User-Defined Subobjects                   ~
+    |                                                               |
+    +---------------+---------------+---------------+---------------+
+
+     */
+
+    public static final short TYPE = 21;
+    public static final int OBJECT_HEADER_LENGTH = 4;
+    private short hLength;
+
+    private final PcepRsvpErrorSpec rsvpErrSpecObj;
+    private final boolean isErrSpceObjSet;
+
+    /**
+     * Constructor to initialize errSpecObj.
+     *
+     * @param rsvpErrSpecObj Rsvp error spec object
+     */
+    public StatefulRsvpErrorSpecTlv(PcepRsvpErrorSpec rsvpErrSpecObj) {
+        this.rsvpErrSpecObj = rsvpErrSpecObj;
+        this.isErrSpceObjSet = true;
+    }
+
+    /**
+     * Returns PcepRsvpErrorSpecObject.
+     *
+     * @return rsvpErrSpecObj
+     */
+    public PcepRsvpErrorSpec getPcepRsvpErrorSpec() {
+        return this.rsvpErrSpecObj;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    /**
+     * Reads channel buffer and returns object of StatefulRsvpErrorSpecTlv.
+     *
+     * @param cb of type channel buffer
+     * @return object of StatefulRsvpErrorSpecTlv
+     * @throws PcepParseException while parsing this tlv from channel buffer
+     */
+    public static PcepValueType read(ChannelBuffer cb) throws PcepParseException {
+
+        PcepRsvpErrorSpec rsvpErrSpecObj = null;
+        PcepRsvpSpecObjHeader rsvpErrSpecObjHeader;
+
+        cb.markReaderIndex();
+        rsvpErrSpecObjHeader = PcepRsvpSpecObjHeader.read(cb);
+        cb.resetReaderIndex();
+
+        if (PcepRsvpIpv4ErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
+                && PcepRsvpIpv4ErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
+            rsvpErrSpecObj = PcepRsvpIpv4ErrorSpec.read(cb);
+        } else if (PcepRsvpIpv6ErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
+                && PcepRsvpIpv6ErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
+            rsvpErrSpecObj = PcepRsvpIpv6ErrorSpec.read(cb);
+        } else if (PcepRsvpUserErrorSpec.CLASS_NUM == rsvpErrSpecObjHeader.getObjClassNum()
+                && PcepRsvpUserErrorSpec.CLASS_TYPE == rsvpErrSpecObjHeader.getObjClassType()) {
+            rsvpErrSpecObj = PcepRsvpUserErrorSpec.read(cb);
+        }
+        return new StatefulRsvpErrorSpecTlv(rsvpErrSpecObj);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rsvpErrSpecObj.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof StatefulRsvpErrorSpecTlv) {
+            StatefulRsvpErrorSpecTlv other = (StatefulRsvpErrorSpecTlv) obj;
+            return Objects.equals(this.rsvpErrSpecObj, other.rsvpErrSpecObj);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        int tlvLenIndex = c.writerIndex();
+        hLength = 0;
+        c.writeShort(hLength);
+        if (isErrSpceObjSet) {
+            rsvpErrSpecObj.write(c);
+        }
+        hLength = (short) (c.writerIndex() - iStartIndex);
+        c.setShort(tlvLenIndex, (hLength - OBJECT_HEADER_LENGTH));
+
+        return c.writerIndex() - iStartIndex;
+    }
+
+    @Override
+    public String toString() {
+        ToStringHelper toStrHelper = MoreObjects.toStringHelper(getClass());
+
+        if (!isErrSpceObjSet) {
+            toStrHelper.add("Type", TYPE).add("Length", hLength);
+        } else {
+            toStrHelper.add("Type", TYPE).add("Length", hLength).add("RSVPErrorSpecObject", rsvpErrSpecObj);
+        }
+        return toStrHelper.toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SymbolicPathNameTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SymbolicPathNameTlv.java
index 12cf435..bf7e7a1 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SymbolicPathNameTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/SymbolicPathNameTlv.java
@@ -1,157 +1,157 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides SymbolicPathNameTlv.
- */
-public class SymbolicPathNameTlv implements PcepValueType {
-
-    /*
-     *    SYMBOLIC-PATH-NAME TLV format
-     *    Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
-     *
-         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
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |           Type=17             |       Length (variable)       |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-         |                                                               |
-         //                      Symbolic Path Name                     //
-         |                                                               |
-         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-    protected static final Logger log = LoggerFactory.getLogger(SymbolicPathNameTlv.class);
-
-    public static final short TYPE = 17;
-    private short hLength;
-
-    private final byte[] rawValue;
-
-    /**
-     * Constructor to initialize raw Value.
-     *
-     * @param rawValue Symbolic path name
-     */
-    public SymbolicPathNameTlv(byte[] rawValue) {
-        this.rawValue = rawValue;
-        this.hLength = (short) rawValue.length;
-    }
-
-    /**
-     * Constructor to initialize raw Value.
-     *
-     * @param rawValue Symbolic path name
-     * @param hLength length of Symbolic path name
-     */
-    public SymbolicPathNameTlv(byte[] rawValue, short hLength) {
-        this.rawValue = rawValue;
-        if (0 == hLength) {
-            this.hLength = (short) rawValue.length;
-        } else {
-            this.hLength = hLength;
-        }
-    }
-
-    /**
-     * Creates an object of SymbolicPathNameTlv.
-     *
-     * @param raw Symbolic path name
-     * @param hLength length of Symbolic path name
-     * @return object of SymbolicPathNameTlv
-     */
-    public static SymbolicPathNameTlv of(final byte[] raw, short hLength) {
-        return new SymbolicPathNameTlv(raw, hLength);
-    }
-
-    /**
-     * Returns Symbolic path name.
-     *
-     * @return Symbolic path name byte array
-     */
-    public byte[] getValue() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof SymbolicPathNameTlv) {
-            SymbolicPathNameTlv other = (SymbolicPathNameTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(hLength);
-        c.writeBytes(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads channel buffer and returns object of SymbolicPathNameTlv.
-     *
-     * @param c of type channel buffer
-     * @param hLength length of bytes to read
-     * @return object of SymbolicPathNameTlv
-     */
-    public static SymbolicPathNameTlv read(ChannelBuffer c, short hLength) {
-        byte[] symbolicPathName = new byte[hLength];
-        c.readBytes(symbolicPathName, 0, hLength);
-        return new SymbolicPathNameTlv(symbolicPathName, hLength);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("SymbolicPathName ", rawValue).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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides SymbolicPathNameTlv.
+ */
+public class SymbolicPathNameTlv implements PcepValueType {
+
+    /*
+     *    SYMBOLIC-PATH-NAME TLV format
+     *    Reference :PCEP Extensions for Stateful PCE draft-ietf-pce-stateful-pce-10
+     *
+         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
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |           Type=17             |       Length (variable)       |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               |
+         //                      Symbolic Path Name                     //
+         |                                                               |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(SymbolicPathNameTlv.class);
+
+    public static final short TYPE = 17;
+    private short hLength;
+
+    private final byte[] rawValue;
+
+    /**
+     * Constructor to initialize raw Value.
+     *
+     * @param rawValue Symbolic path name
+     */
+    public SymbolicPathNameTlv(byte[] rawValue) {
+        this.rawValue = rawValue;
+        this.hLength = (short) rawValue.length;
+    }
+
+    /**
+     * Constructor to initialize raw Value.
+     *
+     * @param rawValue Symbolic path name
+     * @param hLength length of Symbolic path name
+     */
+    public SymbolicPathNameTlv(byte[] rawValue, short hLength) {
+        this.rawValue = rawValue;
+        if (0 == hLength) {
+            this.hLength = (short) rawValue.length;
+        } else {
+            this.hLength = hLength;
+        }
+    }
+
+    /**
+     * Creates an object of SymbolicPathNameTlv.
+     *
+     * @param raw Symbolic path name
+     * @param hLength length of Symbolic path name
+     * @return object of SymbolicPathNameTlv
+     */
+    public static SymbolicPathNameTlv of(final byte[] raw, short hLength) {
+        return new SymbolicPathNameTlv(raw, hLength);
+    }
+
+    /**
+     * Returns Symbolic path name.
+     *
+     * @return Symbolic path name byte array
+     */
+    public byte[] getValue() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof SymbolicPathNameTlv) {
+            SymbolicPathNameTlv other = (SymbolicPathNameTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(hLength);
+        c.writeBytes(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads channel buffer and returns object of SymbolicPathNameTlv.
+     *
+     * @param c of type channel buffer
+     * @param hLength length of bytes to read
+     * @return object of SymbolicPathNameTlv
+     */
+    public static SymbolicPathNameTlv read(ChannelBuffer c, short hLength) {
+        byte[] symbolicPathName = new byte[hLength];
+        c.readBytes(symbolicPathName, 0, hLength);
+        return new SymbolicPathNameTlv(symbolicPathName, hLength);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("SymbolicPathName ", rawValue).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TEDefaultMetricTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TEDefaultMetricTlv.java
index 80e043e..f4c6a28 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TEDefaultMetricTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TEDefaultMetricTlv.java
@@ -1,134 +1,134 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides TEDefaultMetricTlv.
- */
-public class TEDefaultMetricTlv implements PcepValueType {
-
-    /*
-     * Reference :| [I-D.ietf-idr- ls-distribution] /3.3.2.3
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |              Type=TDB37       |             Length=4          |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                    TE Default Link Metric                     |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-    protected static final Logger log = LoggerFactory.getLogger(TEDefaultMetricTlv.class);
-
-    public static final short TYPE = 13400; //TDB37
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue TE Default Link Metric
-     */
-    public TEDefaultMetricTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created TEDefaultMetricTlv object.
-     *
-     * @param raw raw value
-     * @return object of TEDefaultMetricTlv.
-     */
-    public static TEDefaultMetricTlv of(final int raw) {
-        return new TEDefaultMetricTlv(raw);
-    }
-
-    /**
-     * Returns raw value.
-     *
-     * @return rawValue TE Default Link Metric
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof TEDefaultMetricTlv) {
-            TEDefaultMetricTlv other = (TEDefaultMetricTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads channel buffer and returns object of TEDefaultMetricTlv.
-     *
-     * @param c input channel buffer
-     * @return object of TEDefaultMetricTlv
-     */
-    public static TEDefaultMetricTlv read(ChannelBuffer c) {
-        return TEDefaultMetricTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides TEDefaultMetricTlv.
+ */
+public class TEDefaultMetricTlv implements PcepValueType {
+
+    /*
+     * Reference :| [I-D.ietf-idr- ls-distribution] /3.3.2.3
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |              Type=TDB37       |             Length=4          |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                    TE Default Link Metric                     |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+    protected static final Logger log = LoggerFactory.getLogger(TEDefaultMetricTlv.class);
+
+    public static final short TYPE = 13400; //TDB37
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue TE Default Link Metric
+     */
+    public TEDefaultMetricTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created TEDefaultMetricTlv object.
+     *
+     * @param raw raw value
+     * @return object of TEDefaultMetricTlv.
+     */
+    public static TEDefaultMetricTlv of(final int raw) {
+        return new TEDefaultMetricTlv(raw);
+    }
+
+    /**
+     * Returns raw value.
+     *
+     * @return rawValue TE Default Link Metric
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TEDefaultMetricTlv) {
+            TEDefaultMetricTlv other = (TEDefaultMetricTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads channel buffer and returns object of TEDefaultMetricTlv.
+     *
+     * @param c input channel buffer
+     * @return object of TEDefaultMetricTlv
+     */
+    public static TEDefaultMetricTlv read(ChannelBuffer c) {
+        return TEDefaultMetricTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkAttributesTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkAttributesTlv.java
index 6ff9abf..1a13de5 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkAttributesTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkAttributesTlv.java
@@ -1,289 +1,289 @@
-/*
- * 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.types;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides TELinkAttributesTlv.
- */
-public class TELinkAttributesTlv implements PcepValueType {
-
-    /*
-     * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
-     *  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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD27]        |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                                                               |
-     //              Link Attributes Sub-TLVs (variable)            //
-     |                                                               |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(TELinkAttributesTlv.class);
-
-    public static final short TYPE = 1897; //TODD:change this TBD27
-    public short hLength;
-
-    public static final int TLV_HEADER_LENGTH = 4;
-
-    // LinkDescriptors Sub-TLVs (variable)
-    private LinkedList<PcepValueType> llLinkAttributesSubTLVs;
-
-    /**
-     * Constructor to initialize Link Attributes Sub TLVs.
-     *
-     * @param llLinkAttributesSubTLVs linked list of PcepValueType
-     */
-    public TELinkAttributesTlv(LinkedList<PcepValueType> llLinkAttributesSubTLVs) {
-        this.llLinkAttributesSubTLVs = llLinkAttributesSubTLVs;
-    }
-
-    /**
-     * Returns object of TE Link Attributes TLV.
-     *
-     * @param llLinkAttributesSubTLVs linked list of Link Attribute of Sub TLV
-     * @return object of TELinkAttributesTlv
-     */
-    public static TELinkAttributesTlv of(final LinkedList<PcepValueType> llLinkAttributesSubTLVs) {
-        return new TELinkAttributesTlv(llLinkAttributesSubTLVs);
-    }
-
-    /**
-     * Returns linked list of Link Attribute of Sub TLV.
-     *
-     * @return llLinkAttributesSubTLVs linked list of Link Attribute of Sub TLV
-     */
-    public LinkedList<PcepValueType> getllLinkAttributesSubTLVs() {
-        return llLinkAttributesSubTLVs;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(llLinkAttributesSubTLVs.hashCode());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        /*
-         * Here we have a list of Tlv so to compare each sub tlv between the object
-         * we have to take a list iterator so one by one we can get each sub tlv object
-         * and can compare them.
-         * it may be possible that the size of 2 lists is not equal so we have to first check
-         * the size, if both are same then we should check for the subtlv objects otherwise
-         * we should return false.
-         */
-        if (obj instanceof TELinkAttributesTlv) {
-            int countObjSubTlv = 0;
-            int countOtherSubTlv = 0;
-            boolean isCommonSubTlv = true;
-            TELinkAttributesTlv other = (TELinkAttributesTlv) obj;
-            Iterator<PcepValueType> objListIterator = ((TELinkAttributesTlv) obj).llLinkAttributesSubTLVs.iterator();
-            countObjSubTlv = ((TELinkAttributesTlv) obj).llLinkAttributesSubTLVs.size();
-            countOtherSubTlv = other.llLinkAttributesSubTLVs.size();
-            if (countObjSubTlv != countOtherSubTlv) {
-                return false;
-            } else {
-                while (objListIterator.hasNext() && isCommonSubTlv) {
-                    PcepValueType subTlv = objListIterator.next();
-                    isCommonSubTlv = Objects.equals(llLinkAttributesSubTLVs.contains(subTlv),
-                            other.llLinkAttributesSubTLVs.contains(subTlv));
-                }
-                return isCommonSubTlv;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int tlvStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        int tlvLenIndex = c.writerIndex();
-        hLength = 0;
-        c.writeShort(hLength);
-
-        ListIterator<PcepValueType> listIterator = llLinkAttributesSubTLVs.listIterator();
-
-        while (listIterator.hasNext()) {
-            PcepValueType tlv = listIterator.next();
-
-            if (null == tlv) {
-                log.debug("TLV is null from subTlv list");
-                continue;
-            }
-            tlv.write(c);
-
-            // need to take care of padding
-            int pad = tlv.getLength() % 4;
-
-            if (0 != pad) {
-                pad = 4 - pad;
-                for (int i = 0; i < pad; ++i) {
-                    c.writeByte((byte) 0);
-                }
-            }
-        }
-
-        hLength = (short) (c.writerIndex() - tlvStartIndex);
-        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
-
-        return c.writerIndex() - tlvStartIndex;
-    }
-
-    /**
-     * Reads channel buffer and returns object of TE Link Attributes TLV.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of TELinkAttributesTlv
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
-
-        // Node Descriptor Sub-TLVs (variable)
-        LinkedList<PcepValueType> llLinkAttributesSubTLVs = new LinkedList<PcepValueType>();
-
-        ChannelBuffer tempCb = c.readBytes(hLength);
-
-        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
-
-            PcepValueType tlv;
-            short hType = tempCb.readShort();
-            int iValue = 0;
-            short length = tempCb.readShort();
-            switch (hType) {
-
-            case IPv4TERouterIdOfLocalNodeTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new IPv4TERouterIdOfLocalNodeTlv(iValue);
-                break;
-            case IPv6TERouterIdofLocalNodeTlv.TYPE:
-                byte[] ipv6LValue = new byte[IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH];
-                tempCb.readBytes(ipv6LValue, 0, IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH);
-                tlv = new IPv6TERouterIdofLocalNodeTlv(ipv6LValue);
-                break;
-            case IPv4TERouterIdOfRemoteNodeTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new IPv4TERouterIdOfRemoteNodeTlv(iValue);
-                break;
-            case IPv6TERouterIdofRemoteNodeTlv.TYPE:
-                byte[] ipv6RValue = new byte[IPv6TERouterIdofRemoteNodeTlv.VALUE_LENGTH];
-                tempCb.readBytes(ipv6RValue, 0, IPv6TERouterIdofRemoteNodeTlv.VALUE_LENGTH);
-                tlv = new IPv6TERouterIdofRemoteNodeTlv(ipv6RValue);
-                break;
-            case LinkLocalRemoteIdentifiersTlv.TYPE:
-                tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
-                break;
-            case AdministrativeGroupTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new AdministrativeGroupTlv(iValue);
-                break;
-            case MaximumLinkBandwidthTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new MaximumLinkBandwidthTlv(iValue);
-                break;
-            case MaximumReservableLinkBandwidthTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new MaximumReservableLinkBandwidthTlv(iValue);
-                break;
-            case UnreservedBandwidthTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new UnreservedBandwidthTlv(iValue);
-                break;
-            case TEDefaultMetricTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new TEDefaultMetricTlv(iValue);
-                break;
-            case LinkProtectionTypeTlv.TYPE:
-                tlv = LinkProtectionTypeTlv.read(tempCb);
-                break;
-            case MPLSProtocolMaskTlv.TYPE:
-                byte cValue = tempCb.readByte();
-                tlv = new MPLSProtocolMaskTlv(cValue);
-                break;
-            case IGPMetricTlv.TYPE:
-                tlv = IGPMetricTlv.read(tempCb, length);
-                break;
-            case SharedRiskLinkGroupTlv.TYPE:
-                tlv = SharedRiskLinkGroupTlv.read(tempCb, length);
-                break;
-            case OpaqueLinkAttributeTlv.TYPE:
-                tlv = OpaqueLinkAttributeTlv.read(tempCb, length);
-                break;
-            case LinkNameTlv.TYPE:
-                tlv = LinkNameTlv.read(tempCb, length);
-                break;
-            default:
-                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
-            }
-
-            // Check for the padding
-            int pad = length % 4;
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= tempCb.readableBytes()) {
-                    tempCb.skipBytes(pad);
-                }
-            }
-            llLinkAttributesSubTLVs.add(tlv);
-        }
-
-        if (0 < tempCb.readableBytes()) {
-
-            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
-        }
-
-        return new TELinkAttributesTlv(llLinkAttributesSubTLVs);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
-                .add("LinkAttributesSubTLVs", llLinkAttributesSubTLVs).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.types;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides TELinkAttributesTlv.
+ */
+public class TELinkAttributesTlv implements PcepValueType {
+
+    /*
+     * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
+     *  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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD27]        |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                                                               |
+     //              Link Attributes Sub-TLVs (variable)            //
+     |                                                               |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(TELinkAttributesTlv.class);
+
+    public static final short TYPE = 1897; //TODD:change this TBD27
+    public short hLength;
+
+    public static final int TLV_HEADER_LENGTH = 4;
+
+    // LinkDescriptors Sub-TLVs (variable)
+    private LinkedList<PcepValueType> llLinkAttributesSubTLVs;
+
+    /**
+     * Constructor to initialize Link Attributes Sub TLVs.
+     *
+     * @param llLinkAttributesSubTLVs linked list of PcepValueType
+     */
+    public TELinkAttributesTlv(LinkedList<PcepValueType> llLinkAttributesSubTLVs) {
+        this.llLinkAttributesSubTLVs = llLinkAttributesSubTLVs;
+    }
+
+    /**
+     * Returns object of TE Link Attributes TLV.
+     *
+     * @param llLinkAttributesSubTLVs linked list of Link Attribute of Sub TLV
+     * @return object of TELinkAttributesTlv
+     */
+    public static TELinkAttributesTlv of(final LinkedList<PcepValueType> llLinkAttributesSubTLVs) {
+        return new TELinkAttributesTlv(llLinkAttributesSubTLVs);
+    }
+
+    /**
+     * Returns linked list of Link Attribute of Sub TLV.
+     *
+     * @return llLinkAttributesSubTLVs linked list of Link Attribute of Sub TLV
+     */
+    public LinkedList<PcepValueType> getllLinkAttributesSubTLVs() {
+        return llLinkAttributesSubTLVs;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(llLinkAttributesSubTLVs.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        /*
+         * Here we have a list of Tlv so to compare each sub tlv between the object
+         * we have to take a list iterator so one by one we can get each sub tlv object
+         * and can compare them.
+         * it may be possible that the size of 2 lists is not equal so we have to first check
+         * the size, if both are same then we should check for the subtlv objects otherwise
+         * we should return false.
+         */
+        if (obj instanceof TELinkAttributesTlv) {
+            int countObjSubTlv = 0;
+            int countOtherSubTlv = 0;
+            boolean isCommonSubTlv = true;
+            TELinkAttributesTlv other = (TELinkAttributesTlv) obj;
+            Iterator<PcepValueType> objListIterator = ((TELinkAttributesTlv) obj).llLinkAttributesSubTLVs.iterator();
+            countObjSubTlv = ((TELinkAttributesTlv) obj).llLinkAttributesSubTLVs.size();
+            countOtherSubTlv = other.llLinkAttributesSubTLVs.size();
+            if (countObjSubTlv != countOtherSubTlv) {
+                return false;
+            } else {
+                while (objListIterator.hasNext() && isCommonSubTlv) {
+                    PcepValueType subTlv = objListIterator.next();
+                    isCommonSubTlv = Objects.equals(llLinkAttributesSubTLVs.contains(subTlv),
+                            other.llLinkAttributesSubTLVs.contains(subTlv));
+                }
+                return isCommonSubTlv;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int tlvStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        int tlvLenIndex = c.writerIndex();
+        hLength = 0;
+        c.writeShort(hLength);
+
+        ListIterator<PcepValueType> listIterator = llLinkAttributesSubTLVs.listIterator();
+
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            if (null == tlv) {
+                log.debug("TLV is null from subTlv list");
+                continue;
+            }
+            tlv.write(c);
+
+            // need to take care of padding
+            int pad = tlv.getLength() % 4;
+
+            if (0 != pad) {
+                pad = 4 - pad;
+                for (int i = 0; i < pad; ++i) {
+                    c.writeByte((byte) 0);
+                }
+            }
+        }
+
+        hLength = (short) (c.writerIndex() - tlvStartIndex);
+        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
+
+        return c.writerIndex() - tlvStartIndex;
+    }
+
+    /**
+     * Reads channel buffer and returns object of TE Link Attributes TLV.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of TELinkAttributesTlv
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
+
+        // Node Descriptor Sub-TLVs (variable)
+        LinkedList<PcepValueType> llLinkAttributesSubTLVs = new LinkedList<PcepValueType>();
+
+        ChannelBuffer tempCb = c.readBytes(hLength);
+
+        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
+
+            PcepValueType tlv;
+            short hType = tempCb.readShort();
+            int iValue = 0;
+            short length = tempCb.readShort();
+            switch (hType) {
+
+            case IPv4TERouterIdOfLocalNodeTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new IPv4TERouterIdOfLocalNodeTlv(iValue);
+                break;
+            case IPv6TERouterIdofLocalNodeTlv.TYPE:
+                byte[] ipv6LValue = new byte[IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH];
+                tempCb.readBytes(ipv6LValue, 0, IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH);
+                tlv = new IPv6TERouterIdofLocalNodeTlv(ipv6LValue);
+                break;
+            case IPv4TERouterIdOfRemoteNodeTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new IPv4TERouterIdOfRemoteNodeTlv(iValue);
+                break;
+            case IPv6TERouterIdofRemoteNodeTlv.TYPE:
+                byte[] ipv6RValue = new byte[IPv6TERouterIdofRemoteNodeTlv.VALUE_LENGTH];
+                tempCb.readBytes(ipv6RValue, 0, IPv6TERouterIdofRemoteNodeTlv.VALUE_LENGTH);
+                tlv = new IPv6TERouterIdofRemoteNodeTlv(ipv6RValue);
+                break;
+            case LinkLocalRemoteIdentifiersTlv.TYPE:
+                tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
+                break;
+            case AdministrativeGroupTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new AdministrativeGroupTlv(iValue);
+                break;
+            case MaximumLinkBandwidthTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new MaximumLinkBandwidthTlv(iValue);
+                break;
+            case MaximumReservableLinkBandwidthTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new MaximumReservableLinkBandwidthTlv(iValue);
+                break;
+            case UnreservedBandwidthTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new UnreservedBandwidthTlv(iValue);
+                break;
+            case TEDefaultMetricTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new TEDefaultMetricTlv(iValue);
+                break;
+            case LinkProtectionTypeTlv.TYPE:
+                tlv = LinkProtectionTypeTlv.read(tempCb);
+                break;
+            case MPLSProtocolMaskTlv.TYPE:
+                byte cValue = tempCb.readByte();
+                tlv = new MPLSProtocolMaskTlv(cValue);
+                break;
+            case IGPMetricTlv.TYPE:
+                tlv = IGPMetricTlv.read(tempCb, length);
+                break;
+            case SharedRiskLinkGroupTlv.TYPE:
+                tlv = SharedRiskLinkGroupTlv.read(tempCb, length);
+                break;
+            case OpaqueLinkAttributeTlv.TYPE:
+                tlv = OpaqueLinkAttributeTlv.read(tempCb, length);
+                break;
+            case LinkNameTlv.TYPE:
+                tlv = LinkNameTlv.read(tempCb, length);
+                break;
+            default:
+                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
+            }
+
+            // Check for the padding
+            int pad = length % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= tempCb.readableBytes()) {
+                    tempCb.skipBytes(pad);
+                }
+            }
+            llLinkAttributesSubTLVs.add(tlv);
+        }
+
+        if (0 < tempCb.readableBytes()) {
+
+            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
+        }
+
+        return new TELinkAttributesTlv(llLinkAttributesSubTLVs);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
+                .add("LinkAttributesSubTLVs", llLinkAttributesSubTLVs).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkDescriptorsTLV.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkDescriptorsTLV.java
index b4e164c..44059e3 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkDescriptorsTLV.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TELinkDescriptorsTLV.java
@@ -1,248 +1,248 @@
-/*
- * 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.types;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides TE Link Descriptors TLV.
- */
-public class TELinkDescriptorsTLV implements PcepValueType {
-
-    /*
-     * Reference: PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
-     *   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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD14]        |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                                                               |
-     //              Link Descriptor Sub-TLVs (variable)            //
-     |                                                               |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(TELinkDescriptorsTLV.class);
-
-    public static final short TYPE = 1070; //TODD:change this TBD14
-    public short hLength;
-
-    public static final int TLV_HEADER_LENGTH = 4;
-
-    // LinkDescriptors Sub-TLVs (variable)
-    private LinkedList<PcepValueType> llLinkDescriptorsSubTLVs;
-
-    /**
-     * Constructor to initialize llLinkDescriptorsSubTLVs.
-     *
-     * @param llLinkDescriptorsSubTLVs of PcepValueType
-     */
-    public TELinkDescriptorsTLV(LinkedList<PcepValueType> llLinkDescriptorsSubTLVs) {
-        this.llLinkDescriptorsSubTLVs = llLinkDescriptorsSubTLVs;
-    }
-
-    /**
-     * Returns object of TELinkDescriptorsTLV.
-     *
-     * @param llLinkDescriptorsSubTLVs of PcepValueType
-     * @return object of TELinkDescriptorsTLV
-     */
-    public static TELinkDescriptorsTLV of(final LinkedList<PcepValueType> llLinkDescriptorsSubTLVs) {
-        return new TELinkDescriptorsTLV(llLinkDescriptorsSubTLVs);
-    }
-
-    /**
-     * Returns linked list of Link Attribute of Sub TLV.
-     *
-     * @return llLinkDescriptorsSubTLVs linked list of Link Attribute of Sub TLV
-     */
-    public LinkedList<PcepValueType> getllLinkDescriptorsSubTLVs() {
-        return llLinkDescriptorsSubTLVs;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(llLinkDescriptorsSubTLVs.hashCode());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        /*
-         * Here we have a list of Tlv so to compare each sub tlv between the object
-         * we have to take a list iterator so one by one we can get each sub tlv object
-         * and can compare them.
-         * it may be possible that the size of 2 lists is not equal so we have to first check
-         * the size, if both are same then we should check for the subtlv objects otherwise
-         * we should return false.
-         */
-        if (obj instanceof TELinkDescriptorsTLV) {
-            int countObjSubTlv = 0;
-            int countOtherSubTlv = 0;
-            boolean isCommonSubTlv = true;
-            TELinkDescriptorsTLV other = (TELinkDescriptorsTLV) obj;
-            Iterator<PcepValueType> objListIterator = ((TELinkDescriptorsTLV) obj).llLinkDescriptorsSubTLVs.iterator();
-            countObjSubTlv = ((TELinkDescriptorsTLV) obj).llLinkDescriptorsSubTLVs.size();
-            countOtherSubTlv = other.llLinkDescriptorsSubTLVs.size();
-            if (countObjSubTlv != countOtherSubTlv) {
-                return false;
-            } else {
-                while (objListIterator.hasNext() && isCommonSubTlv) {
-                    PcepValueType subTlv = objListIterator.next();
-                    isCommonSubTlv = Objects.equals(llLinkDescriptorsSubTLVs.contains(subTlv),
-                            other.llLinkDescriptorsSubTLVs.contains(subTlv));
-                }
-                return isCommonSubTlv;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int tlvStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        int tlvLenIndex = c.writerIndex();
-        hLength = 0;
-        c.writeShort(hLength);
-
-        ListIterator<PcepValueType> listIterator = llLinkDescriptorsSubTLVs.listIterator();
-
-        while (listIterator.hasNext()) {
-            PcepValueType tlv = listIterator.next();
-
-            tlv.write(c);
-
-            // need to take care of padding
-            int pad = tlv.getLength() % 4;
-
-            if (0 != pad) {
-                pad = 4 - pad;
-                for (int i = 0; i < pad; ++i) {
-                    c.writeByte((byte) 0);
-                }
-            }
-        }
-
-        hLength = (short) (c.writerIndex() - tlvStartIndex);
-        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
-
-        return c.writerIndex() - tlvStartIndex;
-    }
-
-    /**
-     * Reads channel buffer and returns object of TELinkDescriptorsTLV.
-     *
-     * @param c input channel buffer
-     * @param length length
-     * @return object of TELinkDescriptorsTLV
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public static PcepValueType read(ChannelBuffer c, short length) throws PcepParseException {
-
-        // Node Descriptor Sub-TLVs (variable)
-        LinkedList<PcepValueType> llLinkDescriptorsSubTLVs = new LinkedList<PcepValueType>();
-
-        ChannelBuffer tempCb = c.readBytes(length);
-
-        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
-
-            PcepValueType tlv;
-            short hType = tempCb.readShort();
-            int iValue = 0;
-            short hLength = tempCb.readShort();
-            log.debug("sub Tlv Length" + hLength);
-            switch (hType) {
-
-            case LinkLocalRemoteIdentifiersTlv.TYPE:
-                tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
-                break;
-            case IPv4InterfaceAddressTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new IPv4InterfaceAddressTlv(iValue);
-                break;
-            case IPv4NeighborAddressTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new IPv4NeighborAddressTlv(iValue);
-                break;
-            case IPv6InterfaceAddressTlv.TYPE:
-                byte[] ipv6Value = new byte[IPv6InterfaceAddressTlv.VALUE_LENGTH];
-                tempCb.readBytes(ipv6Value, 0, IPv6InterfaceAddressTlv.VALUE_LENGTH);
-                tlv = new IPv6InterfaceAddressTlv(ipv6Value);
-                break;
-            case IPv6NeighborAddressTlv.TYPE:
-                byte[] ipv6NeighborAdd = new byte[IPv6NeighborAddressTlv.VALUE_LENGTH];
-                tempCb.readBytes(ipv6NeighborAdd, 0, IPv6NeighborAddressTlv.VALUE_LENGTH);
-                tlv = new IPv6NeighborAddressTlv(ipv6NeighborAdd);
-                break;
-            default:
-                throw new PcepParseException("Unsupported Sub TLV type:" + hType);
-            }
-
-            // Check for the padding
-            int pad = hLength % 4;
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= tempCb.readableBytes()) {
-                    tempCb.skipBytes(pad);
-                }
-            }
-            llLinkDescriptorsSubTLVs.add(tlv);
-
-        }
-
-        if (0 < tempCb.readableBytes()) {
-
-            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
-        }
-        return new TELinkDescriptorsTLV(llLinkDescriptorsSubTLVs);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
-                .add("LinkDescriptorsSubTLVs", llLinkDescriptorsSubTLVs).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.types;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides TE Link Descriptors TLV.
+ */
+public class TELinkDescriptorsTLV implements PcepValueType {
+
+    /*
+     * Reference: PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
+     *   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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD14]        |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                                                               |
+     //              Link Descriptor Sub-TLVs (variable)            //
+     |                                                               |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(TELinkDescriptorsTLV.class);
+
+    public static final short TYPE = 1070; //TODD:change this TBD14
+    public short hLength;
+
+    public static final int TLV_HEADER_LENGTH = 4;
+
+    // LinkDescriptors Sub-TLVs (variable)
+    private LinkedList<PcepValueType> llLinkDescriptorsSubTLVs;
+
+    /**
+     * Constructor to initialize llLinkDescriptorsSubTLVs.
+     *
+     * @param llLinkDescriptorsSubTLVs of PcepValueType
+     */
+    public TELinkDescriptorsTLV(LinkedList<PcepValueType> llLinkDescriptorsSubTLVs) {
+        this.llLinkDescriptorsSubTLVs = llLinkDescriptorsSubTLVs;
+    }
+
+    /**
+     * Returns object of TELinkDescriptorsTLV.
+     *
+     * @param llLinkDescriptorsSubTLVs of PcepValueType
+     * @return object of TELinkDescriptorsTLV
+     */
+    public static TELinkDescriptorsTLV of(final LinkedList<PcepValueType> llLinkDescriptorsSubTLVs) {
+        return new TELinkDescriptorsTLV(llLinkDescriptorsSubTLVs);
+    }
+
+    /**
+     * Returns linked list of Link Attribute of Sub TLV.
+     *
+     * @return llLinkDescriptorsSubTLVs linked list of Link Attribute of Sub TLV
+     */
+    public LinkedList<PcepValueType> getllLinkDescriptorsSubTLVs() {
+        return llLinkDescriptorsSubTLVs;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(llLinkDescriptorsSubTLVs.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        /*
+         * Here we have a list of Tlv so to compare each sub tlv between the object
+         * we have to take a list iterator so one by one we can get each sub tlv object
+         * and can compare them.
+         * it may be possible that the size of 2 lists is not equal so we have to first check
+         * the size, if both are same then we should check for the subtlv objects otherwise
+         * we should return false.
+         */
+        if (obj instanceof TELinkDescriptorsTLV) {
+            int countObjSubTlv = 0;
+            int countOtherSubTlv = 0;
+            boolean isCommonSubTlv = true;
+            TELinkDescriptorsTLV other = (TELinkDescriptorsTLV) obj;
+            Iterator<PcepValueType> objListIterator = ((TELinkDescriptorsTLV) obj).llLinkDescriptorsSubTLVs.iterator();
+            countObjSubTlv = ((TELinkDescriptorsTLV) obj).llLinkDescriptorsSubTLVs.size();
+            countOtherSubTlv = other.llLinkDescriptorsSubTLVs.size();
+            if (countObjSubTlv != countOtherSubTlv) {
+                return false;
+            } else {
+                while (objListIterator.hasNext() && isCommonSubTlv) {
+                    PcepValueType subTlv = objListIterator.next();
+                    isCommonSubTlv = Objects.equals(llLinkDescriptorsSubTLVs.contains(subTlv),
+                            other.llLinkDescriptorsSubTLVs.contains(subTlv));
+                }
+                return isCommonSubTlv;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int tlvStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        int tlvLenIndex = c.writerIndex();
+        hLength = 0;
+        c.writeShort(hLength);
+
+        ListIterator<PcepValueType> listIterator = llLinkDescriptorsSubTLVs.listIterator();
+
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            tlv.write(c);
+
+            // need to take care of padding
+            int pad = tlv.getLength() % 4;
+
+            if (0 != pad) {
+                pad = 4 - pad;
+                for (int i = 0; i < pad; ++i) {
+                    c.writeByte((byte) 0);
+                }
+            }
+        }
+
+        hLength = (short) (c.writerIndex() - tlvStartIndex);
+        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
+
+        return c.writerIndex() - tlvStartIndex;
+    }
+
+    /**
+     * Reads channel buffer and returns object of TELinkDescriptorsTLV.
+     *
+     * @param c input channel buffer
+     * @param length length
+     * @return object of TELinkDescriptorsTLV
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepValueType read(ChannelBuffer c, short length) throws PcepParseException {
+
+        // Node Descriptor Sub-TLVs (variable)
+        LinkedList<PcepValueType> llLinkDescriptorsSubTLVs = new LinkedList<PcepValueType>();
+
+        ChannelBuffer tempCb = c.readBytes(length);
+
+        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
+
+            PcepValueType tlv;
+            short hType = tempCb.readShort();
+            int iValue = 0;
+            short hLength = tempCb.readShort();
+            log.debug("sub Tlv Length" + hLength);
+            switch (hType) {
+
+            case LinkLocalRemoteIdentifiersTlv.TYPE:
+                tlv = LinkLocalRemoteIdentifiersTlv.read(tempCb);
+                break;
+            case IPv4InterfaceAddressTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new IPv4InterfaceAddressTlv(iValue);
+                break;
+            case IPv4NeighborAddressTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new IPv4NeighborAddressTlv(iValue);
+                break;
+            case IPv6InterfaceAddressTlv.TYPE:
+                byte[] ipv6Value = new byte[IPv6InterfaceAddressTlv.VALUE_LENGTH];
+                tempCb.readBytes(ipv6Value, 0, IPv6InterfaceAddressTlv.VALUE_LENGTH);
+                tlv = new IPv6InterfaceAddressTlv(ipv6Value);
+                break;
+            case IPv6NeighborAddressTlv.TYPE:
+                byte[] ipv6NeighborAdd = new byte[IPv6NeighborAddressTlv.VALUE_LENGTH];
+                tempCb.readBytes(ipv6NeighborAdd, 0, IPv6NeighborAddressTlv.VALUE_LENGTH);
+                tlv = new IPv6NeighborAddressTlv(ipv6NeighborAdd);
+                break;
+            default:
+                throw new PcepParseException("Unsupported Sub TLV type:" + hType);
+            }
+
+            // Check for the padding
+            int pad = hLength % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= tempCb.readableBytes()) {
+                    tempCb.skipBytes(pad);
+                }
+            }
+            llLinkDescriptorsSubTLVs.add(tlv);
+
+        }
+
+        if (0 < tempCb.readableBytes()) {
+
+            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
+        }
+        return new TELinkDescriptorsTLV(llLinkDescriptorsSubTLVs);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
+                .add("LinkDescriptorsSubTLVs", llLinkDescriptorsSubTLVs).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TENodeAttributesTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TENodeAttributesTlv.java
index 0ca288c..31f5d4d 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TENodeAttributesTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TENodeAttributesTlv.java
@@ -1,247 +1,247 @@
-/*
- * 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.types;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.exceptions.PcepParseException;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides TE Node Attributes Tlv.
- */
-public class TENodeAttributesTlv implements PcepValueType {
-    /*
-     * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
-     *
-      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
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |           Type=[TBD20]        |             Length            |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     |                                                               |
-     //              Node Attributes Sub-TLVs (variable)            //
-     |                                                               |
-     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-
-
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(TENodeAttributesTlv.class);
-
-    public static final short TYPE = 1267; //TODD:change this TBD20
-    public short hLength;
-
-    public static final int TLV_HEADER_LENGTH = 4;
-    // LinkDescriptors Sub-TLVs (variable)
-    private LinkedList<PcepValueType> llNodeAttributesSubTLVs;
-
-    /**
-     * Constructor to initialize llNodeAttributesSubTLVs.
-     *
-     * @param llNodeAttributesSubTLVs linked list of Node Attributes Sub-TLVs
-     */
-    public TENodeAttributesTlv(LinkedList<PcepValueType> llNodeAttributesSubTLVs) {
-        this.llNodeAttributesSubTLVs = llNodeAttributesSubTLVs;
-    }
-
-    /**
-     * Returns object of TENodeAttributesTlv.
-     *
-     * @param llNodeAttributesSubTLVs LinkedList of PcepValueType
-     * @return object of TENodeAttributesTlv
-     */
-    public static TENodeAttributesTlv of(LinkedList<PcepValueType> llNodeAttributesSubTLVs) {
-        return new TENodeAttributesTlv(llNodeAttributesSubTLVs);
-    }
-
-    /**
-     * Returns Node Attributes Sub-TLVs.
-     *
-     * @return llNodeAttributesSubTLVs linked list of Node Attributes Sub-TLVs
-     */
-    public LinkedList<PcepValueType> getllNodeAttributesSubTLVs() {
-        return llNodeAttributesSubTLVs;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return hLength;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(llNodeAttributesSubTLVs.hashCode());
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        /*
-         * Here we have a list of Tlv so to compare each sub tlv between the object
-         * we have to take a list iterator so one by one we can get each sub tlv object
-         * and can compare them.
-         * it may be possible that the size of 2 lists is not equal so we have to first check
-         * the size, if both are same then we should check for the subtlv objects otherwise
-         * we should return false.
-         */
-        if (obj instanceof TENodeAttributesTlv) {
-            int countObjSubTlv = 0;
-            int countOtherSubTlv = 0;
-            boolean isCommonSubTlv = true;
-            TENodeAttributesTlv other = (TENodeAttributesTlv) obj;
-            Iterator<PcepValueType> objListIterator = ((TENodeAttributesTlv) obj).llNodeAttributesSubTLVs.iterator();
-            countObjSubTlv = ((TENodeAttributesTlv) obj).llNodeAttributesSubTLVs.size();
-            countOtherSubTlv = other.llNodeAttributesSubTLVs.size();
-            if (countObjSubTlv != countOtherSubTlv) {
-                return false;
-            } else {
-                while (objListIterator.hasNext() && isCommonSubTlv) {
-                    PcepValueType subTlv = objListIterator.next();
-                    isCommonSubTlv = Objects.equals(llNodeAttributesSubTLVs.contains(subTlv),
-                            other.llNodeAttributesSubTLVs.contains(subTlv));
-                }
-                return isCommonSubTlv;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int tlvStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        int tlvLenIndex = c.writerIndex();
-        hLength = 0;
-        c.writeShort(hLength);
-
-        ListIterator<PcepValueType> listIterator = llNodeAttributesSubTLVs.listIterator();
-
-        while (listIterator.hasNext()) {
-            PcepValueType tlv = listIterator.next();
-
-            tlv.write(c);
-
-            // need to take care of padding
-            int pad = tlv.getLength() % 4;
-
-            if (0 != pad) {
-                pad = 4 - pad;
-                for (int i = 0; i < pad; ++i) {
-                    c.writeByte((byte) 0);
-                }
-            }
-        }
-
-        hLength = (short) (c.writerIndex() - tlvStartIndex);
-        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
-
-        return c.writerIndex() - tlvStartIndex;
-    }
-
-    /**
-     * Reads the channel buffer and returns object of TENodeAttributesTlv.
-     *
-     * @param c input channel buffer
-     * @param hLength length
-     * @return object of TENodeAttributesTlv
-     * @throws PcepParseException if mandatory fields are missing
-     */
-    public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
-
-        // Node Descriptor Sub-TLVs (variable)
-        LinkedList<PcepValueType> llNodeAttributesSubTLVs = new LinkedList<PcepValueType>();
-
-        ChannelBuffer tempCb = c.readBytes(hLength);
-
-        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
-            PcepValueType tlv;
-            short hType = tempCb.readShort();
-            int iValue = 0;
-            short length = tempCb.readShort();
-            switch (hType) {
-
-            case NodeFlagBitsTlv.TYPE:
-                byte cValue = tempCb.readByte();
-                tlv = new NodeFlagBitsTlv(cValue);
-                break;
-            case OpaqueNodeAttributeTlv.TYPE:
-                tlv = OpaqueNodeAttributeTlv.read(tempCb, length);
-                break;
-            case NodeNameTlv.TYPE:
-                tlv = NodeNameTlv.read(tempCb, length);
-                break;
-            case ISISAreaIdentifierTlv.TYPE:
-                tlv = ISISAreaIdentifierTlv.read(tempCb, length);
-                break;
-            case IPv4TERouterIdOfLocalNodeTlv.TYPE:
-                iValue = tempCb.readInt();
-                tlv = new IPv4TERouterIdOfLocalNodeTlv(iValue);
-                break;
-            case IPv6TERouterIdofLocalNodeTlv.TYPE:
-                byte[] ipv6Value = new byte[IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH];
-                tempCb.readBytes(ipv6Value, 0, IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH);
-                tlv = new IPv6TERouterIdofLocalNodeTlv(ipv6Value);
-                break;
-            default:
-                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
-            }
-
-            // Check for the padding
-            int pad = length % 4;
-            if (0 < pad) {
-                pad = 4 - pad;
-                if (pad <= tempCb.readableBytes()) {
-                    tempCb.skipBytes(pad);
-                }
-            }
-
-            llNodeAttributesSubTLVs.add(tlv);
-        }
-
-        if (0 < tempCb.readableBytes()) {
-
-            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
-        }
-        return new TENodeAttributesTlv(llNodeAttributesSubTLVs);
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
-                .add("NodeAttributesSubTLVs", llNodeAttributesSubTLVs).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.types;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.exceptions.PcepParseException;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides TE Node Attributes Tlv.
+ */
+public class TENodeAttributesTlv implements PcepValueType {
+    /*
+     * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
+     *
+      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
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |           Type=[TBD20]        |             Length            |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     |                                                               |
+     //              Node Attributes Sub-TLVs (variable)            //
+     |                                                               |
+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(TENodeAttributesTlv.class);
+
+    public static final short TYPE = 1267; //TODD:change this TBD20
+    public short hLength;
+
+    public static final int TLV_HEADER_LENGTH = 4;
+    // LinkDescriptors Sub-TLVs (variable)
+    private LinkedList<PcepValueType> llNodeAttributesSubTLVs;
+
+    /**
+     * Constructor to initialize llNodeAttributesSubTLVs.
+     *
+     * @param llNodeAttributesSubTLVs linked list of Node Attributes Sub-TLVs
+     */
+    public TENodeAttributesTlv(LinkedList<PcepValueType> llNodeAttributesSubTLVs) {
+        this.llNodeAttributesSubTLVs = llNodeAttributesSubTLVs;
+    }
+
+    /**
+     * Returns object of TENodeAttributesTlv.
+     *
+     * @param llNodeAttributesSubTLVs LinkedList of PcepValueType
+     * @return object of TENodeAttributesTlv
+     */
+    public static TENodeAttributesTlv of(LinkedList<PcepValueType> llNodeAttributesSubTLVs) {
+        return new TENodeAttributesTlv(llNodeAttributesSubTLVs);
+    }
+
+    /**
+     * Returns Node Attributes Sub-TLVs.
+     *
+     * @return llNodeAttributesSubTLVs linked list of Node Attributes Sub-TLVs
+     */
+    public LinkedList<PcepValueType> getllNodeAttributesSubTLVs() {
+        return llNodeAttributesSubTLVs;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return hLength;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(llNodeAttributesSubTLVs.hashCode());
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        /*
+         * Here we have a list of Tlv so to compare each sub tlv between the object
+         * we have to take a list iterator so one by one we can get each sub tlv object
+         * and can compare them.
+         * it may be possible that the size of 2 lists is not equal so we have to first check
+         * the size, if both are same then we should check for the subtlv objects otherwise
+         * we should return false.
+         */
+        if (obj instanceof TENodeAttributesTlv) {
+            int countObjSubTlv = 0;
+            int countOtherSubTlv = 0;
+            boolean isCommonSubTlv = true;
+            TENodeAttributesTlv other = (TENodeAttributesTlv) obj;
+            Iterator<PcepValueType> objListIterator = ((TENodeAttributesTlv) obj).llNodeAttributesSubTLVs.iterator();
+            countObjSubTlv = ((TENodeAttributesTlv) obj).llNodeAttributesSubTLVs.size();
+            countOtherSubTlv = other.llNodeAttributesSubTLVs.size();
+            if (countObjSubTlv != countOtherSubTlv) {
+                return false;
+            } else {
+                while (objListIterator.hasNext() && isCommonSubTlv) {
+                    PcepValueType subTlv = objListIterator.next();
+                    isCommonSubTlv = Objects.equals(llNodeAttributesSubTLVs.contains(subTlv),
+                            other.llNodeAttributesSubTLVs.contains(subTlv));
+                }
+                return isCommonSubTlv;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int tlvStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        int tlvLenIndex = c.writerIndex();
+        hLength = 0;
+        c.writeShort(hLength);
+
+        ListIterator<PcepValueType> listIterator = llNodeAttributesSubTLVs.listIterator();
+
+        while (listIterator.hasNext()) {
+            PcepValueType tlv = listIterator.next();
+
+            tlv.write(c);
+
+            // need to take care of padding
+            int pad = tlv.getLength() % 4;
+
+            if (0 != pad) {
+                pad = 4 - pad;
+                for (int i = 0; i < pad; ++i) {
+                    c.writeByte((byte) 0);
+                }
+            }
+        }
+
+        hLength = (short) (c.writerIndex() - tlvStartIndex);
+        c.setShort(tlvLenIndex, (hLength - TLV_HEADER_LENGTH));
+
+        return c.writerIndex() - tlvStartIndex;
+    }
+
+    /**
+     * Reads the channel buffer and returns object of TENodeAttributesTlv.
+     *
+     * @param c input channel buffer
+     * @param hLength length
+     * @return object of TENodeAttributesTlv
+     * @throws PcepParseException if mandatory fields are missing
+     */
+    public static PcepValueType read(ChannelBuffer c, short hLength) throws PcepParseException {
+
+        // Node Descriptor Sub-TLVs (variable)
+        LinkedList<PcepValueType> llNodeAttributesSubTLVs = new LinkedList<PcepValueType>();
+
+        ChannelBuffer tempCb = c.readBytes(hLength);
+
+        while (TLV_HEADER_LENGTH <= tempCb.readableBytes()) {
+            PcepValueType tlv;
+            short hType = tempCb.readShort();
+            int iValue = 0;
+            short length = tempCb.readShort();
+            switch (hType) {
+
+            case NodeFlagBitsTlv.TYPE:
+                byte cValue = tempCb.readByte();
+                tlv = new NodeFlagBitsTlv(cValue);
+                break;
+            case OpaqueNodeAttributeTlv.TYPE:
+                tlv = OpaqueNodeAttributeTlv.read(tempCb, length);
+                break;
+            case NodeNameTlv.TYPE:
+                tlv = NodeNameTlv.read(tempCb, length);
+                break;
+            case ISISAreaIdentifierTlv.TYPE:
+                tlv = ISISAreaIdentifierTlv.read(tempCb, length);
+                break;
+            case IPv4TERouterIdOfLocalNodeTlv.TYPE:
+                iValue = tempCb.readInt();
+                tlv = new IPv4TERouterIdOfLocalNodeTlv(iValue);
+                break;
+            case IPv6TERouterIdofLocalNodeTlv.TYPE:
+                byte[] ipv6Value = new byte[IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH];
+                tempCb.readBytes(ipv6Value, 0, IPv6TERouterIdofLocalNodeTlv.VALUE_LENGTH);
+                tlv = new IPv6TERouterIdofLocalNodeTlv(ipv6Value);
+                break;
+            default:
+                throw new PcepParseException("Unsupported Sub TLV type :" + hType);
+            }
+
+            // Check for the padding
+            int pad = length % 4;
+            if (0 < pad) {
+                pad = 4 - pad;
+                if (pad <= tempCb.readableBytes()) {
+                    tempCb.skipBytes(pad);
+                }
+            }
+
+            llNodeAttributesSubTLVs.add(tlv);
+        }
+
+        if (0 < tempCb.readableBytes()) {
+
+            throw new PcepParseException("Sub Tlv parsing error. Extra bytes received.");
+        }
+        return new TENodeAttributesTlv(llNodeAttributesSubTLVs);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", hLength)
+                .add("NodeAttributesSubTLVs", llNodeAttributesSubTLVs).toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TedCapabilityTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TedCapabilityTlv.java
index fa477cf..a1fc92b 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TedCapabilityTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/TedCapabilityTlv.java
@@ -1,178 +1,178 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides TED Capability Tlv.
- */
-public class TedCapabilityTlv implements PcepValueType {
-
-    /*
-     * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
-     *  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
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |               Type=[TBD5]     |            Length=4           |
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-       |                             Flags                           |R|
-       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(TedCapabilityTlv.class);
-
-    public static final short TYPE = 132; //TODO: need to change this TBD5
-    public static final short LENGTH = 4;
-    public static final int SET = 1;
-    public static final byte RFLAG_CHECK = 0x01;
-
-    private final boolean bRFlag;
-    private final int rawValue;
-    private final boolean isRawValueSet;
-
-    /**
-     * Constructor to initialize raw Value.
-     *
-     * @param rawValue Flags
-     */
-    public TedCapabilityTlv(final int rawValue) {
-        this.rawValue = rawValue;
-        this.isRawValueSet = true;
-        int temp = rawValue;
-        temp = temp & RFLAG_CHECK;
-        if (temp == SET) {
-            this.bRFlag = true;
-        } else {
-            this.bRFlag = false;
-        }
-
-    }
-
-    /**
-     * Constructor to initialize bRFlag.
-     *
-     * @param bRFlag R-flag
-     */
-    public TedCapabilityTlv(boolean bRFlag) {
-        this.bRFlag = bRFlag;
-        this.rawValue = 0;
-        this.isRawValueSet = false;
-    }
-
-    /**
-     * Returns R-flag.
-     *
-     * @return bRFlag
-     */
-    public boolean getbRFlag() {
-        return bRFlag;
-    }
-
-    /**
-     * Returns an object of TedCapabilityTlv.
-     *
-     * @param raw value Flags
-     * @return object of TedCapabilityTlv
-     */
-    public static TedCapabilityTlv of(final int raw) {
-        return new TedCapabilityTlv(raw);
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        if (isRawValueSet) {
-            return Objects.hash(rawValue);
-        } else {
-            return Objects.hash(bRFlag);
-        }
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof TedCapabilityTlv) {
-            TedCapabilityTlv other = (TedCapabilityTlv) obj;
-            if (isRawValueSet) {
-                return Objects.equals(this.rawValue, other.rawValue);
-            } else {
-                return Objects.equals(this.bRFlag, other.bRFlag);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iStartIndex = c.writerIndex();
-        int temp = 0;
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        if (isRawValueSet) {
-            c.writeInt(rawValue);
-        } else {
-            if (bRFlag) {
-                temp = temp | RFLAG_CHECK;
-            }
-            c.writeInt(temp);
-        }
-        return c.writerIndex() - iStartIndex;
-    }
-
-    /**
-     * Reads channel buffer and returns object of TedCapabilityTlv.
-     *
-     * @param c input channel buffer
-     * @return object of TedCapabilityTlv
-     */
-    public static TedCapabilityTlv read(ChannelBuffer c) {
-        return TedCapabilityTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides TED Capability Tlv.
+ */
+public class TedCapabilityTlv implements PcepValueType {
+
+    /*
+     * Reference :PCEP Extension for Transporting TE Data draft-dhodylee-pce-pcep-te-data-extn-02
+     *  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
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |               Type=[TBD5]     |            Length=4           |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                             Flags                           |R|
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(TedCapabilityTlv.class);
+
+    public static final short TYPE = 132; //TODO: need to change this TBD5
+    public static final short LENGTH = 4;
+    public static final int SET = 1;
+    public static final byte RFLAG_CHECK = 0x01;
+
+    private final boolean bRFlag;
+    private final int rawValue;
+    private final boolean isRawValueSet;
+
+    /**
+     * Constructor to initialize raw Value.
+     *
+     * @param rawValue Flags
+     */
+    public TedCapabilityTlv(final int rawValue) {
+        this.rawValue = rawValue;
+        this.isRawValueSet = true;
+        int temp = rawValue;
+        temp = temp & RFLAG_CHECK;
+        if (temp == SET) {
+            this.bRFlag = true;
+        } else {
+            this.bRFlag = false;
+        }
+
+    }
+
+    /**
+     * Constructor to initialize bRFlag.
+     *
+     * @param bRFlag R-flag
+     */
+    public TedCapabilityTlv(boolean bRFlag) {
+        this.bRFlag = bRFlag;
+        this.rawValue = 0;
+        this.isRawValueSet = false;
+    }
+
+    /**
+     * Returns R-flag.
+     *
+     * @return bRFlag
+     */
+    public boolean getbRFlag() {
+        return bRFlag;
+    }
+
+    /**
+     * Returns an object of TedCapabilityTlv.
+     *
+     * @param raw value Flags
+     * @return object of TedCapabilityTlv
+     */
+    public static TedCapabilityTlv of(final int raw) {
+        return new TedCapabilityTlv(raw);
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        if (isRawValueSet) {
+            return Objects.hash(rawValue);
+        } else {
+            return Objects.hash(bRFlag);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TedCapabilityTlv) {
+            TedCapabilityTlv other = (TedCapabilityTlv) obj;
+            if (isRawValueSet) {
+                return Objects.equals(this.rawValue, other.rawValue);
+            } else {
+                return Objects.equals(this.bRFlag, other.bRFlag);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iStartIndex = c.writerIndex();
+        int temp = 0;
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        if (isRawValueSet) {
+            c.writeInt(rawValue);
+        } else {
+            if (bRFlag) {
+                temp = temp | RFLAG_CHECK;
+            }
+            c.writeInt(temp);
+        }
+        return c.writerIndex() - iStartIndex;
+    }
+
+    /**
+     * Reads channel buffer and returns object of TedCapabilityTlv.
+     *
+     * @param c input channel buffer
+     * @return object of TedCapabilityTlv
+     */
+    public static TedCapabilityTlv read(ChannelBuffer c) {
+        return TedCapabilityTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/UnreservedBandwidthTlv.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/UnreservedBandwidthTlv.java
index 71006f9..44a3e44 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/UnreservedBandwidthTlv.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/types/UnreservedBandwidthTlv.java
@@ -1,133 +1,133 @@
-/*
- * 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.types;
-
-import java.util.Objects;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.onosproject.pcepio.protocol.PcepVersion;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.MoreObjects;
-
-/**
- * Provides Unreserved Bandwidth Tlv.
- */
-public class UnreservedBandwidthTlv implements PcepValueType {
-
-    /* Reference :[RFC5305]/3.6
-     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
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |           Type=[TDB36]        |             Length=4          |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-    |                 Unreserved Bandwidth                          |
-    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-     */
-
-    protected static final Logger log = LoggerFactory.getLogger(UnreservedBandwidthTlv.class);
-
-    public static final short TYPE = 11; //TDB36
-    public static final short LENGTH = 4;
-
-    private final int rawValue;
-
-    /**
-     * Constructor to initialize rawValue.
-     *
-     * @param rawValue Unreserved Bandwidth
-     */
-    public UnreservedBandwidthTlv(int rawValue) {
-        this.rawValue = rawValue;
-    }
-
-    /**
-     * Returns newly created UnreservedBandwidthTlv object.
-     *
-     * @param raw as Unreserved Bandwidth
-     * @return object of UnreservedBandwidthTlv
-     */
-    public static UnreservedBandwidthTlv of(final int raw) {
-        return new UnreservedBandwidthTlv(raw);
-    }
-
-    /**
-     * Returns Unreserved Bandwidth.
-     *
-     * @return rawValue Unreserved Bandwidth
-     */
-    public int getInt() {
-        return rawValue;
-    }
-
-    @Override
-    public PcepVersion getVersion() {
-        return PcepVersion.PCEP_1;
-    }
-
-    @Override
-    public short getType() {
-        return TYPE;
-    }
-
-    @Override
-    public short getLength() {
-        return LENGTH;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(rawValue);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof UnreservedBandwidthTlv) {
-            UnreservedBandwidthTlv other = (UnreservedBandwidthTlv) obj;
-            return Objects.equals(this.rawValue, other.rawValue);
-        }
-        return false;
-    }
-
-    @Override
-    public int write(ChannelBuffer c) {
-        int iLenStartIndex = c.writerIndex();
-        c.writeShort(TYPE);
-        c.writeShort(LENGTH);
-        c.writeInt(rawValue);
-        return c.writerIndex() - iLenStartIndex;
-    }
-
-    /**
-     * Reads byte stream from channel buffer and returns object of UnreservedBandwidthTlv.
-     *
-     * @param c input channel buffer
-     * @return object of UnreservedBandwidthTlv
-     */
-    public static UnreservedBandwidthTlv read(ChannelBuffer c) {
-        return UnreservedBandwidthTlv.of(c.readInt());
-    }
-
-    @Override
-    public String toString() {
-        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
-                .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.types;
+
+import java.util.Objects;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.onosproject.pcepio.protocol.PcepVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.MoreObjects;
+
+/**
+ * Provides Unreserved Bandwidth Tlv.
+ */
+public class UnreservedBandwidthTlv implements PcepValueType {
+
+    /* Reference :[RFC5305]/3.6
+     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
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |           Type=[TDB36]        |             Length=4          |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    |                 Unreserved Bandwidth                          |
+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     */
+
+    protected static final Logger log = LoggerFactory.getLogger(UnreservedBandwidthTlv.class);
+
+    public static final short TYPE = 11; //TDB36
+    public static final short LENGTH = 4;
+
+    private final int rawValue;
+
+    /**
+     * Constructor to initialize rawValue.
+     *
+     * @param rawValue Unreserved Bandwidth
+     */
+    public UnreservedBandwidthTlv(int rawValue) {
+        this.rawValue = rawValue;
+    }
+
+    /**
+     * Returns newly created UnreservedBandwidthTlv object.
+     *
+     * @param raw as Unreserved Bandwidth
+     * @return object of UnreservedBandwidthTlv
+     */
+    public static UnreservedBandwidthTlv of(final int raw) {
+        return new UnreservedBandwidthTlv(raw);
+    }
+
+    /**
+     * Returns Unreserved Bandwidth.
+     *
+     * @return rawValue Unreserved Bandwidth
+     */
+    public int getInt() {
+        return rawValue;
+    }
+
+    @Override
+    public PcepVersion getVersion() {
+        return PcepVersion.PCEP_1;
+    }
+
+    @Override
+    public short getType() {
+        return TYPE;
+    }
+
+    @Override
+    public short getLength() {
+        return LENGTH;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(rawValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof UnreservedBandwidthTlv) {
+            UnreservedBandwidthTlv other = (UnreservedBandwidthTlv) obj;
+            return Objects.equals(this.rawValue, other.rawValue);
+        }
+        return false;
+    }
+
+    @Override
+    public int write(ChannelBuffer c) {
+        int iLenStartIndex = c.writerIndex();
+        c.writeShort(TYPE);
+        c.writeShort(LENGTH);
+        c.writeInt(rawValue);
+        return c.writerIndex() - iLenStartIndex;
+    }
+
+    /**
+     * Reads byte stream from channel buffer and returns object of UnreservedBandwidthTlv.
+     *
+     * @param c input channel buffer
+     * @return object of UnreservedBandwidthTlv
+     */
+    public static UnreservedBandwidthTlv read(ChannelBuffer c) {
+        return UnreservedBandwidthTlv.of(c.readInt());
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(getClass()).add("Type", TYPE).add("Length", LENGTH).add("Value", rawValue)
+                .toString();
+    }
+}
diff --git a/pcep/pcepio/src/main/java/org/onosproject/pcepio/util/HexDump.java b/pcep/pcepio/src/main/java/org/onosproject/pcepio/util/HexDump.java
index 0e0c3cb..60ff884 100644
--- a/pcep/pcepio/src/main/java/org/onosproject/pcepio/util/HexDump.java
+++ b/pcep/pcepio/src/main/java/org/onosproject/pcepio/util/HexDump.java
@@ -1,41 +1,41 @@
-package org.onosproject.pcepio.util;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Provides Hex Dump for debugging.
- */
-public final class HexDump {
-    protected static final Logger log = LoggerFactory.getLogger(HexDump.class);
-
-    private HexDump() {
-    }
-
-    public static void pcepHexDump(ChannelBuffer buff) {
-
-        log.debug("==================== HEX DUMP ======================");
-        try {
-            byte[] yTemp;
-            yTemp = buff.array();
-
-            int iStartIndex = buff.readerIndex();
-            int iEndIndex = buff.writerIndex();
-            do {
-                StringBuilder sb = new StringBuilder();
-                for (int k = 0; (k < 16) && (iStartIndex < iEndIndex); ++k) {
-                    if (0 == k % 4) {
-                        sb.append(String.format(" ")); //blank after 4 bytes
-                    }
-                    sb.append(String.format("%02X ", yTemp[iStartIndex++]));
-                }
-                log.debug(sb.toString());
-            } while (iStartIndex < iEndIndex);
-        } catch (Exception e) {
-            log.error("[HexDump] Invalid buffer: " + e.toString());
-        }
-
-        log.debug("===================================================");
-    }
-}
+package org.onosproject.pcepio.util;
+
+import org.jboss.netty.buffer.ChannelBuffer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides Hex Dump for debugging.
+ */
+public final class HexDump {
+    protected static final Logger log = LoggerFactory.getLogger(HexDump.class);
+
+    private HexDump() {
+    }
+
+    public static void pcepHexDump(ChannelBuffer buff) {
+
+        log.debug("==================== HEX DUMP ======================");
+        try {
+            byte[] yTemp;
+            yTemp = buff.array();
+
+            int iStartIndex = buff.readerIndex();
+            int iEndIndex = buff.writerIndex();
+            do {
+                StringBuilder sb = new StringBuilder();
+                for (int k = 0; (k < 16) && (iStartIndex < iEndIndex); ++k) {
+                    if (0 == k % 4) {
+                        sb.append(String.format(" ")); //blank after 4 bytes
+                    }
+                    sb.append(String.format("%02X ", yTemp[iStartIndex++]));
+                }
+                log.debug(sb.toString());
+            } while (iStartIndex < iEndIndex);
+        } catch (Exception e) {
+            log.error("[HexDump] Invalid buffer: " + e.toString());
+        }
+
+        log.debug("===================================================");
+    }
+}
