diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java
index 8436fde..924b73a 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/JsonRpcReaderUtil.java
@@ -1,165 +1,165 @@
-/*
- * 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.ovsdb.rfc.utils;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.buffer.ByteBufInputStream;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Stack;
-
-import org.onosproject.ovsdb.rfc.error.UnsupportedException;
-import org.onosproject.ovsdb.rfc.jsonrpc.JsonReadContext;
-
-import com.fasterxml.jackson.core.JsonEncoding;
-import com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.io.IOContext;
-import com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper;
-import com.fasterxml.jackson.core.util.BufferRecycler;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.MappingJsonFactory;
-
-/**
- * Decoder utility class.
- */
-public final class JsonRpcReaderUtil {
-
-    /**
-     * Constructs a JsonRpcReaderUtil object. Utility classes should not have a
-     * public or default constructor, otherwise IDE will compile unsuccessfully.
-     * This class should not be instantiated.
-     */
-    private JsonRpcReaderUtil() {
-    }
-
-    /**
-     * Decode the bytes to Json object.
-     * @param in input of bytes
-     * @param out ouput of Json object list
-     * @param jrContext context for the last decoding process
-     * @throws IOException IOException
-     * @throws JsonParseException JsonParseException
-     */
-    public static void readToJsonNode(ByteBuf in, List<Object> out, JsonReadContext jrContext)
-            throws JsonParseException, IOException {
-        int lastReadBytes = jrContext.getLastReadBytes();
-        if (lastReadBytes == 0) {
-            if (in.readableBytes() < 4) {
-                return;
-            }
-            checkEncoding(in);
-        }
-
-        int i = lastReadBytes + in.readerIndex();
-        Stack<Byte> bufStack = jrContext.getBufStack();
-        for (; i < in.writerIndex(); i++) {
-            byte b = in.getByte(i);
-            switch (b) {
-            case '{':
-                if (!isDoubleQuote(bufStack)) {
-                    bufStack.push(b);
-                    jrContext.setStartMatch(true);
-                }
-                break;
-            case '}':
-                if (!isDoubleQuote(bufStack)) {
-                    bufStack.pop();
-                }
-                break;
-            case '"':
-                if (in.getByte(i - 1) != '\\') {
-                    if (!bufStack.isEmpty() && bufStack.peek() != '"') {
-                        bufStack.push(b);
-                    } else {
-                        bufStack.pop();
-                    }
-                }
-                break;
-            default:
-                break;
-            }
-
-            if (jrContext.isStartMatch() && bufStack.isEmpty()) {
-                ByteBuf buf = in.readSlice(i - in.readerIndex() + 1);
-                JsonParser jf = new MappingJsonFactory().createParser(new ByteBufInputStream(buf));
-                JsonNode jsonNode = jf.readValueAsTree();
-                out.add(jsonNode);
-                lastReadBytes = 0;
-                jrContext.setLastReadBytes(lastReadBytes);
-                break;
-            }
-        }
-
-        if (i >= in.writerIndex()) {
-            lastReadBytes = in.readableBytes();
-            jrContext.setLastReadBytes(lastReadBytes);
-        }
-    }
-
-    /**
-     * Filter the invalid characters before decoding.
-     * @param in input of bytes
-     * @param lastReadBytes the bytes for last decoding incomplete record
-     */
-    private static void fliterCharaters(ByteBuf in) {
-        while (in.isReadable()) {
-            int ch = in.getByte(in.readerIndex());
-            if ((ch != ' ') && (ch != '\n') && (ch != '\t') && (ch != '\r')) {
-                break;
-            } else {
-                in.readByte();
-            }
-        }
-    }
-
-    /**
-     * Check whether the peek of the stack element is double quote.
-     * @param jrContext context for the last decoding process
-     * @return boolean
-     */
-    private static boolean isDoubleQuote(Stack<Byte> bufStack) {
-        if (!bufStack.isEmpty() && bufStack.peek() == '"') {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Check whether the encoding is valid.
-     * @param in input of bytes
-     * @throws IOException this is an IO exception
-     * @throws UnsupportedException this is an unsupported exception
-     */
-    private static void checkEncoding(ByteBuf in) throws IOException {
-        int inputStart = 0;
-        int inputLength = 4;
-        fliterCharaters(in);
-        byte[] buff = new byte[4];
-        in.getBytes(in.readerIndex(), buff);
-        ByteSourceJsonBootstrapper strapper = new ByteSourceJsonBootstrapper(new IOContext(new BufferRecycler(),
-                                                                                           null,
-                                                                                           false),
-                                                                             buff, inputStart,
-                                                                             inputLength);
-        JsonEncoding jsonEncoding = strapper.detectEncoding();
-        if (!JsonEncoding.UTF8.equals(jsonEncoding)) {
-            throw new UnsupportedException("Only UTF-8 encoding is supported.");
-        }
-    }
-
-}
+/*
+ * 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.ovsdb.rfc.utils;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufInputStream;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Stack;
+
+import org.onosproject.ovsdb.rfc.error.UnsupportedException;
+import org.onosproject.ovsdb.rfc.jsonrpc.JsonReadContext;
+
+import com.fasterxml.jackson.core.JsonEncoding;
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.io.IOContext;
+import com.fasterxml.jackson.core.json.ByteSourceJsonBootstrapper;
+import com.fasterxml.jackson.core.util.BufferRecycler;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.MappingJsonFactory;
+
+/**
+ * Decoder utility class.
+ */
+public final class JsonRpcReaderUtil {
+
+    /**
+     * Constructs a JsonRpcReaderUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully.
+     * This class should not be instantiated.
+     */
+    private JsonRpcReaderUtil() {
+    }
+
+    /**
+     * Decode the bytes to Json object.
+     * @param in input of bytes
+     * @param out ouput of Json object list
+     * @param jrContext context for the last decoding process
+     * @throws IOException IOException
+     * @throws JsonParseException JsonParseException
+     */
+    public static void readToJsonNode(ByteBuf in, List<Object> out, JsonReadContext jrContext)
+            throws JsonParseException, IOException {
+        int lastReadBytes = jrContext.getLastReadBytes();
+        if (lastReadBytes == 0) {
+            if (in.readableBytes() < 4) {
+                return;
+            }
+            checkEncoding(in);
+        }
+
+        int i = lastReadBytes + in.readerIndex();
+        Stack<Byte> bufStack = jrContext.getBufStack();
+        for (; i < in.writerIndex(); i++) {
+            byte b = in.getByte(i);
+            switch (b) {
+            case '{':
+                if (!isDoubleQuote(bufStack)) {
+                    bufStack.push(b);
+                    jrContext.setStartMatch(true);
+                }
+                break;
+            case '}':
+                if (!isDoubleQuote(bufStack)) {
+                    bufStack.pop();
+                }
+                break;
+            case '"':
+                if (in.getByte(i - 1) != '\\') {
+                    if (!bufStack.isEmpty() && bufStack.peek() != '"') {
+                        bufStack.push(b);
+                    } else {
+                        bufStack.pop();
+                    }
+                }
+                break;
+            default:
+                break;
+            }
+
+            if (jrContext.isStartMatch() && bufStack.isEmpty()) {
+                ByteBuf buf = in.readSlice(i - in.readerIndex() + 1);
+                JsonParser jf = new MappingJsonFactory().createParser(new ByteBufInputStream(buf));
+                JsonNode jsonNode = jf.readValueAsTree();
+                out.add(jsonNode);
+                lastReadBytes = 0;
+                jrContext.setLastReadBytes(lastReadBytes);
+                break;
+            }
+        }
+
+        if (i >= in.writerIndex()) {
+            lastReadBytes = in.readableBytes();
+            jrContext.setLastReadBytes(lastReadBytes);
+        }
+    }
+
+    /**
+     * Filter the invalid characters before decoding.
+     * @param in input of bytes
+     * @param lastReadBytes the bytes for last decoding incomplete record
+     */
+    private static void fliterCharaters(ByteBuf in) {
+        while (in.isReadable()) {
+            int ch = in.getByte(in.readerIndex());
+            if ((ch != ' ') && (ch != '\n') && (ch != '\t') && (ch != '\r')) {
+                break;
+            } else {
+                in.readByte();
+            }
+        }
+    }
+
+    /**
+     * Check whether the peek of the stack element is double quote.
+     * @param jrContext context for the last decoding process
+     * @return boolean
+     */
+    private static boolean isDoubleQuote(Stack<Byte> bufStack) {
+        if (!bufStack.isEmpty() && bufStack.peek() == '"') {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Check whether the encoding is valid.
+     * @param in input of bytes
+     * @throws IOException this is an IO exception
+     * @throws UnsupportedException this is an unsupported exception
+     */
+    private static void checkEncoding(ByteBuf in) throws IOException {
+        int inputStart = 0;
+        int inputLength = 4;
+        fliterCharaters(in);
+        byte[] buff = new byte[4];
+        in.getBytes(in.readerIndex(), buff);
+        ByteSourceJsonBootstrapper strapper = new ByteSourceJsonBootstrapper(new IOContext(new BufferRecycler(),
+                                                                                           null,
+                                                                                           false),
+                                                                             buff, inputStart,
+                                                                             inputLength);
+        JsonEncoding jsonEncoding = strapper.detectEncoding();
+        if (!JsonEncoding.UTF8.equals(jsonEncoding)) {
+            throw new UnsupportedException("Only UTF-8 encoding is supported.");
+        }
+    }
+
+}
