diff --git a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
index 7559715..a271f93 100644
--- a/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
+++ b/ovsdb/api/src/main/java/org/onosproject/ovsdb/controller/driver/DefaultOvsdbClient.java
@@ -1,1128 +1,1128 @@
-/*
- * 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.controller.driver;
-
-import io.netty.channel.Channel;
-
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ExecutionException;
-
-import org.onlab.packet.IpAddress;
-import org.onosproject.ovsdb.controller.OvsdbBridge;
-import org.onosproject.ovsdb.controller.OvsdbBridgeName;
-import org.onosproject.ovsdb.controller.OvsdbClientService;
-import org.onosproject.ovsdb.controller.OvsdbConstant;
-import org.onosproject.ovsdb.controller.OvsdbDatapathId;
-import org.onosproject.ovsdb.controller.OvsdbNodeId;
-import org.onosproject.ovsdb.controller.OvsdbPort;
-import org.onosproject.ovsdb.controller.OvsdbPortName;
-import org.onosproject.ovsdb.controller.OvsdbPortNumber;
-import org.onosproject.ovsdb.controller.OvsdbRowStore;
-import org.onosproject.ovsdb.controller.OvsdbStore;
-import org.onosproject.ovsdb.controller.OvsdbTableStore;
-import org.onosproject.ovsdb.controller.OvsdbTunnel;
-import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
-import org.onosproject.ovsdb.rfc.message.OperationResult;
-import org.onosproject.ovsdb.rfc.message.TableUpdates;
-import org.onosproject.ovsdb.rfc.notation.Condition;
-import org.onosproject.ovsdb.rfc.notation.Mutation;
-import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
-import org.onosproject.ovsdb.rfc.notation.Row;
-import org.onosproject.ovsdb.rfc.notation.UUID;
-import org.onosproject.ovsdb.rfc.operations.Delete;
-import org.onosproject.ovsdb.rfc.operations.Insert;
-import org.onosproject.ovsdb.rfc.operations.Mutate;
-import org.onosproject.ovsdb.rfc.operations.Operation;
-import org.onosproject.ovsdb.rfc.operations.Update;
-import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
-import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-import org.onosproject.ovsdb.rfc.table.Bridge;
-import org.onosproject.ovsdb.rfc.table.Controller;
-import org.onosproject.ovsdb.rfc.table.Interface;
-import org.onosproject.ovsdb.rfc.table.OvsdbTable;
-import org.onosproject.ovsdb.rfc.table.Port;
-import org.onosproject.ovsdb.rfc.table.TableGenerator;
-import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
-import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
-import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
-import org.onosproject.ovsdb.rfc.utils.MutationUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.base.Function;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-import com.google.common.util.concurrent.SettableFuture;
-
-/**
- * An representation of an ovsdb client.
- */
-public class DefaultOvsdbClient
-        implements OvsdbProviderService, OvsdbClientService {
-
-    private final Logger log = LoggerFactory
-            .getLogger(DefaultOvsdbClient.class);
-
-    private Channel channel;
-
-    private OvsdbAgent agent;
-    private boolean connected;
-    private OvsdbNodeId nodeId;
-    private Callback monitorCallBack;
-
-    private OvsdbStore ovsdbStore = new OvsdbStore();
-
-    private final Map<String, String> requestMethod = Maps.newHashMap();
-    private final Map<String, SettableFuture<? extends Object>> requestResult = Maps
-            .newHashMap();
-
-    private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
-    private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
-
-    /**
-     * Creates an OvsdbClient.
-     *
-     * @param nodeId ovsdb node id
-     */
-    public DefaultOvsdbClient(OvsdbNodeId nodeId) {
-        this.nodeId = nodeId;
-    }
-
-    @Override
-    public OvsdbNodeId nodeId() {
-        return nodeId;
-    }
-
-    @Override
-    public void setAgent(OvsdbAgent agent) {
-        if (this.agent == null) {
-            this.agent = agent;
-        }
-    }
-
-    @Override
-    public void setChannel(Channel channel) {
-        this.channel = channel;
-    }
-
-    @Override
-    public void setConnection(boolean connected) {
-        this.connected = connected;
-    }
-
-    @Override
-    public boolean isConnected() {
-        return this.connected;
-    }
-
-    @Override
-    public void nodeAdded() {
-        this.agent.addConnectedNode(nodeId, this);
-    }
-
-    @Override
-    public void nodeRemoved() {
-        this.agent.removeConnectedNode(nodeId);
-        channel.disconnect();
-    }
-
-    /**
-     * Gets the ovsdb table store.
-     *
-     * @param dbName the ovsdb database name
-     * @return ovsTableStore, empty if table store is find
-     */
-    private OvsdbTableStore getTableStore(String dbName) {
-        if (ovsdbStore == null) {
-            return null;
-        }
-        return ovsdbStore.getOvsdbTableStore(dbName);
-    }
-
-    /**
-     * Gets the ovsdb row store.
-     *
-     * @param dbName the ovsdb database name
-     * @param tableName the ovsdb table name
-     *
-     * @return ovsRowStore, empty if row store is find
-     */
-    private OvsdbRowStore getRowStore(String dbName, String tableName) {
-        OvsdbTableStore tableStore = getTableStore(dbName);
-        if (tableStore == null) {
-            return null;
-        }
-        return tableStore.getRows(tableName);
-    }
-
-    /**
-     * Gets the ovsdb row.
-     *
-     * @param dbName the ovsdb database name
-     * @param tableName the ovsdb table name
-     * @param uuid the key of the row
-     * @return row, empty if row is find
-     */
-    @Override
-    public Row getRow(String dbName, String tableName, String uuid) {
-        OvsdbTableStore tableStore = getTableStore(dbName);
-        if (tableStore == null) {
-            return null;
-        }
-        OvsdbRowStore rowStore = tableStore.getRows(tableName);
-        if (rowStore == null) {
-            return null;
-        }
-        return rowStore.getRow(uuid);
-    }
-
-    @Override
-    public void removeRow(String dbName, String tableName, String uuid) {
-        OvsdbTableStore tableStore = getTableStore(dbName);
-        if (tableStore == null) {
-            return;
-        }
-        OvsdbRowStore rowStore = tableStore.getRows(tableName);
-        if (rowStore == null) {
-            return;
-        }
-        rowStore.deleteRow(uuid);
-    }
-
-    @Override
-    public void updateOvsdbStore(String dbName, String tableName, String uuid,
-                                 Row row) {
-        OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
-        if (tableStore == null) {
-            tableStore = new OvsdbTableStore();
-        }
-        OvsdbRowStore rowStore = tableStore.getRows(tableName);
-        if (rowStore == null) {
-            rowStore = new OvsdbRowStore();
-        }
-        rowStore.insertRow(uuid, row);
-        tableStore.createOrUpdateTable(tableName, rowStore);
-        ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
-    }
-
-    @Override
-    public String getPortUuid(String portName, String bridgeUuid) {
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-
-        Row bridgeRow = getRow(OvsdbConstant.DATABASENAME,
-                               OvsdbConstant.BRIDGE, bridgeUuid);
-
-        Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
-                                                         OvsdbTable.BRIDGE);
-        if (bridge != null) {
-            OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
-            @SuppressWarnings("unchecked")
-            Set<UUID> ports = setPorts.set();
-            if (ports == null || ports.size() == 0) {
-                log.warn("The port uuid is null");
-                return null;
-            }
-
-            for (UUID uuid : ports) {
-                Row portRow = getRow(OvsdbConstant.DATABASENAME,
-                                     OvsdbConstant.PORT, uuid.value());
-                Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
-                                                           OvsdbTable.PORT);
-                if (port != null && portName.equalsIgnoreCase(port.getName())) {
-                    return uuid.value();
-                }
-            }
-
-        }
-        return null;
-    }
-
-    @Override
-    public String getInterfaceUuid(String portUuid, String portName) {
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-
-        Row portRow = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.PORT,
-                             portUuid);
-        Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
-                                                   OvsdbTable.PORT);
-
-        if (port != null) {
-            OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
-            @SuppressWarnings("unchecked")
-            Set<UUID> interfaces = setInterfaces.set();
-
-            if (interfaces == null || interfaces.size() == 0) {
-                log.warn("The interface uuid is null");
-                return null;
-            }
-
-            for (UUID uuid : interfaces) {
-                Row intfRow = getRow(OvsdbConstant.DATABASENAME,
-                                     OvsdbConstant.INTERFACE, uuid.value());
-                Interface intf = (Interface) TableGenerator
-                        .getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
-                if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
-                    return uuid.value();
-                }
-            }
-
-        }
-
-        return null;
-    }
-
-    @Override
-    public String getBridgeUuid(String bridgeName) {
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-
-        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
-                                             OvsdbConstant.BRIDGE);
-        if (rowStore == null) {
-            log.debug("The bridge uuid is null");
-            return null;
-        }
-
-        ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
-        if (bridgeTableRows == null) {
-            log.debug("The bridge uuid is null");
-            return null;
-        }
-
-        for (String uuid : bridgeTableRows.keySet()) {
-            Bridge bridge = (Bridge) TableGenerator
-                    .getTable(dbSchema, bridgeTableRows.get(uuid),
-                              OvsdbTable.BRIDGE);
-
-            if (bridge.getName().equals(bridgeName)) {
-                return uuid;
-            }
-
-        }
-        return null;
-    }
-
-    @Override
-    public String getControllerUuid(String controllerName,
-                                    String controllerTarget) {
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
-                                             OvsdbConstant.CONTROLLER);
-        if (rowStore == null) {
-            log.debug("The controller uuid is null");
-            return null;
-        }
-
-        ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
-        if (controllerTableRows != null) {
-            for (String uuid : controllerTableRows.keySet()) {
-
-                Controller controller = (Controller) TableGenerator
-                        .getTable(dbSchema, controllerTableRows.get(uuid),
-                                  OvsdbTable.CONTROLLER);
-                String target = (String) controller.getTargetColumn().data();
-                if (target.equalsIgnoreCase(controllerTarget)) {
-                    return uuid;
-                }
-
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public String getOvsUuid(String dbName) {
-        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
-                                             OvsdbConstant.DATABASENAME);
-        if (rowStore == null) {
-            log.debug("The bridge uuid is null");
-            return null;
-        }
-        ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
-        if (ovsTableRows != null) {
-            for (String uuid : ovsTableRows.keySet()) {
-                Row row = ovsTableRows.get(uuid);
-                String tableName = row.tableName();
-                if (tableName.equals(dbName)) {
-                    return uuid;
-                }
-            }
-        }
-        return null;
-    }
-
-    @Override
-    public void createPort(String bridgeName, String portName) {
-        String bridgeUuid = getBridgeUuid(bridgeName);
-        if (bridgeUuid == null) {
-            log.error("Can't find bridge {} in {}", bridgeName,
-                      nodeId.getIpAddress());
-            return;
-        }
-
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-        String portUuid = getPortUuid(portName, bridgeUuid);
-
-        Port port = (Port) TableGenerator
-                .createTable(dbSchema, OvsdbTable.PORT);
-
-        port.setName(portName);
-        if (portUuid == null) {
-            insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
-                      "ports", bridgeUuid, port.getRow());
-        } else {
-            updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
-        }
-
-        return;
-    }
-
-    @Override
-    public void dropPort(String bridgeName, String portName) {
-        String bridgeUuid = getBridgeUuid(bridgeName);
-        if (bridgeUuid == null) {
-            log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
-            return;
-        }
-
-        String portUuid = getPortUuid(portName, bridgeUuid);
-        if (portUuid != null) {
-            log.info("Port {} delete", portName);
-            deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
-                      OvsdbConstant.BRIDGE, "ports");
-        }
-    }
-
-    @Override
-    public void createBridge(String bridgeName) {
-        log.debug("create bridge {}", bridgeName);
-
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-        if (dbSchema == null) {
-            log.warn("The schema is null");
-            return;
-        }
-
-        Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
-                                                            OvsdbTable.BRIDGE);
-        if (bridge == null) {
-            log.debug("Can not create bridge");
-            return;
-        }
-
-        Set<String> failModes = new HashSet<>();
-        failModes.add("secure");
-        bridge.setFailMode(failModes);
-
-        Set<String> protocols = new HashSet<>();
-        protocols.add(OvsdbConstant.OPENFLOW13);
-        bridge.setProtocols(protocols);
-
-        String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
-        if (ovsUuid == null) {
-            log.warn("The Open_vSwitch is null");
-            return;
-        }
-
-        String bridgeUuid = getBridgeUuid(bridgeName);
-        if (bridgeUuid == null) {
-            log.debug("Create a new bridge");
-
-            bridge.setName(bridgeName);
-            bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
-                                   OvsdbConstant.DATABASENAME, "bridges",
-                                   ovsUuid, bridge.getRow());
-
-            if (bridgeUuid != null) {
-                Port port = (Port) TableGenerator.createTable(dbSchema,
-                                                              OvsdbTable.PORT);
-                if (port != null) {
-                    log.debug("the port is not null");
-                    port.setName(bridgeName);
-
-                    insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
-                              port.getRow());
-                }
-            }
-
-        } else {
-            log.info("Update a bridge");
-            updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
-        }
-
-        setController(bridgeUuid);
-        log.info("Create bridge success");
-    }
-
-    /**
-     * Sets the Controller.
-     *
-     * @param bridgeUuid bridge uuid
-     */
-    private void setController(String bridgeUuid) {
-        String controllerUuid = null;
-        String iPAddress = IpAddress.valueOf(((InetSocketAddress) channel
-                                                     .localAddress())
-                                                     .getAddress()
-                                                     .getHostAddress())
-                .toString();
-
-        String target = "tcp:" + iPAddress + ":" + OvsdbConstant.OFPORT;
-        log.debug("controller IP {}: port {}", iPAddress, OvsdbConstant.OFPORT);
-
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-        Controller controller = (Controller) TableGenerator
-                .createTable(dbSchema, OvsdbTable.CONTROLLER);
-
-        if (controller != null) {
-            controller.setTarget(target);
-            controllerUuid = getControllerUuid(OvsdbConstant.CONTROLLER, target);
-            if (controllerUuid == null) {
-
-                insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
-                          OvsdbConstant.BRIDGE, "controller", bridgeUuid,
-                          controller.getRow());
-
-            } else {
-
-                Bridge bridge = (Bridge) TableGenerator
-                        .createTable(dbSchema, OvsdbTable.BRIDGE);
-                Set<UUID> controllerUuids = new HashSet<>();
-                controllerUuids.add(UUID.uuid(controllerUuid));
-                bridge.setController(controllerUuids);
-                updateConfig(OvsdbConstant.CONTROLLER, "_uuid", bridgeUuid, bridge.getRow());
-
-            }
-        }
-
-    }
-
-    @Override
-    public void dropBridge(String bridgeName) {
-        String bridgeUUID = getBridgeUuid(bridgeName);
-        if (bridgeUUID == null) {
-            log.warn("Could not find bridge in node", nodeId.getIpAddress());
-            return;
-        }
-        deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUUID,
-                  OvsdbConstant.DATABASENAME, "bridges");
-    }
-
-    @Override
-    public void createTunnel(IpAddress srcIp, IpAddress dstIp) {
-        String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
-        if (bridgeUuid == null) {
-            log.warn("Could not find bridge {} and Could not create tunnel. ",
-                     OvsdbConstant.INTEGRATION_BRIDGE);
-            return;
-        }
-
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-        String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
-        String portUuid = getPortUuid(portName, bridgeUuid);
-
-        Port port = (Port) TableGenerator
-                .createTable(dbSchema, OvsdbTable.PORT);
-        if (port != null) {
-            port.setName(portName);
-        }
-
-        if (portUuid == null) {
-            portUuid = insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
-                      "ports", bridgeUuid, port.getRow());
-        } else {
-            updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
-        }
-
-        // When a tunnel is created, A row is inserted into port table and
-        // interface table of the ovsdb node.
-        // and the following step is to get the interface uuid from local store
-        // in controller node.
-        // but it need spend some time synchronising data between node and
-        // controller.
-        // so loop to judge if interfaceUUid is null is necessary.
-        String interfaceUuid = null;
-        for (int i = 0; i < 10; i++) {
-            interfaceUuid = getInterfaceUuid(portUuid, portName);
-            if (interfaceUuid == null) {
-                try {
-                    Thread.sleep(500);
-                } catch (InterruptedException e) {
-                    log.warn("Interrupted while waiting to get interfaceUuid");
-                    Thread.currentThread().interrupt();
-                }
-            } else {
-                break;
-            }
-        }
-
-        if (interfaceUuid != null) {
-
-            Interface tunInterface = (Interface) TableGenerator
-                    .createTable(dbSchema, OvsdbTable.INTERFACE);
-
-            if (tunInterface != null) {
-
-                tunInterface.setType(OvsdbConstant.TYPEVXLAN);
-                Map<String, String> options = Maps.newHashMap();
-                options.put("key", "flow");
-                options.put("local_ip", srcIp.toString());
-                options.put("remote_ip", dstIp.toString());
-                tunInterface.setOptions(options);
-                updateConfig(OvsdbConstant.INTERFACE, "_uuid", interfaceUuid,
-                          tunInterface.getRow());
-                log.info("Tunnel added success", tunInterface);
-
-            }
-        }
-
-        return;
-    }
-
-    @Override
-    public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
-        String bridgeName = OvsdbConstant.INTEGRATION_BRIDGE;
-        String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
-        String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
-        if (bridgeUuid == null) {
-            log.warn("Could not find bridge {} in {}", bridgeName,
-                     nodeId.getIpAddress());
-            return;
-        }
-
-        String portUUID = getPortUuid(portName, bridgeUuid);
-        if (portUUID != null) {
-            log.info("Delete tunnel");
-            deleteConfig(OvsdbConstant.PORT, "_uuid", portUUID,
-                      OvsdbConstant.BRIDGE, "ports");
-        }
-
-        return;
-    }
-
-    /**
-     * Delete transact config.
-     *
-     * @param childTableName child table name
-     * @param childColumnName child column name
-     * @param childUuid child row uuid
-     * @param parentTableName parent table name
-     * @param parentColumnName parent column
-     *
-     */
-    private void deleteConfig(String childTableName, String childColumnName,
-                           String childUuid, String parentTableName,
-                           String parentColumnName) {
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-        TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
-
-        ArrayList<Operation> operations = Lists.newArrayList();
-        if (parentTableName != null && parentColumnName != null) {
-            TableSchema parentTableSchema = dbSchema
-                    .getTableSchema(parentTableName);
-            ColumnSchema parentColumnSchema = parentTableSchema
-                    .getColumnSchema(parentColumnName);
-            List<Mutation> mutations = Lists.newArrayList();
-            Mutation mutation = MutationUtil.delete(parentColumnSchema.name(),
-                                                    UUID.uuid(childUuid));
-            mutations.add(mutation);
-            List<Condition> conditions = Lists.newArrayList();
-            Condition condition = ConditionUtil.includes(parentColumnName,
-                                                         UUID.uuid(childUuid));
-            conditions.add(condition);
-            Mutate op = new Mutate(parentTableSchema, conditions, mutations);
-            operations.add(op);
-        }
-
-        List<Condition> conditions = Lists.newArrayList();
-        Condition condition = ConditionUtil.equals(childColumnName, UUID.uuid(childUuid));
-        conditions.add(condition);
-        Delete del = new Delete(childTableSchema, conditions);
-        operations.add(del);
-        transactConfig(OvsdbConstant.DATABASENAME, operations);
-
-        return;
-    }
-
-    /**
-     * Update transact config.
-     *
-     * @param tableName table name
-     * @param columnName column name
-     * @param uuid uuid
-     * @param row the config data
-     *
-     */
-    private void updateConfig(String tableName, String columnName, String uuid,
-                           Row row) {
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-        TableSchema tableSchema = dbSchema.getTableSchema(tableName);
-
-        List<Condition> conditions = Lists.newArrayList();
-        Condition condition = ConditionUtil.equals(columnName, UUID.uuid(uuid));
-        conditions.add(condition);
-
-        Update update = new Update(tableSchema, row, conditions);
-
-        ArrayList<Operation> operations = Lists.newArrayList();
-        operations.add(update);
-
-        transactConfig(OvsdbConstant.DATABASENAME, operations);
-    }
-
-    /**
-     * Insert transact config.
-     *
-     * @param childTableName child table name
-     * @param childColumnName child column name
-     * @param parentTableName parent table name
-     * @param parentColumnName parent column
-     * @param parentUuid parent uuid
-     * @param row the config data
-     *
-     * @return uuid, empty if no uuid is find
-     */
-    private String insertConfig(String childTableName, String childColumnName,
-                             String parentTableName, String parentColumnName,
-                             String parentUuid, Row row) {
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-        TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
-
-        String namedUuid = childTableName;
-        Insert insert = new Insert(tableSchema, namedUuid, row);
-
-        ArrayList<Operation> operations = Lists.newArrayList();
-        operations.add(insert);
-
-        if (parentTableName != null && parentColumnName != null) {
-            TableSchema parentTableSchema = dbSchema
-                    .getTableSchema(parentTableName);
-            ColumnSchema parentColumnSchema = parentTableSchema
-                    .getColumnSchema(parentColumnName);
-
-            List<Mutation> mutations = Lists.newArrayList();
-            Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
-                                                    UUID.uuid(namedUuid));
-            mutations.add(mutation);
-
-            List<Condition> conditions = Lists.newArrayList();
-            Condition condition = ConditionUtil.equals("_uuid",
-                                                       UUID.uuid(parentUuid));
-            conditions.add(condition);
-
-            Mutate op = new Mutate(parentTableSchema, conditions, mutations);
-            operations.add(op);
-        }
-        if (childTableName.equalsIgnoreCase(OvsdbConstant.PORT)) {
-            log.info("Handle port insert");
-            Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE,
-                                                    row);
-
-            if (intfInsert != null) {
-                operations.add(intfInsert);
-            }
-
-            Insert ins = (Insert) operations.get(0);
-            ins.getRow().put("interfaces",
-                             UUID.uuid(OvsdbConstant.INTERFACE));
-        }
-
-        List<OperationResult> results;
-        try {
-            results = transactConfig(OvsdbConstant.DATABASENAME, operations)
-                    .get();
-
-            return results.get(0).getUuid().value();
-        } catch (InterruptedException e) {
-            log.warn("Interrupted while waiting to get result");
-            Thread.currentThread().interrupt();
-        } catch (ExecutionException e) {
-            log.error("Exception thrown while to get result");
-        }
-
-        return null;
-    }
-
-    /**
-     * Handles port insert.
-     *
-     * @param tableName ovsdb table interface
-     * @param portRow row of port
-     *
-     * @return insert, empty if null
-     */
-    private Insert handlePortInsertTable(String tableName, Row portRow) {
-        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
-
-        TableSchema portTableSchema = dbSchema
-                .getTableSchema(OvsdbConstant.PORT);
-        ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
-
-        String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
-
-        Interface inf = (Interface) TableGenerator
-                .createTable(dbSchema, OvsdbTable.INTERFACE);
-
-        inf.setName(portName);
-
-        TableSchema intfTableSchema = dbSchema
-                .getTableSchema(OvsdbConstant.INTERFACE);
-        Insert insert = new Insert(intfTableSchema, OvsdbConstant.INTERFACE,
-                                   inf.getRow());
-        return insert;
-    }
-
-    /**
-     * Gets tunnel name.
-     *
-     * @param tunnelType
-     * @param dstIp the remote ip address
-     *
-     * @return tunnel name
-     */
-    private String getTunnelName(String tunnelType, IpAddress dstIp) {
-        return tunnelType + "-" + dstIp.toString();
-    }
-
-    @Override
-    public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
-        if (dbName == null) {
-            return null;
-        }
-        DatabaseSchema databaseSchema = schema.get(dbName);
-        if (databaseSchema == null) {
-            List<String> dbNames = new ArrayList<String>();
-            dbNames.add(dbName);
-            Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() {
-                @Override
-                public DatabaseSchema apply(JsonNode input) {
-                    log.info("Get ovsdb database schema", dbName);
-                    DatabaseSchema dbSchema = FromJsonUtil
-                            .jsonNodeToDbSchema(dbName, input);
-                    if (dbSchema == null) {
-                        log.debug("Get ovsdb database schema error");
-                        return null;
-                    }
-                    schema.put(dbName, dbSchema);
-
-                    return dbSchema;
-                }
-            };
-
-            ListenableFuture<JsonNode> input = getSchema(dbNames);
-            if (input != null) {
-                return Futures.transform(input, rowFunction);
-            }
-            return null;
-        } else {
-            return Futures.immediateFuture(databaseSchema);
-        }
-    }
-
-    @Override
-    public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
-        if (dbName == null) {
-            return null;
-        }
-        DatabaseSchema dbSchema = schema.get(dbName);
-        if (dbSchema != null) {
-            Function<JsonNode, TableUpdates> rowFunction = new Function<JsonNode, TableUpdates>() {
-                @Override
-                public TableUpdates apply(JsonNode input) {
-                    log.info("Get table updates");
-                    TableUpdates updates = FromJsonUtil
-                            .jsonNodeToTableUpdates(input, dbSchema);
-                    if (updates == null) {
-                        log.debug("Get table updates error");
-                        return null;
-                    }
-                    return updates;
-                }
-            };
-            return Futures.transform(monitor(dbSchema, id), rowFunction);
-        }
-        return null;
-    }
-
-    @Override
-    public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
-                                                                  List<Operation> operations) {
-        if (dbName == null) {
-            return null;
-        }
-        DatabaseSchema dbSchema = schema.get(dbName);
-        if (dbSchema != null) {
-            Function<List<JsonNode>, List<OperationResult>> rowFunction =
-                    new Function<List<JsonNode>, List<OperationResult>>() {
-                @Override
-                public List<OperationResult> apply(List<JsonNode> input) {
-                    log.info("Get ovsdb operation result");
-                    List<OperationResult> result = FromJsonUtil
-                            .jsonNodeToOperationResult(input, operations);
-
-                    if (result == null) {
-                        log.debug("The operation result is null");
-                        return null;
-                    }
-                    return result;
-                }
-            };
-            return Futures.transform(transact(dbSchema, operations),
-                                     rowFunction);
-        }
-        return null;
-    }
-
-    @Override
-    public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
-        String id = java.util.UUID.randomUUID().toString();
-        String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
-
-        SettableFuture<JsonNode> sf = SettableFuture.create();
-        requestResult.put(id, sf);
-        requestMethod.put(id, "getSchema");
-
-        channel.writeAndFlush(getSchemaString);
-        return sf;
-
-    }
-
-    @Override
-    public ListenableFuture<List<String>> echo() {
-        String id = java.util.UUID.randomUUID().toString();
-        String echoString = JsonRpcWriterUtil.echoStr(id);
-
-        SettableFuture<List<String>> sf = SettableFuture.create();
-        requestResult.put(id, sf);
-        requestMethod.put(id, "echo");
-
-        channel.writeAndFlush(echoString);
-        return sf;
-
-    }
-
-    @Override
-    public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
-                                              String monitorId) {
-        String id = java.util.UUID.randomUUID().toString();
-        String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
-                                                            dbSchema);
-
-        SettableFuture<JsonNode> sf = SettableFuture.create();
-        requestResult.put(id, sf);
-        requestMethod.put(id, "monitor");
-
-        channel.writeAndFlush(monitorString);
-        return sf;
-
-    }
-
-    @Override
-    public ListenableFuture<List<String>> listDbs() {
-        String id = java.util.UUID.randomUUID().toString();
-        String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
-
-        SettableFuture<List<String>> sf = SettableFuture.create();
-        requestResult.put(id, sf);
-        requestMethod.put(id, "listDbs");
-
-        channel.writeAndFlush(listDbsString);
-        return sf;
-
-    }
-
-    @Override
-    public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
-                                                     List<Operation> operations) {
-        String id = java.util.UUID.randomUUID().toString();
-        String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
-                                                              operations);
-
-        SettableFuture<List<JsonNode>> sf = SettableFuture.create();
-        requestResult.put(id, sf);
-        requestMethod.put(id, "transact");
-
-        channel.writeAndFlush(transactString);
-        return sf;
-
-    }
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Override
-    public void processResult(JsonNode response) {
-        log.debug("Handle result");
-        String requestId = response.get("id").asText();
-        SettableFuture sf = requestResult.get(requestId);
-        if (sf == null) {
-            log.debug("No such future to process");
-            return;
-        }
-        String methodName = requestMethod.get(requestId);
-
-        Object result;
-        result = FromJsonUtil.jsonResultParser(response, methodName);
-
-        sf.set(result);
-        return;
-    }
-
-    @Override
-    public void processRequest(JsonNode requestJson) {
-        log.debug("Handle request");
-        if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
-            log.debug("handle echo request");
-
-            String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
-            channel.writeAndFlush(replyString);
-
-            return;
-        } else {
-            FromJsonUtil
-                    .jsonCallbackRequestParser(requestJson, monitorCallBack);
-            return;
-        }
-    }
-
-    @Override
-    public void setCallback(Callback monitorCallback) {
-        this.monitorCallBack = monitorCallback;
-    }
-
-    @Override
-    public Set<OvsdbTunnel> getTunnels() {
-        return ovsdbTunnels;
-    }
-
-    @Override
-    public Set<OvsdbBridge> getBridges() {
-        Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
-        OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
-        if (tableStore == null) {
-            return null;
-        }
-        OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.BRIDGE);
-        if (rowStore == null) {
-            return null;
-        }
-        ConcurrentMap<String, Row> rows = rowStore.getRowStore();
-        for (String uuid : rows.keySet()) {
-            Row row = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.BRIDGE,
-                             uuid);
-            OvsdbBridge ovsdbBridge = getOvsdbBridge(row);
-            if (ovsdbBridge != null) {
-                ovsdbBridges.add(ovsdbBridge);
-            }
-        }
-        return ovsdbBridges;
-    }
-
-    @Override
-    public Set<OvsdbPort> getPorts() {
-        Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
-        OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
-        if (tableStore == null) {
-            return null;
-        }
-        OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
-        if (rowStore == null) {
-            return null;
-        }
-        ConcurrentMap<String, Row> rows = rowStore.getRowStore();
-        for (String uuid : rows.keySet()) {
-            Row row = getRow(OvsdbConstant.DATABASENAME,
-                             OvsdbConstant.INTERFACE, uuid);
-            OvsdbPort ovsdbPort = getOvsdbPort(row);
-            if (ovsdbPort != null) {
-                ovsdbPorts.add(ovsdbPort);
-            }
-        }
-        return ovsdbPorts;
-    }
-
-    @Override
-    public DatabaseSchema getDatabaseSchema(String dbName) {
-        return schema.get(dbName);
-    }
-
-    //Gets ovsdb port.
-    private OvsdbPort getOvsdbPort(Row row) {
-        DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
-        Interface intf = (Interface) TableGenerator
-                .getTable(dbSchema, row, OvsdbTable.INTERFACE);
-        if (intf == null) {
-            return null;
-        }
-        long ofPort = getOfPort(intf);
-        String portName = intf.getName();
-        if ((ofPort < 0) || (portName == null)) {
-            return null;
-        }
-
-        OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
-                                            new OvsdbPortName(portName));
-        return ovsdbPort;
-    }
-
-    ////Gets ovsdb bridge.
-    private OvsdbBridge getOvsdbBridge(Row row) {
-        DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
-        Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row,
-                                                         OvsdbTable.BRIDGE);
-        if (bridge == null) {
-            return null;
-        }
-
-        OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
-        @SuppressWarnings("unchecked")
-        Set<String> datapathIds = datapathIdSet.set();
-        if (datapathIds == null || datapathIds.size() == 0) {
-            return null;
-        }
-        String datapathId = (String) datapathIds.toArray()[0];
-        String bridgeName = bridge.getName();
-        if ((datapathId == null) || (bridgeName == null)) {
-            return null;
-        }
-
-        OvsdbBridge ovsdbBridge = new OvsdbBridge(new OvsdbBridgeName(bridgeName),
-                                                  new OvsdbDatapathId(datapathId));
-        return ovsdbBridge;
-    }
-
-    //Gets ofPort in the interface.
-    private long getOfPort(Interface intf) {
-        OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
-        @SuppressWarnings("unchecked")
-        Set<Integer> ofPorts = ofPortSet.set();
-        while (ofPorts == null || ofPorts.size() <= 0) {
-            log.debug("The ofport is null in {}", intf.getName());
-            return -1;
-        }
-        // return (long) ofPorts.toArray()[0];
-        Iterator<Integer> it = ofPorts.iterator();
-        return Long.parseLong(it.next().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.ovsdb.controller.driver;
+
+import io.netty.channel.Channel;
+
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+
+import org.onlab.packet.IpAddress;
+import org.onosproject.ovsdb.controller.OvsdbBridge;
+import org.onosproject.ovsdb.controller.OvsdbBridgeName;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbConstant;
+import org.onosproject.ovsdb.controller.OvsdbDatapathId;
+import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.ovsdb.controller.OvsdbPort;
+import org.onosproject.ovsdb.controller.OvsdbPortName;
+import org.onosproject.ovsdb.controller.OvsdbPortNumber;
+import org.onosproject.ovsdb.controller.OvsdbRowStore;
+import org.onosproject.ovsdb.controller.OvsdbStore;
+import org.onosproject.ovsdb.controller.OvsdbTableStore;
+import org.onosproject.ovsdb.controller.OvsdbTunnel;
+import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
+import org.onosproject.ovsdb.rfc.message.OperationResult;
+import org.onosproject.ovsdb.rfc.message.TableUpdates;
+import org.onosproject.ovsdb.rfc.notation.Condition;
+import org.onosproject.ovsdb.rfc.notation.Mutation;
+import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.operations.Delete;
+import org.onosproject.ovsdb.rfc.operations.Insert;
+import org.onosproject.ovsdb.rfc.operations.Mutate;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.operations.Update;
+import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+import org.onosproject.ovsdb.rfc.table.Bridge;
+import org.onosproject.ovsdb.rfc.table.Controller;
+import org.onosproject.ovsdb.rfc.table.Interface;
+import org.onosproject.ovsdb.rfc.table.OvsdbTable;
+import org.onosproject.ovsdb.rfc.table.Port;
+import org.onosproject.ovsdb.rfc.table.TableGenerator;
+import org.onosproject.ovsdb.rfc.utils.ConditionUtil;
+import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
+import org.onosproject.ovsdb.rfc.utils.JsonRpcWriterUtil;
+import org.onosproject.ovsdb.rfc.utils.MutationUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.SettableFuture;
+
+/**
+ * An representation of an ovsdb client.
+ */
+public class DefaultOvsdbClient
+        implements OvsdbProviderService, OvsdbClientService {
+
+    private final Logger log = LoggerFactory
+            .getLogger(DefaultOvsdbClient.class);
+
+    private Channel channel;
+
+    private OvsdbAgent agent;
+    private boolean connected;
+    private OvsdbNodeId nodeId;
+    private Callback monitorCallBack;
+
+    private OvsdbStore ovsdbStore = new OvsdbStore();
+
+    private final Map<String, String> requestMethod = Maps.newHashMap();
+    private final Map<String, SettableFuture<? extends Object>> requestResult = Maps
+            .newHashMap();
+
+    private final Map<String, DatabaseSchema> schema = Maps.newHashMap();
+    private final Set<OvsdbTunnel> ovsdbTunnels = new HashSet<OvsdbTunnel>();
+
+    /**
+     * Creates an OvsdbClient.
+     *
+     * @param nodeId ovsdb node id
+     */
+    public DefaultOvsdbClient(OvsdbNodeId nodeId) {
+        this.nodeId = nodeId;
+    }
+
+    @Override
+    public OvsdbNodeId nodeId() {
+        return nodeId;
+    }
+
+    @Override
+    public void setAgent(OvsdbAgent agent) {
+        if (this.agent == null) {
+            this.agent = agent;
+        }
+    }
+
+    @Override
+    public void setChannel(Channel channel) {
+        this.channel = channel;
+    }
+
+    @Override
+    public void setConnection(boolean connected) {
+        this.connected = connected;
+    }
+
+    @Override
+    public boolean isConnected() {
+        return this.connected;
+    }
+
+    @Override
+    public void nodeAdded() {
+        this.agent.addConnectedNode(nodeId, this);
+    }
+
+    @Override
+    public void nodeRemoved() {
+        this.agent.removeConnectedNode(nodeId);
+        channel.disconnect();
+    }
+
+    /**
+     * Gets the ovsdb table store.
+     *
+     * @param dbName the ovsdb database name
+     * @return ovsTableStore, empty if table store is find
+     */
+    private OvsdbTableStore getTableStore(String dbName) {
+        if (ovsdbStore == null) {
+            return null;
+        }
+        return ovsdbStore.getOvsdbTableStore(dbName);
+    }
+
+    /**
+     * Gets the ovsdb row store.
+     *
+     * @param dbName the ovsdb database name
+     * @param tableName the ovsdb table name
+     *
+     * @return ovsRowStore, empty if row store is find
+     */
+    private OvsdbRowStore getRowStore(String dbName, String tableName) {
+        OvsdbTableStore tableStore = getTableStore(dbName);
+        if (tableStore == null) {
+            return null;
+        }
+        return tableStore.getRows(tableName);
+    }
+
+    /**
+     * Gets the ovsdb row.
+     *
+     * @param dbName the ovsdb database name
+     * @param tableName the ovsdb table name
+     * @param uuid the key of the row
+     * @return row, empty if row is find
+     */
+    @Override
+    public Row getRow(String dbName, String tableName, String uuid) {
+        OvsdbTableStore tableStore = getTableStore(dbName);
+        if (tableStore == null) {
+            return null;
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(tableName);
+        if (rowStore == null) {
+            return null;
+        }
+        return rowStore.getRow(uuid);
+    }
+
+    @Override
+    public void removeRow(String dbName, String tableName, String uuid) {
+        OvsdbTableStore tableStore = getTableStore(dbName);
+        if (tableStore == null) {
+            return;
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(tableName);
+        if (rowStore == null) {
+            return;
+        }
+        rowStore.deleteRow(uuid);
+    }
+
+    @Override
+    public void updateOvsdbStore(String dbName, String tableName, String uuid,
+                                 Row row) {
+        OvsdbTableStore tableStore = ovsdbStore.getOvsdbTableStore(dbName);
+        if (tableStore == null) {
+            tableStore = new OvsdbTableStore();
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(tableName);
+        if (rowStore == null) {
+            rowStore = new OvsdbRowStore();
+        }
+        rowStore.insertRow(uuid, row);
+        tableStore.createOrUpdateTable(tableName, rowStore);
+        ovsdbStore.createOrUpdateOvsdbStore(dbName, tableStore);
+    }
+
+    @Override
+    public String getPortUuid(String portName, String bridgeUuid) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+        Row bridgeRow = getRow(OvsdbConstant.DATABASENAME,
+                               OvsdbConstant.BRIDGE, bridgeUuid);
+
+        Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
+                                                         OvsdbTable.BRIDGE);
+        if (bridge != null) {
+            OvsdbSet setPorts = (OvsdbSet) bridge.getPortsColumn().data();
+            @SuppressWarnings("unchecked")
+            Set<UUID> ports = setPorts.set();
+            if (ports == null || ports.size() == 0) {
+                log.warn("The port uuid is null");
+                return null;
+            }
+
+            for (UUID uuid : ports) {
+                Row portRow = getRow(OvsdbConstant.DATABASENAME,
+                                     OvsdbConstant.PORT, uuid.value());
+                Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
+                                                           OvsdbTable.PORT);
+                if (port != null && portName.equalsIgnoreCase(port.getName())) {
+                    return uuid.value();
+                }
+            }
+
+        }
+        return null;
+    }
+
+    @Override
+    public String getInterfaceUuid(String portUuid, String portName) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+        Row portRow = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.PORT,
+                             portUuid);
+        Port port = (Port) TableGenerator.getTable(dbSchema, portRow,
+                                                   OvsdbTable.PORT);
+
+        if (port != null) {
+            OvsdbSet setInterfaces = (OvsdbSet) port.getInterfacesColumn().data();
+            @SuppressWarnings("unchecked")
+            Set<UUID> interfaces = setInterfaces.set();
+
+            if (interfaces == null || interfaces.size() == 0) {
+                log.warn("The interface uuid is null");
+                return null;
+            }
+
+            for (UUID uuid : interfaces) {
+                Row intfRow = getRow(OvsdbConstant.DATABASENAME,
+                                     OvsdbConstant.INTERFACE, uuid.value());
+                Interface intf = (Interface) TableGenerator
+                        .getTable(dbSchema, intfRow, OvsdbTable.INTERFACE);
+                if (intf != null && portName.equalsIgnoreCase(intf.getName())) {
+                    return uuid.value();
+                }
+            }
+
+        }
+
+        return null;
+    }
+
+    @Override
+    public String getBridgeUuid(String bridgeName) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+                                             OvsdbConstant.BRIDGE);
+        if (rowStore == null) {
+            log.debug("The bridge uuid is null");
+            return null;
+        }
+
+        ConcurrentMap<String, Row> bridgeTableRows = rowStore.getRowStore();
+        if (bridgeTableRows == null) {
+            log.debug("The bridge uuid is null");
+            return null;
+        }
+
+        for (String uuid : bridgeTableRows.keySet()) {
+            Bridge bridge = (Bridge) TableGenerator
+                    .getTable(dbSchema, bridgeTableRows.get(uuid),
+                              OvsdbTable.BRIDGE);
+
+            if (bridge.getName().equals(bridgeName)) {
+                return uuid;
+            }
+
+        }
+        return null;
+    }
+
+    @Override
+    public String getControllerUuid(String controllerName,
+                                    String controllerTarget) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+                                             OvsdbConstant.CONTROLLER);
+        if (rowStore == null) {
+            log.debug("The controller uuid is null");
+            return null;
+        }
+
+        ConcurrentMap<String, Row> controllerTableRows = rowStore.getRowStore();
+        if (controllerTableRows != null) {
+            for (String uuid : controllerTableRows.keySet()) {
+
+                Controller controller = (Controller) TableGenerator
+                        .getTable(dbSchema, controllerTableRows.get(uuid),
+                                  OvsdbTable.CONTROLLER);
+                String target = (String) controller.getTargetColumn().data();
+                if (target.equalsIgnoreCase(controllerTarget)) {
+                    return uuid;
+                }
+
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getOvsUuid(String dbName) {
+        OvsdbRowStore rowStore = getRowStore(OvsdbConstant.DATABASENAME,
+                                             OvsdbConstant.DATABASENAME);
+        if (rowStore == null) {
+            log.debug("The bridge uuid is null");
+            return null;
+        }
+        ConcurrentMap<String, Row> ovsTableRows = rowStore.getRowStore();
+        if (ovsTableRows != null) {
+            for (String uuid : ovsTableRows.keySet()) {
+                Row row = ovsTableRows.get(uuid);
+                String tableName = row.tableName();
+                if (tableName.equals(dbName)) {
+                    return uuid;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public void createPort(String bridgeName, String portName) {
+        String bridgeUuid = getBridgeUuid(bridgeName);
+        if (bridgeUuid == null) {
+            log.error("Can't find bridge {} in {}", bridgeName,
+                      nodeId.getIpAddress());
+            return;
+        }
+
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        String portUuid = getPortUuid(portName, bridgeUuid);
+
+        Port port = (Port) TableGenerator
+                .createTable(dbSchema, OvsdbTable.PORT);
+
+        port.setName(portName);
+        if (portUuid == null) {
+            insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
+                      "ports", bridgeUuid, port.getRow());
+        } else {
+            updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
+        }
+
+        return;
+    }
+
+    @Override
+    public void dropPort(String bridgeName, String portName) {
+        String bridgeUuid = getBridgeUuid(bridgeName);
+        if (bridgeUuid == null) {
+            log.error("Could not find Bridge {} in {}", bridgeName, nodeId);
+            return;
+        }
+
+        String portUuid = getPortUuid(portName, bridgeUuid);
+        if (portUuid != null) {
+            log.info("Port {} delete", portName);
+            deleteConfig(OvsdbConstant.PORT, "_uuid", portUuid,
+                      OvsdbConstant.BRIDGE, "ports");
+        }
+    }
+
+    @Override
+    public void createBridge(String bridgeName) {
+        log.debug("create bridge {}", bridgeName);
+
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        if (dbSchema == null) {
+            log.warn("The schema is null");
+            return;
+        }
+
+        Bridge bridge = (Bridge) TableGenerator.createTable(dbSchema,
+                                                            OvsdbTable.BRIDGE);
+        if (bridge == null) {
+            log.debug("Can not create bridge");
+            return;
+        }
+
+        Set<String> failModes = new HashSet<>();
+        failModes.add("secure");
+        bridge.setFailMode(failModes);
+
+        Set<String> protocols = new HashSet<>();
+        protocols.add(OvsdbConstant.OPENFLOW13);
+        bridge.setProtocols(protocols);
+
+        String ovsUuid = getOvsUuid(OvsdbConstant.DATABASENAME);
+        if (ovsUuid == null) {
+            log.warn("The Open_vSwitch is null");
+            return;
+        }
+
+        String bridgeUuid = getBridgeUuid(bridgeName);
+        if (bridgeUuid == null) {
+            log.debug("Create a new bridge");
+
+            bridge.setName(bridgeName);
+            bridgeUuid = insertConfig(OvsdbConstant.BRIDGE, "_uuid",
+                                   OvsdbConstant.DATABASENAME, "bridges",
+                                   ovsUuid, bridge.getRow());
+
+            if (bridgeUuid != null) {
+                Port port = (Port) TableGenerator.createTable(dbSchema,
+                                                              OvsdbTable.PORT);
+                if (port != null) {
+                    log.debug("the port is not null");
+                    port.setName(bridgeName);
+
+                    insertConfig(OvsdbConstant.PORT, "_uuid", "Bridge", "ports", bridgeUuid,
+                              port.getRow());
+                }
+            }
+
+        } else {
+            log.info("Update a bridge");
+            updateConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUuid, bridge.getRow());
+        }
+
+        setController(bridgeUuid);
+        log.info("Create bridge success");
+    }
+
+    /**
+     * Sets the Controller.
+     *
+     * @param bridgeUuid bridge uuid
+     */
+    private void setController(String bridgeUuid) {
+        String controllerUuid = null;
+        String iPAddress = IpAddress.valueOf(((InetSocketAddress) channel
+                                                     .localAddress())
+                                                     .getAddress()
+                                                     .getHostAddress())
+                .toString();
+
+        String target = "tcp:" + iPAddress + ":" + OvsdbConstant.OFPORT;
+        log.debug("controller IP {}: port {}", iPAddress, OvsdbConstant.OFPORT);
+
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        Controller controller = (Controller) TableGenerator
+                .createTable(dbSchema, OvsdbTable.CONTROLLER);
+
+        if (controller != null) {
+            controller.setTarget(target);
+            controllerUuid = getControllerUuid(OvsdbConstant.CONTROLLER, target);
+            if (controllerUuid == null) {
+
+                insertConfig(OvsdbConstant.CONTROLLER, "_uuid",
+                          OvsdbConstant.BRIDGE, "controller", bridgeUuid,
+                          controller.getRow());
+
+            } else {
+
+                Bridge bridge = (Bridge) TableGenerator
+                        .createTable(dbSchema, OvsdbTable.BRIDGE);
+                Set<UUID> controllerUuids = new HashSet<>();
+                controllerUuids.add(UUID.uuid(controllerUuid));
+                bridge.setController(controllerUuids);
+                updateConfig(OvsdbConstant.CONTROLLER, "_uuid", bridgeUuid, bridge.getRow());
+
+            }
+        }
+
+    }
+
+    @Override
+    public void dropBridge(String bridgeName) {
+        String bridgeUUID = getBridgeUuid(bridgeName);
+        if (bridgeUUID == null) {
+            log.warn("Could not find bridge in node", nodeId.getIpAddress());
+            return;
+        }
+        deleteConfig(OvsdbConstant.BRIDGE, "_uuid", bridgeUUID,
+                  OvsdbConstant.DATABASENAME, "bridges");
+    }
+
+    @Override
+    public void createTunnel(IpAddress srcIp, IpAddress dstIp) {
+        String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
+        if (bridgeUuid == null) {
+            log.warn("Could not find bridge {} and Could not create tunnel. ",
+                     OvsdbConstant.INTEGRATION_BRIDGE);
+            return;
+        }
+
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
+        String portUuid = getPortUuid(portName, bridgeUuid);
+
+        Port port = (Port) TableGenerator
+                .createTable(dbSchema, OvsdbTable.PORT);
+        if (port != null) {
+            port.setName(portName);
+        }
+
+        if (portUuid == null) {
+            portUuid = insertConfig(OvsdbConstant.PORT, "_uuid", OvsdbConstant.BRIDGE,
+                      "ports", bridgeUuid, port.getRow());
+        } else {
+            updateConfig(OvsdbConstant.PORT, "_uuid", portUuid, port.getRow());
+        }
+
+        // When a tunnel is created, A row is inserted into port table and
+        // interface table of the ovsdb node.
+        // and the following step is to get the interface uuid from local store
+        // in controller node.
+        // but it need spend some time synchronising data between node and
+        // controller.
+        // so loop to judge if interfaceUUid is null is necessary.
+        String interfaceUuid = null;
+        for (int i = 0; i < 10; i++) {
+            interfaceUuid = getInterfaceUuid(portUuid, portName);
+            if (interfaceUuid == null) {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    log.warn("Interrupted while waiting to get interfaceUuid");
+                    Thread.currentThread().interrupt();
+                }
+            } else {
+                break;
+            }
+        }
+
+        if (interfaceUuid != null) {
+
+            Interface tunInterface = (Interface) TableGenerator
+                    .createTable(dbSchema, OvsdbTable.INTERFACE);
+
+            if (tunInterface != null) {
+
+                tunInterface.setType(OvsdbConstant.TYPEVXLAN);
+                Map<String, String> options = Maps.newHashMap();
+                options.put("key", "flow");
+                options.put("local_ip", srcIp.toString());
+                options.put("remote_ip", dstIp.toString());
+                tunInterface.setOptions(options);
+                updateConfig(OvsdbConstant.INTERFACE, "_uuid", interfaceUuid,
+                          tunInterface.getRow());
+                log.info("Tunnel added success", tunInterface);
+
+            }
+        }
+
+        return;
+    }
+
+    @Override
+    public void dropTunnel(IpAddress srcIp, IpAddress dstIp) {
+        String bridgeName = OvsdbConstant.INTEGRATION_BRIDGE;
+        String portName = getTunnelName(OvsdbConstant.TYPEVXLAN, dstIp);
+        String bridgeUuid = getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
+        if (bridgeUuid == null) {
+            log.warn("Could not find bridge {} in {}", bridgeName,
+                     nodeId.getIpAddress());
+            return;
+        }
+
+        String portUUID = getPortUuid(portName, bridgeUuid);
+        if (portUUID != null) {
+            log.info("Delete tunnel");
+            deleteConfig(OvsdbConstant.PORT, "_uuid", portUUID,
+                      OvsdbConstant.BRIDGE, "ports");
+        }
+
+        return;
+    }
+
+    /**
+     * Delete transact config.
+     *
+     * @param childTableName child table name
+     * @param childColumnName child column name
+     * @param childUuid child row uuid
+     * @param parentTableName parent table name
+     * @param parentColumnName parent column
+     *
+     */
+    private void deleteConfig(String childTableName, String childColumnName,
+                           String childUuid, String parentTableName,
+                           String parentColumnName) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        TableSchema childTableSchema = dbSchema.getTableSchema(childTableName);
+
+        ArrayList<Operation> operations = Lists.newArrayList();
+        if (parentTableName != null && parentColumnName != null) {
+            TableSchema parentTableSchema = dbSchema
+                    .getTableSchema(parentTableName);
+            ColumnSchema parentColumnSchema = parentTableSchema
+                    .getColumnSchema(parentColumnName);
+            List<Mutation> mutations = Lists.newArrayList();
+            Mutation mutation = MutationUtil.delete(parentColumnSchema.name(),
+                                                    UUID.uuid(childUuid));
+            mutations.add(mutation);
+            List<Condition> conditions = Lists.newArrayList();
+            Condition condition = ConditionUtil.includes(parentColumnName,
+                                                         UUID.uuid(childUuid));
+            conditions.add(condition);
+            Mutate op = new Mutate(parentTableSchema, conditions, mutations);
+            operations.add(op);
+        }
+
+        List<Condition> conditions = Lists.newArrayList();
+        Condition condition = ConditionUtil.equals(childColumnName, UUID.uuid(childUuid));
+        conditions.add(condition);
+        Delete del = new Delete(childTableSchema, conditions);
+        operations.add(del);
+        transactConfig(OvsdbConstant.DATABASENAME, operations);
+
+        return;
+    }
+
+    /**
+     * Update transact config.
+     *
+     * @param tableName table name
+     * @param columnName column name
+     * @param uuid uuid
+     * @param row the config data
+     *
+     */
+    private void updateConfig(String tableName, String columnName, String uuid,
+                           Row row) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        TableSchema tableSchema = dbSchema.getTableSchema(tableName);
+
+        List<Condition> conditions = Lists.newArrayList();
+        Condition condition = ConditionUtil.equals(columnName, UUID.uuid(uuid));
+        conditions.add(condition);
+
+        Update update = new Update(tableSchema, row, conditions);
+
+        ArrayList<Operation> operations = Lists.newArrayList();
+        operations.add(update);
+
+        transactConfig(OvsdbConstant.DATABASENAME, operations);
+    }
+
+    /**
+     * Insert transact config.
+     *
+     * @param childTableName child table name
+     * @param childColumnName child column name
+     * @param parentTableName parent table name
+     * @param parentColumnName parent column
+     * @param parentUuid parent uuid
+     * @param row the config data
+     *
+     * @return uuid, empty if no uuid is find
+     */
+    private String insertConfig(String childTableName, String childColumnName,
+                             String parentTableName, String parentColumnName,
+                             String parentUuid, Row row) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+        TableSchema tableSchema = dbSchema.getTableSchema(childTableName);
+
+        String namedUuid = childTableName;
+        Insert insert = new Insert(tableSchema, namedUuid, row);
+
+        ArrayList<Operation> operations = Lists.newArrayList();
+        operations.add(insert);
+
+        if (parentTableName != null && parentColumnName != null) {
+            TableSchema parentTableSchema = dbSchema
+                    .getTableSchema(parentTableName);
+            ColumnSchema parentColumnSchema = parentTableSchema
+                    .getColumnSchema(parentColumnName);
+
+            List<Mutation> mutations = Lists.newArrayList();
+            Mutation mutation = MutationUtil.insert(parentColumnSchema.name(),
+                                                    UUID.uuid(namedUuid));
+            mutations.add(mutation);
+
+            List<Condition> conditions = Lists.newArrayList();
+            Condition condition = ConditionUtil.equals("_uuid",
+                                                       UUID.uuid(parentUuid));
+            conditions.add(condition);
+
+            Mutate op = new Mutate(parentTableSchema, conditions, mutations);
+            operations.add(op);
+        }
+        if (childTableName.equalsIgnoreCase(OvsdbConstant.PORT)) {
+            log.info("Handle port insert");
+            Insert intfInsert = handlePortInsertTable(OvsdbConstant.INTERFACE,
+                                                    row);
+
+            if (intfInsert != null) {
+                operations.add(intfInsert);
+            }
+
+            Insert ins = (Insert) operations.get(0);
+            ins.getRow().put("interfaces",
+                             UUID.uuid(OvsdbConstant.INTERFACE));
+        }
+
+        List<OperationResult> results;
+        try {
+            results = transactConfig(OvsdbConstant.DATABASENAME, operations)
+                    .get();
+
+            return results.get(0).getUuid().value();
+        } catch (InterruptedException e) {
+            log.warn("Interrupted while waiting to get result");
+            Thread.currentThread().interrupt();
+        } catch (ExecutionException e) {
+            log.error("Exception thrown while to get result");
+        }
+
+        return null;
+    }
+
+    /**
+     * Handles port insert.
+     *
+     * @param tableName ovsdb table interface
+     * @param portRow row of port
+     *
+     * @return insert, empty if null
+     */
+    private Insert handlePortInsertTable(String tableName, Row portRow) {
+        DatabaseSchema dbSchema = schema.get(OvsdbConstant.DATABASENAME);
+
+        TableSchema portTableSchema = dbSchema
+                .getTableSchema(OvsdbConstant.PORT);
+        ColumnSchema portColumnSchema = portTableSchema.getColumnSchema("name");
+
+        String portName = (String) portRow.getColumn(portColumnSchema.name()).data();
+
+        Interface inf = (Interface) TableGenerator
+                .createTable(dbSchema, OvsdbTable.INTERFACE);
+
+        inf.setName(portName);
+
+        TableSchema intfTableSchema = dbSchema
+                .getTableSchema(OvsdbConstant.INTERFACE);
+        Insert insert = new Insert(intfTableSchema, OvsdbConstant.INTERFACE,
+                                   inf.getRow());
+        return insert;
+    }
+
+    /**
+     * Gets tunnel name.
+     *
+     * @param tunnelType
+     * @param dstIp the remote ip address
+     *
+     * @return tunnel name
+     */
+    private String getTunnelName(String tunnelType, IpAddress dstIp) {
+        return tunnelType + "-" + dstIp.toString();
+    }
+
+    @Override
+    public ListenableFuture<DatabaseSchema> getOvsdbSchema(String dbName) {
+        if (dbName == null) {
+            return null;
+        }
+        DatabaseSchema databaseSchema = schema.get(dbName);
+        if (databaseSchema == null) {
+            List<String> dbNames = new ArrayList<String>();
+            dbNames.add(dbName);
+            Function<JsonNode, DatabaseSchema> rowFunction = new Function<JsonNode, DatabaseSchema>() {
+                @Override
+                public DatabaseSchema apply(JsonNode input) {
+                    log.info("Get ovsdb database schema", dbName);
+                    DatabaseSchema dbSchema = FromJsonUtil
+                            .jsonNodeToDbSchema(dbName, input);
+                    if (dbSchema == null) {
+                        log.debug("Get ovsdb database schema error");
+                        return null;
+                    }
+                    schema.put(dbName, dbSchema);
+
+                    return dbSchema;
+                }
+            };
+
+            ListenableFuture<JsonNode> input = getSchema(dbNames);
+            if (input != null) {
+                return Futures.transform(input, rowFunction);
+            }
+            return null;
+        } else {
+            return Futures.immediateFuture(databaseSchema);
+        }
+    }
+
+    @Override
+    public ListenableFuture<TableUpdates> monitorTables(String dbName, String id) {
+        if (dbName == null) {
+            return null;
+        }
+        DatabaseSchema dbSchema = schema.get(dbName);
+        if (dbSchema != null) {
+            Function<JsonNode, TableUpdates> rowFunction = new Function<JsonNode, TableUpdates>() {
+                @Override
+                public TableUpdates apply(JsonNode input) {
+                    log.info("Get table updates");
+                    TableUpdates updates = FromJsonUtil
+                            .jsonNodeToTableUpdates(input, dbSchema);
+                    if (updates == null) {
+                        log.debug("Get table updates error");
+                        return null;
+                    }
+                    return updates;
+                }
+            };
+            return Futures.transform(monitor(dbSchema, id), rowFunction);
+        }
+        return null;
+    }
+
+    @Override
+    public ListenableFuture<List<OperationResult>> transactConfig(String dbName,
+                                                                  List<Operation> operations) {
+        if (dbName == null) {
+            return null;
+        }
+        DatabaseSchema dbSchema = schema.get(dbName);
+        if (dbSchema != null) {
+            Function<List<JsonNode>, List<OperationResult>> rowFunction =
+                    new Function<List<JsonNode>, List<OperationResult>>() {
+                @Override
+                public List<OperationResult> apply(List<JsonNode> input) {
+                    log.info("Get ovsdb operation result");
+                    List<OperationResult> result = FromJsonUtil
+                            .jsonNodeToOperationResult(input, operations);
+
+                    if (result == null) {
+                        log.debug("The operation result is null");
+                        return null;
+                    }
+                    return result;
+                }
+            };
+            return Futures.transform(transact(dbSchema, operations),
+                                     rowFunction);
+        }
+        return null;
+    }
+
+    @Override
+    public ListenableFuture<JsonNode> getSchema(List<String> dbnames) {
+        String id = java.util.UUID.randomUUID().toString();
+        String getSchemaString = JsonRpcWriterUtil.getSchemaStr(id, dbnames);
+
+        SettableFuture<JsonNode> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "getSchema");
+
+        channel.writeAndFlush(getSchemaString);
+        return sf;
+
+    }
+
+    @Override
+    public ListenableFuture<List<String>> echo() {
+        String id = java.util.UUID.randomUUID().toString();
+        String echoString = JsonRpcWriterUtil.echoStr(id);
+
+        SettableFuture<List<String>> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "echo");
+
+        channel.writeAndFlush(echoString);
+        return sf;
+
+    }
+
+    @Override
+    public ListenableFuture<JsonNode> monitor(DatabaseSchema dbSchema,
+                                              String monitorId) {
+        String id = java.util.UUID.randomUUID().toString();
+        String monitorString = JsonRpcWriterUtil.monitorStr(id, monitorId,
+                                                            dbSchema);
+
+        SettableFuture<JsonNode> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "monitor");
+
+        channel.writeAndFlush(monitorString);
+        return sf;
+
+    }
+
+    @Override
+    public ListenableFuture<List<String>> listDbs() {
+        String id = java.util.UUID.randomUUID().toString();
+        String listDbsString = JsonRpcWriterUtil.listDbsStr(id);
+
+        SettableFuture<List<String>> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "listDbs");
+
+        channel.writeAndFlush(listDbsString);
+        return sf;
+
+    }
+
+    @Override
+    public ListenableFuture<List<JsonNode>> transact(DatabaseSchema dbSchema,
+                                                     List<Operation> operations) {
+        String id = java.util.UUID.randomUUID().toString();
+        String transactString = JsonRpcWriterUtil.transactStr(id, dbSchema,
+                                                              operations);
+
+        SettableFuture<List<JsonNode>> sf = SettableFuture.create();
+        requestResult.put(id, sf);
+        requestMethod.put(id, "transact");
+
+        channel.writeAndFlush(transactString);
+        return sf;
+
+    }
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Override
+    public void processResult(JsonNode response) {
+        log.debug("Handle result");
+        String requestId = response.get("id").asText();
+        SettableFuture sf = requestResult.get(requestId);
+        if (sf == null) {
+            log.debug("No such future to process");
+            return;
+        }
+        String methodName = requestMethod.get(requestId);
+
+        Object result;
+        result = FromJsonUtil.jsonResultParser(response, methodName);
+
+        sf.set(result);
+        return;
+    }
+
+    @Override
+    public void processRequest(JsonNode requestJson) {
+        log.debug("Handle request");
+        if (requestJson.get("method").asText().equalsIgnoreCase("echo")) {
+            log.debug("handle echo request");
+
+            String replyString = FromJsonUtil.getEchoRequestStr(requestJson);
+            channel.writeAndFlush(replyString);
+
+            return;
+        } else {
+            FromJsonUtil
+                    .jsonCallbackRequestParser(requestJson, monitorCallBack);
+            return;
+        }
+    }
+
+    @Override
+    public void setCallback(Callback monitorCallback) {
+        this.monitorCallBack = monitorCallback;
+    }
+
+    @Override
+    public Set<OvsdbTunnel> getTunnels() {
+        return ovsdbTunnels;
+    }
+
+    @Override
+    public Set<OvsdbBridge> getBridges() {
+        Set<OvsdbBridge> ovsdbBridges = new HashSet<OvsdbBridge>();
+        OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
+        if (tableStore == null) {
+            return null;
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.BRIDGE);
+        if (rowStore == null) {
+            return null;
+        }
+        ConcurrentMap<String, Row> rows = rowStore.getRowStore();
+        for (String uuid : rows.keySet()) {
+            Row row = getRow(OvsdbConstant.DATABASENAME, OvsdbConstant.BRIDGE,
+                             uuid);
+            OvsdbBridge ovsdbBridge = getOvsdbBridge(row);
+            if (ovsdbBridge != null) {
+                ovsdbBridges.add(ovsdbBridge);
+            }
+        }
+        return ovsdbBridges;
+    }
+
+    @Override
+    public Set<OvsdbPort> getPorts() {
+        Set<OvsdbPort> ovsdbPorts = new HashSet<OvsdbPort>();
+        OvsdbTableStore tableStore = getTableStore(OvsdbConstant.DATABASENAME);
+        if (tableStore == null) {
+            return null;
+        }
+        OvsdbRowStore rowStore = tableStore.getRows(OvsdbConstant.INTERFACE);
+        if (rowStore == null) {
+            return null;
+        }
+        ConcurrentMap<String, Row> rows = rowStore.getRowStore();
+        for (String uuid : rows.keySet()) {
+            Row row = getRow(OvsdbConstant.DATABASENAME,
+                             OvsdbConstant.INTERFACE, uuid);
+            OvsdbPort ovsdbPort = getOvsdbPort(row);
+            if (ovsdbPort != null) {
+                ovsdbPorts.add(ovsdbPort);
+            }
+        }
+        return ovsdbPorts;
+    }
+
+    @Override
+    public DatabaseSchema getDatabaseSchema(String dbName) {
+        return schema.get(dbName);
+    }
+
+    //Gets ovsdb port.
+    private OvsdbPort getOvsdbPort(Row row) {
+        DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
+        Interface intf = (Interface) TableGenerator
+                .getTable(dbSchema, row, OvsdbTable.INTERFACE);
+        if (intf == null) {
+            return null;
+        }
+        long ofPort = getOfPort(intf);
+        String portName = intf.getName();
+        if ((ofPort < 0) || (portName == null)) {
+            return null;
+        }
+
+        OvsdbPort ovsdbPort = new OvsdbPort(new OvsdbPortNumber(ofPort),
+                                            new OvsdbPortName(portName));
+        return ovsdbPort;
+    }
+
+    ////Gets ovsdb bridge.
+    private OvsdbBridge getOvsdbBridge(Row row) {
+        DatabaseSchema dbSchema = getDatabaseSchema(OvsdbConstant.DATABASENAME);
+        Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, row,
+                                                         OvsdbTable.BRIDGE);
+        if (bridge == null) {
+            return null;
+        }
+
+        OvsdbSet datapathIdSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
+        @SuppressWarnings("unchecked")
+        Set<String> datapathIds = datapathIdSet.set();
+        if (datapathIds == null || datapathIds.size() == 0) {
+            return null;
+        }
+        String datapathId = (String) datapathIds.toArray()[0];
+        String bridgeName = bridge.getName();
+        if ((datapathId == null) || (bridgeName == null)) {
+            return null;
+        }
+
+        OvsdbBridge ovsdbBridge = new OvsdbBridge(new OvsdbBridgeName(bridgeName),
+                                                  new OvsdbDatapathId(datapathId));
+        return ovsdbBridge;
+    }
+
+    //Gets ofPort in the interface.
+    private long getOfPort(Interface intf) {
+        OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
+        @SuppressWarnings("unchecked")
+        Set<Integer> ofPorts = ofPortSet.set();
+        while (ofPorts == null || ofPorts.size() <= 0) {
+            log.debug("The ofport is null in {}", intf.getName());
+            return -1;
+        }
+        // return (long) ofPorts.toArray()[0];
+        Iterator<Integer> it = ofPorts.iterator();
+        return Long.parseLong(it.next().toString());
+    }
+}
diff --git a/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java b/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
index f80a89e..07100a9 100644
--- a/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
+++ b/ovsdb/ctl/src/main/java/org/onosproject/ovsdb/controller/impl/OvsdbControllerImpl.java
@@ -1,413 +1,413 @@
-/*
- * 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.controller.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.math.BigInteger;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.ExecutionException;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onosproject.ovsdb.controller.DefaultEventSubject;
-import org.onosproject.ovsdb.controller.EventSubject;
-import org.onosproject.ovsdb.controller.OvsdbClientService;
-import org.onosproject.ovsdb.controller.OvsdbConstant;
-import org.onosproject.ovsdb.controller.OvsdbController;
-import org.onosproject.ovsdb.controller.OvsdbDatapathId;
-import org.onosproject.ovsdb.controller.OvsdbEvent;
-import org.onosproject.ovsdb.controller.OvsdbEvent.Type;
-import org.onosproject.ovsdb.controller.OvsdbEventListener;
-import org.onosproject.ovsdb.controller.OvsdbIfaceId;
-import org.onosproject.ovsdb.controller.OvsdbNodeId;
-import org.onosproject.ovsdb.controller.OvsdbNodeListener;
-import org.onosproject.ovsdb.controller.OvsdbPortName;
-import org.onosproject.ovsdb.controller.OvsdbPortNumber;
-import org.onosproject.ovsdb.controller.OvsdbPortType;
-import org.onosproject.ovsdb.controller.driver.OvsdbAgent;
-import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
-import org.onosproject.ovsdb.rfc.message.TableUpdate;
-import org.onosproject.ovsdb.rfc.message.TableUpdates;
-import org.onosproject.ovsdb.rfc.message.UpdateNotification;
-import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
-import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
-import org.onosproject.ovsdb.rfc.notation.Row;
-import org.onosproject.ovsdb.rfc.notation.UUID;
-import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
-import org.onosproject.ovsdb.rfc.table.Bridge;
-import org.onosproject.ovsdb.rfc.table.Interface;
-import org.onosproject.ovsdb.rfc.table.OvsdbTable;
-import org.onosproject.ovsdb.rfc.table.TableGenerator;
-import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-/**
- * The implementation of OvsdbController.
- */
-@Component(immediate = true)
-@Service
-public class OvsdbControllerImpl implements OvsdbController {
-
-    public static final Logger log = LoggerFactory
-            .getLogger(OvsdbControllerImpl.class);
-
-    protected ConcurrentHashMap<OvsdbNodeId, OvsdbClientService> ovsdbClients =
-            new ConcurrentHashMap<OvsdbNodeId, OvsdbClientService>();
-
-    protected OvsdbAgent agent = new InternalOvsdbNodeAgent();
-    protected InternalMonitorCallBack updateCallback = new InternalMonitorCallBack();
-
-    protected Set<OvsdbNodeListener> ovsdbNodeListener = new CopyOnWriteArraySet<>();
-    protected Set<OvsdbEventListener> ovsdbEventListener = new CopyOnWriteArraySet<>();
-
-    protected ConcurrentHashMap<String, OvsdbClientService> requestNotification =
-            new ConcurrentHashMap<String, OvsdbClientService>();
-
-    protected ConcurrentHashMap<String, String> requestDbName = new ConcurrentHashMap<String, String>();
-
-    private final Controller controller = new Controller();
-
-    @Activate
-    public void activate(ComponentContext context) {
-        controller.start(agent, updateCallback);
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        controller.stop();
-        log.info("Stoped");
-    }
-
-    @Override
-    public void addNodeListener(OvsdbNodeListener listener) {
-        if (!ovsdbNodeListener.contains(listener)) {
-            this.ovsdbNodeListener.add(listener);
-        }
-    }
-
-    @Override
-    public void removeNodeListener(OvsdbNodeListener listener) {
-        this.ovsdbNodeListener.remove(listener);
-    }
-
-    @Override
-    public void addOvsdbEventListener(OvsdbEventListener listener) {
-        if (!ovsdbEventListener.contains(listener)) {
-            this.ovsdbEventListener.add(listener);
-        }
-    }
-
-    @Override
-    public void removeOvsdbEventListener(OvsdbEventListener listener) {
-        this.ovsdbEventListener.remove(listener);
-    }
-
-    @Override
-    public List<OvsdbNodeId> getNodeIds() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public OvsdbClientService getOvsdbClient(OvsdbNodeId nodeId) {
-        return ovsdbClients.get(nodeId);
-    }
-
-    /**
-     * Implementation of an Ovsdb Agent which is responsible for keeping track
-     * of connected node and the state in which they are.
-     */
-    private class InternalOvsdbNodeAgent implements OvsdbAgent {
-        @Override
-        public void addConnectedNode(OvsdbNodeId nodeId,
-                                     OvsdbClientService ovsdbClient) {
-
-            if (ovsdbClients.get(nodeId) != null) {
-                return;
-            } else {
-                ovsdbClients.put(nodeId, ovsdbClient);
-
-                try {
-                    List<String> dbNames = ovsdbClient.listDbs().get();
-                    for (String dbName : dbNames) {
-                        DatabaseSchema dbSchema;
-                        dbSchema = ovsdbClient.getOvsdbSchema(dbName).get();
-
-                        log.debug("Begin to monitor tables");
-                        String id = java.util.UUID.randomUUID().toString();
-                        TableUpdates updates = ovsdbClient
-                                .monitorTables(dbName, id).get();
-
-                        requestDbName.put(id, dbName);
-                        requestNotification.put(id, ovsdbClient);
-
-                        if (updates != null) {
-                            processTableUpdates(ovsdbClient, updates,
-                                                dbSchema.name());
-                        }
-                    }
-                } catch (InterruptedException e) {
-                    log.warn("Interrupted while waiting to get message from ovsdb");
-                    Thread.currentThread().interrupt();
-                } catch (ExecutionException e) {
-                    log.error("Exception thrown while to get message from ovsdb");
-                }
-
-                log.debug("Add node to north");
-                for (OvsdbNodeListener l : ovsdbNodeListener) {
-                    l.nodeAdded(nodeId);
-                }
-                return;
-            }
-        }
-
-        @Override
-        public void removeConnectedNode(OvsdbNodeId nodeId) {
-            ovsdbClients.remove(nodeId);
-            log.debug("Node connection is removed");
-            for (OvsdbNodeListener l : ovsdbNodeListener) {
-                l.nodeRemoved(nodeId);
-            }
-        }
-    }
-
-    /**
-     * Processes table updates.
-     *
-     * @param clientService OvsdbClientService instance
-     * @param updates TableUpdates instance
-     * @param dbName ovsdb database name
-     */
-    private void processTableUpdates(OvsdbClientService clientService,
-                                     TableUpdates updates, String dbName)
-            throws InterruptedException {
-        checkNotNull(clientService, "OvsdbClientService is not null");
-
-        DatabaseSchema dbSchema = clientService.getDatabaseSchema(dbName);
-
-        for (String tableName : updates.result().keySet()) {
-            TableUpdate update = updates.result().get(tableName);
-            for (UUID uuid : (Set<UUID>) update.rows().keySet()) {
-                log.debug("Begin to process table updates uuid: {}, databaseName: {}, tableName: {}",
-                          uuid.value(), dbName, tableName);
-
-                Row oldRow = update.getOld(uuid);
-                Row newRow = update.getNew(uuid);
-                if (newRow != null) {
-                    clientService.updateOvsdbStore(dbName, tableName,
-                                                   uuid.value(), newRow);
-
-                    if (OvsdbConstant.INTERFACE.equals(tableName)) {
-                        dispatchInterfaceEvent(clientService,
-                                               newRow, null,
-                                               OvsdbEvent.Type.PORT_ADDED,
-                                               dbSchema);
-                    }
-                } else if (update.getOld(uuid) != null) {
-                    clientService.removeRow(dbName, tableName, uuid.value());
-                    if (OvsdbConstant.PORT.equals(tableName)) {
-                        dispatchInterfaceEvent(clientService, null,
-                                               oldRow,
-                                          OvsdbEvent.Type.PORT_REMOVED,
-                                          dbSchema);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Dispatches event to the north.
-     *
-     * @param clientService OvsdbClientService instance
-     * @param newRow a new row
-     * @param oldRow an old row
-     * @param eventType type of event
-     * @param dbSchema ovsdb database schema
-     */
-    private void dispatchInterfaceEvent(OvsdbClientService clientService,
-                                        Row newRow, Row oldRow,
-                                        Type eventType,
-                                        DatabaseSchema dbSchema) {
-
-        long dpid = getDataPathid(clientService, dbSchema);
-        Interface intf = (Interface) TableGenerator
-                .getTable(dbSchema, newRow, OvsdbTable.INTERFACE);
-        if (intf == null) {
-            return;
-        }
-
-        String portType = (String) intf.getTypeColumn().data();
-        long localPort = getOfPort(intf);
-        if (localPort < 0) {
-            return;
-        }
-        String[] macAndIfaceId = getMacAndIfaceid(intf);
-        if (macAndIfaceId == null) {
-            return;
-        }
-
-        EventSubject eventSubject = new DefaultEventSubject(MacAddress.valueOf(
-                                                                               macAndIfaceId[0]),
-                                                            new HashSet<IpAddress>(),
-                                                            new OvsdbPortName(intf
-                                                                    .getName()),
-                                                            new OvsdbPortNumber(localPort),
-                                                            new OvsdbDatapathId(Long
-                                                                    .toString(dpid)),
-                                                            new OvsdbPortType(portType),
-                                                            new OvsdbIfaceId(macAndIfaceId[1]));
-        for (OvsdbEventListener listener : ovsdbEventListener) {
-            listener.handle(new OvsdbEvent<EventSubject>(eventType,
-                                                         eventSubject));
-        }
-    }
-
-    /**
-     * Gets mac and iface from the table Interface.
-     *
-     * @param intf Interface instance
-     * @return attachedMac, ifaceid
-     */
-    private String[] getMacAndIfaceid(Interface intf) {
-        OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
-        @SuppressWarnings("unchecked")
-        Map<String, String> externalIds = ovsdbMap.map();
-        if (externalIds == null) {
-            log.warn("The external_ids is null");
-            return null;
-        }
-
-        String attachedMac = externalIds.get(OvsdbConstant.EXTERNAL_ID_VM_MAC);
-        if (attachedMac == null) {
-            log.warn("The attachedMac is null");
-            return null;
-        }
-        String ifaceid = externalIds
-                .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
-        if (ifaceid == null) {
-            log.warn("The ifaceid is null");
-            return null;
-        }
-        return new String[] {attachedMac, ifaceid};
-    }
-
-    /**
-     * Gets ofPorts number from table Interface.
-     *
-     * @param intf Interface instance
-     * @return ofport the ofport number
-     */
-    private long getOfPort(Interface intf) {
-        OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
-        @SuppressWarnings("unchecked")
-        Set<Integer> ofPorts = ofPortSet.set();
-        while (ofPorts == null || ofPorts.size() <= 0) {
-            log.debug("The ofport is null in {}", intf.getName());
-            return -1;
-        }
-        Iterator<Integer> it = ofPorts.iterator();
-        return Long.parseLong(it.next().toString());
-    }
-
-    /**
-     * Gets datapathid from table bridge.
-     *
-     * @param clientService OvsdbClientService instance
-     * @param dbSchema ovsdb database schema
-     * @return datapathid the bridge datapathid
-     */
-    private long getDataPathid(OvsdbClientService clientService,
-                               DatabaseSchema dbSchema) {
-        String bridgeUuid = clientService
-                .getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
-        if (bridgeUuid == null) {
-            log.debug("Unable to spot bridge uuid for {} in {}",
-                      OvsdbConstant.INTEGRATION_BRIDGE, clientService);
-            return 0;
-        }
-
-        Row bridgeRow = clientService.getRow(OvsdbConstant.DATABASENAME,
-                                             "Bridge", bridgeUuid);
-        Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
-                                                         OvsdbTable.BRIDGE);
-        OvsdbSet dpidSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
-        @SuppressWarnings("unchecked")
-        Set<String> dpids = dpidSet.set();
-        if (dpids == null || dpids.size() == 0) {
-            return 0;
-        }
-        return stringToLong((String) dpids.toArray()[0]);
-    }
-
-    private long stringToLong(String values) {
-        long value = (new BigInteger(values.replaceAll(":", ""), 16))
-                .longValue();
-        return value;
-    }
-
-    /**
-     * Implementation of an Callback which is responsible for receiving request
-     * infomation from ovsdb.
-     */
-    private class InternalMonitorCallBack implements Callback {
-        @Override
-        public void update(UpdateNotification updateNotification) {
-            Object key = updateNotification.jsonValue();
-            OvsdbClientService ovsdbClient = requestNotification.get(key);
-
-            String dbName = requestDbName.get(key);
-            JsonNode updatesJson = updateNotification.tbUpdatesJsonNode();
-            DatabaseSchema dbSchema = ovsdbClient.getDatabaseSchema(dbName);
-            TableUpdates updates = FromJsonUtil
-                    .jsonNodeToTableUpdates(updatesJson, dbSchema);
-            try {
-                processTableUpdates(ovsdbClient, updates, dbName);
-            } catch (InterruptedException e) {
-                log.warn("Interrupted while processing table updates");
-                Thread.currentThread().interrupt();
-            }
-        }
-
-        @Override
-        public void locked(List<String> ids) {
-            // TODO Auto-generated method stub
-        }
-
-        @Override
-        public void stolen(List<String> ids) {
-            // TODO Auto-generated method stub
-        }
-
-    }
-
-}
+/*
+ * 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.controller.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ExecutionException;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onosproject.ovsdb.controller.DefaultEventSubject;
+import org.onosproject.ovsdb.controller.EventSubject;
+import org.onosproject.ovsdb.controller.OvsdbClientService;
+import org.onosproject.ovsdb.controller.OvsdbConstant;
+import org.onosproject.ovsdb.controller.OvsdbController;
+import org.onosproject.ovsdb.controller.OvsdbDatapathId;
+import org.onosproject.ovsdb.controller.OvsdbEvent;
+import org.onosproject.ovsdb.controller.OvsdbEvent.Type;
+import org.onosproject.ovsdb.controller.OvsdbEventListener;
+import org.onosproject.ovsdb.controller.OvsdbIfaceId;
+import org.onosproject.ovsdb.controller.OvsdbNodeId;
+import org.onosproject.ovsdb.controller.OvsdbNodeListener;
+import org.onosproject.ovsdb.controller.OvsdbPortName;
+import org.onosproject.ovsdb.controller.OvsdbPortNumber;
+import org.onosproject.ovsdb.controller.OvsdbPortType;
+import org.onosproject.ovsdb.controller.driver.OvsdbAgent;
+import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
+import org.onosproject.ovsdb.rfc.message.TableUpdate;
+import org.onosproject.ovsdb.rfc.message.TableUpdates;
+import org.onosproject.ovsdb.rfc.message.UpdateNotification;
+import org.onosproject.ovsdb.rfc.notation.OvsdbMap;
+import org.onosproject.ovsdb.rfc.notation.OvsdbSet;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.table.Bridge;
+import org.onosproject.ovsdb.rfc.table.Interface;
+import org.onosproject.ovsdb.rfc.table.OvsdbTable;
+import org.onosproject.ovsdb.rfc.table.TableGenerator;
+import org.onosproject.ovsdb.rfc.utils.FromJsonUtil;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * The implementation of OvsdbController.
+ */
+@Component(immediate = true)
+@Service
+public class OvsdbControllerImpl implements OvsdbController {
+
+    public static final Logger log = LoggerFactory
+            .getLogger(OvsdbControllerImpl.class);
+
+    protected ConcurrentHashMap<OvsdbNodeId, OvsdbClientService> ovsdbClients =
+            new ConcurrentHashMap<OvsdbNodeId, OvsdbClientService>();
+
+    protected OvsdbAgent agent = new InternalOvsdbNodeAgent();
+    protected InternalMonitorCallBack updateCallback = new InternalMonitorCallBack();
+
+    protected Set<OvsdbNodeListener> ovsdbNodeListener = new CopyOnWriteArraySet<>();
+    protected Set<OvsdbEventListener> ovsdbEventListener = new CopyOnWriteArraySet<>();
+
+    protected ConcurrentHashMap<String, OvsdbClientService> requestNotification =
+            new ConcurrentHashMap<String, OvsdbClientService>();
+
+    protected ConcurrentHashMap<String, String> requestDbName = new ConcurrentHashMap<String, String>();
+
+    private final Controller controller = new Controller();
+
+    @Activate
+    public void activate(ComponentContext context) {
+        controller.start(agent, updateCallback);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        controller.stop();
+        log.info("Stoped");
+    }
+
+    @Override
+    public void addNodeListener(OvsdbNodeListener listener) {
+        if (!ovsdbNodeListener.contains(listener)) {
+            this.ovsdbNodeListener.add(listener);
+        }
+    }
+
+    @Override
+    public void removeNodeListener(OvsdbNodeListener listener) {
+        this.ovsdbNodeListener.remove(listener);
+    }
+
+    @Override
+    public void addOvsdbEventListener(OvsdbEventListener listener) {
+        if (!ovsdbEventListener.contains(listener)) {
+            this.ovsdbEventListener.add(listener);
+        }
+    }
+
+    @Override
+    public void removeOvsdbEventListener(OvsdbEventListener listener) {
+        this.ovsdbEventListener.remove(listener);
+    }
+
+    @Override
+    public List<OvsdbNodeId> getNodeIds() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public OvsdbClientService getOvsdbClient(OvsdbNodeId nodeId) {
+        return ovsdbClients.get(nodeId);
+    }
+
+    /**
+     * Implementation of an Ovsdb Agent which is responsible for keeping track
+     * of connected node and the state in which they are.
+     */
+    private class InternalOvsdbNodeAgent implements OvsdbAgent {
+        @Override
+        public void addConnectedNode(OvsdbNodeId nodeId,
+                                     OvsdbClientService ovsdbClient) {
+
+            if (ovsdbClients.get(nodeId) != null) {
+                return;
+            } else {
+                ovsdbClients.put(nodeId, ovsdbClient);
+
+                try {
+                    List<String> dbNames = ovsdbClient.listDbs().get();
+                    for (String dbName : dbNames) {
+                        DatabaseSchema dbSchema;
+                        dbSchema = ovsdbClient.getOvsdbSchema(dbName).get();
+
+                        log.debug("Begin to monitor tables");
+                        String id = java.util.UUID.randomUUID().toString();
+                        TableUpdates updates = ovsdbClient
+                                .monitorTables(dbName, id).get();
+
+                        requestDbName.put(id, dbName);
+                        requestNotification.put(id, ovsdbClient);
+
+                        if (updates != null) {
+                            processTableUpdates(ovsdbClient, updates,
+                                                dbSchema.name());
+                        }
+                    }
+                } catch (InterruptedException e) {
+                    log.warn("Interrupted while waiting to get message from ovsdb");
+                    Thread.currentThread().interrupt();
+                } catch (ExecutionException e) {
+                    log.error("Exception thrown while to get message from ovsdb");
+                }
+
+                log.debug("Add node to north");
+                for (OvsdbNodeListener l : ovsdbNodeListener) {
+                    l.nodeAdded(nodeId);
+                }
+                return;
+            }
+        }
+
+        @Override
+        public void removeConnectedNode(OvsdbNodeId nodeId) {
+            ovsdbClients.remove(nodeId);
+            log.debug("Node connection is removed");
+            for (OvsdbNodeListener l : ovsdbNodeListener) {
+                l.nodeRemoved(nodeId);
+            }
+        }
+    }
+
+    /**
+     * Processes table updates.
+     *
+     * @param clientService OvsdbClientService instance
+     * @param updates TableUpdates instance
+     * @param dbName ovsdb database name
+     */
+    private void processTableUpdates(OvsdbClientService clientService,
+                                     TableUpdates updates, String dbName)
+            throws InterruptedException {
+        checkNotNull(clientService, "OvsdbClientService is not null");
+
+        DatabaseSchema dbSchema = clientService.getDatabaseSchema(dbName);
+
+        for (String tableName : updates.result().keySet()) {
+            TableUpdate update = updates.result().get(tableName);
+            for (UUID uuid : (Set<UUID>) update.rows().keySet()) {
+                log.debug("Begin to process table updates uuid: {}, databaseName: {}, tableName: {}",
+                          uuid.value(), dbName, tableName);
+
+                Row oldRow = update.getOld(uuid);
+                Row newRow = update.getNew(uuid);
+                if (newRow != null) {
+                    clientService.updateOvsdbStore(dbName, tableName,
+                                                   uuid.value(), newRow);
+
+                    if (OvsdbConstant.INTERFACE.equals(tableName)) {
+                        dispatchInterfaceEvent(clientService,
+                                               newRow, null,
+                                               OvsdbEvent.Type.PORT_ADDED,
+                                               dbSchema);
+                    }
+                } else if (update.getOld(uuid) != null) {
+                    clientService.removeRow(dbName, tableName, uuid.value());
+                    if (OvsdbConstant.PORT.equals(tableName)) {
+                        dispatchInterfaceEvent(clientService, null,
+                                               oldRow,
+                                          OvsdbEvent.Type.PORT_REMOVED,
+                                          dbSchema);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Dispatches event to the north.
+     *
+     * @param clientService OvsdbClientService instance
+     * @param newRow a new row
+     * @param oldRow an old row
+     * @param eventType type of event
+     * @param dbSchema ovsdb database schema
+     */
+    private void dispatchInterfaceEvent(OvsdbClientService clientService,
+                                        Row newRow, Row oldRow,
+                                        Type eventType,
+                                        DatabaseSchema dbSchema) {
+
+        long dpid = getDataPathid(clientService, dbSchema);
+        Interface intf = (Interface) TableGenerator
+                .getTable(dbSchema, newRow, OvsdbTable.INTERFACE);
+        if (intf == null) {
+            return;
+        }
+
+        String portType = (String) intf.getTypeColumn().data();
+        long localPort = getOfPort(intf);
+        if (localPort < 0) {
+            return;
+        }
+        String[] macAndIfaceId = getMacAndIfaceid(intf);
+        if (macAndIfaceId == null) {
+            return;
+        }
+
+        EventSubject eventSubject = new DefaultEventSubject(MacAddress.valueOf(
+                                                                               macAndIfaceId[0]),
+                                                            new HashSet<IpAddress>(),
+                                                            new OvsdbPortName(intf
+                                                                    .getName()),
+                                                            new OvsdbPortNumber(localPort),
+                                                            new OvsdbDatapathId(Long
+                                                                    .toString(dpid)),
+                                                            new OvsdbPortType(portType),
+                                                            new OvsdbIfaceId(macAndIfaceId[1]));
+        for (OvsdbEventListener listener : ovsdbEventListener) {
+            listener.handle(new OvsdbEvent<EventSubject>(eventType,
+                                                         eventSubject));
+        }
+    }
+
+    /**
+     * Gets mac and iface from the table Interface.
+     *
+     * @param intf Interface instance
+     * @return attachedMac, ifaceid
+     */
+    private String[] getMacAndIfaceid(Interface intf) {
+        OvsdbMap ovsdbMap = (OvsdbMap) intf.getExternalIdsColumn().data();
+        @SuppressWarnings("unchecked")
+        Map<String, String> externalIds = ovsdbMap.map();
+        if (externalIds == null) {
+            log.warn("The external_ids is null");
+            return null;
+        }
+
+        String attachedMac = externalIds.get(OvsdbConstant.EXTERNAL_ID_VM_MAC);
+        if (attachedMac == null) {
+            log.warn("The attachedMac is null");
+            return null;
+        }
+        String ifaceid = externalIds
+                .get(OvsdbConstant.EXTERNAL_ID_INTERFACE_ID);
+        if (ifaceid == null) {
+            log.warn("The ifaceid is null");
+            return null;
+        }
+        return new String[] {attachedMac, ifaceid};
+    }
+
+    /**
+     * Gets ofPorts number from table Interface.
+     *
+     * @param intf Interface instance
+     * @return ofport the ofport number
+     */
+    private long getOfPort(Interface intf) {
+        OvsdbSet ofPortSet = (OvsdbSet) intf.getOpenFlowPortColumn().data();
+        @SuppressWarnings("unchecked")
+        Set<Integer> ofPorts = ofPortSet.set();
+        while (ofPorts == null || ofPorts.size() <= 0) {
+            log.debug("The ofport is null in {}", intf.getName());
+            return -1;
+        }
+        Iterator<Integer> it = ofPorts.iterator();
+        return Long.parseLong(it.next().toString());
+    }
+
+    /**
+     * Gets datapathid from table bridge.
+     *
+     * @param clientService OvsdbClientService instance
+     * @param dbSchema ovsdb database schema
+     * @return datapathid the bridge datapathid
+     */
+    private long getDataPathid(OvsdbClientService clientService,
+                               DatabaseSchema dbSchema) {
+        String bridgeUuid = clientService
+                .getBridgeUuid(OvsdbConstant.INTEGRATION_BRIDGE);
+        if (bridgeUuid == null) {
+            log.debug("Unable to spot bridge uuid for {} in {}",
+                      OvsdbConstant.INTEGRATION_BRIDGE, clientService);
+            return 0;
+        }
+
+        Row bridgeRow = clientService.getRow(OvsdbConstant.DATABASENAME,
+                                             "Bridge", bridgeUuid);
+        Bridge bridge = (Bridge) TableGenerator.getTable(dbSchema, bridgeRow,
+                                                         OvsdbTable.BRIDGE);
+        OvsdbSet dpidSet = (OvsdbSet) bridge.getDatapathIdColumn().data();
+        @SuppressWarnings("unchecked")
+        Set<String> dpids = dpidSet.set();
+        if (dpids == null || dpids.size() == 0) {
+            return 0;
+        }
+        return stringToLong((String) dpids.toArray()[0]);
+    }
+
+    private long stringToLong(String values) {
+        long value = (new BigInteger(values.replaceAll(":", ""), 16))
+                .longValue();
+        return value;
+    }
+
+    /**
+     * Implementation of an Callback which is responsible for receiving request
+     * infomation from ovsdb.
+     */
+    private class InternalMonitorCallBack implements Callback {
+        @Override
+        public void update(UpdateNotification updateNotification) {
+            Object key = updateNotification.jsonValue();
+            OvsdbClientService ovsdbClient = requestNotification.get(key);
+
+            String dbName = requestDbName.get(key);
+            JsonNode updatesJson = updateNotification.tbUpdatesJsonNode();
+            DatabaseSchema dbSchema = ovsdbClient.getDatabaseSchema(dbName);
+            TableUpdates updates = FromJsonUtil
+                    .jsonNodeToTableUpdates(updatesJson, dbSchema);
+            try {
+                processTableUpdates(ovsdbClient, updates, dbName);
+            } catch (InterruptedException e) {
+                log.warn("Interrupted while processing table updates");
+                Thread.currentThread().interrupt();
+            }
+        }
+
+        @Override
+        public void locked(List<String> ids) {
+            // TODO Auto-generated method stub
+        }
+
+        @Override
+        public void stolen(List<String> ids) {
+            // TODO Auto-generated method stub
+        }
+
+    }
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java
index d539ff3..d4f0513 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/message/UpdateNotification.java
@@ -1,90 +1,90 @@
-/*
- * 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.message;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-import org.onosproject.ovsdb.rfc.notation.json.UpdateNotificationConverter;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
-
-/**
- * The "update" notification is sent by the server to the client to report
- * changes in tables that are being monitored following a "monitor" request. The
- * "params" of the result JsonNode.
- */
-@JsonDeserialize(converter = UpdateNotificationConverter.class)
-public final class UpdateNotification {
-    private final Object jsonValue;
-    private final JsonNode tbUpdatesJsonNode;
-
-    /**
-     * Constructs a UpdateNotification object.
-     * @param jsonValue the "json-value" in "params" of the result JsonNode
-     * @param tbUpdatesJsonNode the "table-updates" in "params" of the result JsonNode
-     */
-    public UpdateNotification(Object jsonValue, JsonNode tbUpdatesJsonNode) {
-        checkNotNull(jsonValue, "jsonValue cannot be null");
-        checkNotNull(tbUpdatesJsonNode, "tablebUpdates JsonNode cannot be null");
-        this.jsonValue = jsonValue;
-        this.tbUpdatesJsonNode = tbUpdatesJsonNode;
-    }
-
-    /**
-     * Return context.
-     * @return context
-     */
-    public Object jsonValue() {
-        return jsonValue;
-    }
-
-    /**
-     * Return tbUpdatesJsonNode.
-     * @return tbUpdatesJsonNode
-     */
-    public JsonNode tbUpdatesJsonNode() {
-        return tbUpdatesJsonNode;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(jsonValue, tbUpdatesJsonNode);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof UpdateNotification) {
-            final UpdateNotification other = (UpdateNotification) obj;
-            return Objects.equals(this.jsonValue, other.jsonValue)
-                    && Objects.equals(this.tbUpdatesJsonNode,
-                                      other.tbUpdatesJsonNode);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("jsonValue", jsonValue)
-                .add("tbUpdatesJsonNode", tbUpdatesJsonNode).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.ovsdb.rfc.message;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onosproject.ovsdb.rfc.notation.json.UpdateNotificationConverter;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+
+/**
+ * The "update" notification is sent by the server to the client to report
+ * changes in tables that are being monitored following a "monitor" request. The
+ * "params" of the result JsonNode.
+ */
+@JsonDeserialize(converter = UpdateNotificationConverter.class)
+public final class UpdateNotification {
+    private final Object jsonValue;
+    private final JsonNode tbUpdatesJsonNode;
+
+    /**
+     * Constructs a UpdateNotification object.
+     * @param jsonValue the "json-value" in "params" of the result JsonNode
+     * @param tbUpdatesJsonNode the "table-updates" in "params" of the result JsonNode
+     */
+    public UpdateNotification(Object jsonValue, JsonNode tbUpdatesJsonNode) {
+        checkNotNull(jsonValue, "jsonValue cannot be null");
+        checkNotNull(tbUpdatesJsonNode, "tablebUpdates JsonNode cannot be null");
+        this.jsonValue = jsonValue;
+        this.tbUpdatesJsonNode = tbUpdatesJsonNode;
+    }
+
+    /**
+     * Return context.
+     * @return context
+     */
+    public Object jsonValue() {
+        return jsonValue;
+    }
+
+    /**
+     * Return tbUpdatesJsonNode.
+     * @return tbUpdatesJsonNode
+     */
+    public JsonNode tbUpdatesJsonNode() {
+        return tbUpdatesJsonNode;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(jsonValue, tbUpdatesJsonNode);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof UpdateNotification) {
+            final UpdateNotification other = (UpdateNotification) obj;
+            return Objects.equals(this.jsonValue, other.jsonValue)
+                    && Objects.equals(this.tbUpdatesJsonNode,
+                                      other.tbUpdatesJsonNode);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("jsonValue", jsonValue)
+                .add("tbUpdatesJsonNode", tbUpdatesJsonNode).toString();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java
index 615eaac..60f4944 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Column.java
@@ -1,81 +1,81 @@
-/*
- * 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.notation;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-/**
- * Column is the basic element of the OpenVswitch database.
- */
-public final class Column {
-    private final String columnName;
-    private final Object data;
-
-    /**
-     * Column constructor.
-     * @param columnName the column name
-     * @param obj the data of the column
-     */
-    public Column(String columnName, Object obj) {
-        checkNotNull(columnName, "columnName cannot be null");
-        checkNotNull(obj, "data cannot be null");
-        this.columnName = columnName;
-        this.data = obj;
-    }
-
-    /**
-     * Returns column data.
-     * @return column data
-     */
-    public Object data() {
-        return data;
-    }
-
-    /**
-     * Returns columnName.
-     * @return columnName
-     */
-    public String columnName() {
-        return columnName;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(columnName, data);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof Column) {
-            final Column other = (Column) obj;
-            return Objects.equals(this.columnName, other.columnName)
-                    && Objects.equals(this.data, other.data);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("columnName", columnName)
-                .add("data", data).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.ovsdb.rfc.notation;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * Column is the basic element of the OpenVswitch database.
+ */
+public final class Column {
+    private final String columnName;
+    private final Object data;
+
+    /**
+     * Column constructor.
+     * @param columnName the column name
+     * @param obj the data of the column
+     */
+    public Column(String columnName, Object obj) {
+        checkNotNull(columnName, "columnName cannot be null");
+        checkNotNull(obj, "data cannot be null");
+        this.columnName = columnName;
+        this.data = obj;
+    }
+
+    /**
+     * Returns column data.
+     * @return column data
+     */
+    public Object data() {
+        return data;
+    }
+
+    /**
+     * Returns columnName.
+     * @return columnName
+     */
+    public String columnName() {
+        return columnName;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(columnName, data);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Column) {
+            final Column other = (Column) obj;
+            return Objects.equals(this.columnName, other.columnName)
+                    && Objects.equals(this.data, other.data);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("columnName", columnName)
+                .add("data", data).toString();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java
index 9ef5b48..3326922 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/Row.java
@@ -1,128 +1,128 @@
-/*
- * 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.notation;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Objects;
-
-import com.google.common.collect.Maps;
-
-/**
- * Row is the basic element of the OpenVswitch's table.
- */
-public final class Row {
-    private String tableName;
-    private Map<String, Column> columns;
-
-    /**
-     * Row constructor.
-     */
-    public Row() {
-        this.columns = Maps.newHashMap();
-    }
-
-    /**
-     * Row constructor.
-     * @param tableName table name
-     */
-    public Row(String tableName) {
-        checkNotNull(tableName, "tableName cannot be null");
-        this.tableName = tableName;
-        this.columns = Maps.newHashMap();
-    }
-
-    /**
-     * Row constructor.
-     * @param tableName table name
-     * @param columns Map of Column entity
-     */
-    public Row(String tableName, Map<String, Column> columns) {
-        checkNotNull(tableName, "table name cannot be null");
-        checkNotNull(columns, "columns cannot be null");
-        this.tableName = tableName;
-        this.columns = columns;
-    }
-
-    /**
-     * Returns tableName.
-     * @return tableName
-     */
-    public String tableName() {
-        return tableName;
-    }
-
-    /**
-     * Set tableName value.
-     * @param tableName table name
-     */
-    public void setTableName(String tableName) {
-        this.tableName = tableName;
-    }
-
-    /**
-     * Returns Column by ColumnSchema.
-     * @param columnName column name
-     * @return Column
-     */
-    public Column getColumn(String columnName) {
-        return columns.get(columnName);
-    }
-
-    /**
-     * Returns Collection of Column.
-     * @return Collection of Column
-     */
-    public Collection<Column> getColumns() {
-        return columns.values();
-    }
-
-    /**
-     * add Column.
-     * @param columnName column name
-     * @param data Column entity
-     */
-    public void addColumn(String columnName, Column data) {
-        this.columns.put(columnName, data);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(tableName, columns);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof Row) {
-            final Row other = (Row) obj;
-            return Objects.equals(this.tableName, other.tableName)
-                    && Objects.equals(this.columns, other.columns);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("tableName", tableName)
-                .add("columns", columns).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.ovsdb.rfc.notation;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+
+import com.google.common.collect.Maps;
+
+/**
+ * Row is the basic element of the OpenVswitch's table.
+ */
+public final class Row {
+    private String tableName;
+    private Map<String, Column> columns;
+
+    /**
+     * Row constructor.
+     */
+    public Row() {
+        this.columns = Maps.newHashMap();
+    }
+
+    /**
+     * Row constructor.
+     * @param tableName table name
+     */
+    public Row(String tableName) {
+        checkNotNull(tableName, "tableName cannot be null");
+        this.tableName = tableName;
+        this.columns = Maps.newHashMap();
+    }
+
+    /**
+     * Row constructor.
+     * @param tableName table name
+     * @param columns Map of Column entity
+     */
+    public Row(String tableName, Map<String, Column> columns) {
+        checkNotNull(tableName, "table name cannot be null");
+        checkNotNull(columns, "columns cannot be null");
+        this.tableName = tableName;
+        this.columns = columns;
+    }
+
+    /**
+     * Returns tableName.
+     * @return tableName
+     */
+    public String tableName() {
+        return tableName;
+    }
+
+    /**
+     * Set tableName value.
+     * @param tableName table name
+     */
+    public void setTableName(String tableName) {
+        this.tableName = tableName;
+    }
+
+    /**
+     * Returns Column by ColumnSchema.
+     * @param columnName column name
+     * @return Column
+     */
+    public Column getColumn(String columnName) {
+        return columns.get(columnName);
+    }
+
+    /**
+     * Returns Collection of Column.
+     * @return Collection of Column
+     */
+    public Collection<Column> getColumns() {
+        return columns.values();
+    }
+
+    /**
+     * add Column.
+     * @param columnName column name
+     * @param data Column entity
+     */
+    public void addColumn(String columnName, Column data) {
+        this.columns.put(columnName, data);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(tableName, columns);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof Row) {
+            final Row other = (Row) obj;
+            return Objects.equals(this.tableName, other.tableName)
+                    && Objects.equals(this.columns, other.columns);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("tableName", tableName)
+                .add("columns", columns).toString();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java
index 02e6bb7..66a8663 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/notation/json/UUIDConverter.java
@@ -1,32 +1,32 @@
-/*
- * 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.notation.json;
-
-import org.onosproject.ovsdb.rfc.notation.UUID;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.util.StdConverter;
-
-/**
- * UUIDConverter Converter.
- */
-public class UUIDConverter extends StdConverter<JsonNode, UUID> {
-
-    @Override
-    public UUID convert(JsonNode json) {
-        return UUID.uuid(json.get(1).asText());
-    }
-}
+/*
+ * 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.notation.json;
+
+import org.onosproject.ovsdb.rfc.notation.UUID;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.util.StdConverter;
+
+/**
+ * UUIDConverter Converter.
+ */
+public class UUIDConverter extends StdConverter<JsonNode, UUID> {
+
+    @Override
+    public UUID convert(JsonNode json) {
+        return UUID.uuid(json.get(1).asText());
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java
index 8dcf1fc..08b5e52 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Delete.java
@@ -1,77 +1,77 @@
-/*
- * 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.operations;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-
-import org.onosproject.ovsdb.rfc.notation.Condition;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * delete operation.Refer to RFC 7047 Section 5.2.
- */
-public final class Delete implements Operation {
-
-    @JsonIgnore
-    private final TableSchema tableSchema;
-    private final String op;
-    private final List<Condition> where;
-
-    /**
-     * Constructs a Delete object.
-     * @param schema TableSchema entity
-     * @param where the List of Condition entity
-     */
-    public Delete(TableSchema schema, List<Condition> where) {
-        checkNotNull(schema, "TableSchema cannot be null");
-        checkNotNull(where, "where is not null");
-        this.tableSchema = schema;
-        this.op = Operations.DELETE.op();
-        this.where = where;
-    }
-
-    /**
-     * Returns the where member of delete operation.
-     * @return the where member of delete operation
-     */
-    public List<Condition> getWhere() {
-        return where;
-    }
-
-    @Override
-    public String getOp() {
-        return op;
-    }
-
-    @Override
-    public TableSchema getTableSchema() {
-        return tableSchema;
-    }
-
-    /**
-     * For the use of serialization.
-     * @return the table member of update operation
-     */
-    @JsonProperty
-    public String getTable() {
-        return tableSchema.name();
-    }
-}
+/*
+ * 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.operations;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import org.onosproject.ovsdb.rfc.notation.Condition;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * delete operation.Refer to RFC 7047 Section 5.2.
+ */
+public final class Delete implements Operation {
+
+    @JsonIgnore
+    private final TableSchema tableSchema;
+    private final String op;
+    private final List<Condition> where;
+
+    /**
+     * Constructs a Delete object.
+     * @param schema TableSchema entity
+     * @param where the List of Condition entity
+     */
+    public Delete(TableSchema schema, List<Condition> where) {
+        checkNotNull(schema, "TableSchema cannot be null");
+        checkNotNull(where, "where is not null");
+        this.tableSchema = schema;
+        this.op = Operations.DELETE.op();
+        this.where = where;
+    }
+
+    /**
+     * Returns the where member of delete operation.
+     * @return the where member of delete operation
+     */
+    public List<Condition> getWhere() {
+        return where;
+    }
+
+    @Override
+    public String getOp() {
+        return op;
+    }
+
+    @Override
+    public TableSchema getTableSchema() {
+        return tableSchema;
+    }
+
+    /**
+     * For the use of serialization.
+     * @return the table member of update operation
+     */
+    @JsonProperty
+    public String getTable() {
+        return tableSchema.name();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java
index 32e5ce0..8545b43 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Insert.java
@@ -1,110 +1,110 @@
-/*
- * 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.operations;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collection;
-import java.util.Map;
-
-import org.onosproject.ovsdb.rfc.notation.Column;
-import org.onosproject.ovsdb.rfc.notation.Row;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-import org.onosproject.ovsdb.rfc.utils.TransValueUtil;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.collect.Maps;
-
-/**
- * insert operation.Refer to RFC 7047 Section 5.2.
- */
-public final class Insert implements Operation {
-
-    @JsonIgnore
-    private final TableSchema tableSchema;
-    private final String op;
-    @JsonProperty("uuid-name")
-    private final String uuidName;
-    private final Map<String, Object> row;
-
-    /**
-     * Constructs a Insert object.
-     * @param schema TableSchema entity
-     * @param uuidName uuid-name
-     * @param row Row entity
-     */
-    public Insert(TableSchema schema, String uuidName, Row row) {
-        checkNotNull(schema, "TableSchema cannot be null");
-        checkNotNull(uuidName, "uuid name cannot be null");
-        checkNotNull(row, "row cannot be null");
-        this.tableSchema = schema;
-        this.op = Operations.INSERT.op();
-        this.uuidName = uuidName;
-        this.row = Maps.newHashMap();
-        generateOperationRow(row);
-    }
-
-    /**
-     * Row entity convert into the row format of insert operation. Refer to RFC
-     * 7047 Section 5.2.
-     * @param row Row entity
-     */
-    private void generateOperationRow(Row row) {
-        Collection<Column> columns = row.getColumns();
-        for (Column column : columns) {
-            String columnName = column.columnName();
-            Object value = column.data();
-            Object formatValue = TransValueUtil.getFormatData(value);
-            this.row.put(columnName, formatValue);
-        }
-    }
-
-    /**
-     * Returns the uuid-name member of insert operation.
-     * @return the uuid-name member of insert operation
-     */
-    public String getUuidName() {
-        return uuidName;
-    }
-
-    /**
-     * Returns the row member of insert operation.
-     * @return the row member of insert operation
-     */
-    public Map<String, Object> getRow() {
-        return row;
-    }
-
-    @Override
-    public String getOp() {
-        return op;
-    }
-
-    @Override
-    public TableSchema getTableSchema() {
-        return tableSchema;
-    }
-
-    /**
-     * For the use of serialization.
-     * @return the table member of update operation
-     */
-    @JsonProperty
-    public String getTable() {
-        return tableSchema.name();
-    }
-}
+/*
+ * 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.operations;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+import org.onosproject.ovsdb.rfc.utils.TransValueUtil;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.Maps;
+
+/**
+ * insert operation.Refer to RFC 7047 Section 5.2.
+ */
+public final class Insert implements Operation {
+
+    @JsonIgnore
+    private final TableSchema tableSchema;
+    private final String op;
+    @JsonProperty("uuid-name")
+    private final String uuidName;
+    private final Map<String, Object> row;
+
+    /**
+     * Constructs a Insert object.
+     * @param schema TableSchema entity
+     * @param uuidName uuid-name
+     * @param row Row entity
+     */
+    public Insert(TableSchema schema, String uuidName, Row row) {
+        checkNotNull(schema, "TableSchema cannot be null");
+        checkNotNull(uuidName, "uuid name cannot be null");
+        checkNotNull(row, "row cannot be null");
+        this.tableSchema = schema;
+        this.op = Operations.INSERT.op();
+        this.uuidName = uuidName;
+        this.row = Maps.newHashMap();
+        generateOperationRow(row);
+    }
+
+    /**
+     * Row entity convert into the row format of insert operation. Refer to RFC
+     * 7047 Section 5.2.
+     * @param row Row entity
+     */
+    private void generateOperationRow(Row row) {
+        Collection<Column> columns = row.getColumns();
+        for (Column column : columns) {
+            String columnName = column.columnName();
+            Object value = column.data();
+            Object formatValue = TransValueUtil.getFormatData(value);
+            this.row.put(columnName, formatValue);
+        }
+    }
+
+    /**
+     * Returns the uuid-name member of insert operation.
+     * @return the uuid-name member of insert operation
+     */
+    public String getUuidName() {
+        return uuidName;
+    }
+
+    /**
+     * Returns the row member of insert operation.
+     * @return the row member of insert operation
+     */
+    public Map<String, Object> getRow() {
+        return row;
+    }
+
+    @Override
+    public String getOp() {
+        return op;
+    }
+
+    @Override
+    public TableSchema getTableSchema() {
+        return tableSchema;
+    }
+
+    /**
+     * For the use of serialization.
+     * @return the table member of update operation
+     */
+    @JsonProperty
+    public String getTable() {
+        return tableSchema.name();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java
index 1a7023d..b282779 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Mutate.java
@@ -1,91 +1,91 @@
-/*
- * 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.operations;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-
-import org.onosproject.ovsdb.rfc.notation.Condition;
-import org.onosproject.ovsdb.rfc.notation.Mutation;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * mutate operation.Refer to RFC 7047 Section 5.2.
- */
-public final class Mutate implements Operation {
-
-    @JsonIgnore
-    private final TableSchema tableSchema;
-    private final String op;
-    private final List<Condition> where;
-    private final List<Mutation> mutations;
-
-    /**
-     * Constructs a Mutate object.
-     * @param schema TableSchema entity
-     * @param where the List of Condition entity
-     * @param mutations the List of Mutation entity
-     */
-    public Mutate(TableSchema schema, List<Condition> where,
-                  List<Mutation> mutations) {
-        checkNotNull(schema, "TableSchema cannot be null");
-        checkNotNull(mutations, "mutations cannot be null");
-        checkNotNull(where, "where cannot be null");
-        this.tableSchema = schema;
-        this.op = Operations.MUTATE.op();
-        this.where = where;
-        this.mutations = mutations;
-    }
-
-    /**
-     * Returns the mutations member of mutate operation.
-     * @return the mutations member of mutate operation
-     */
-    public List<Mutation> getMutations() {
-        return mutations;
-    }
-
-    /**
-     * Returns the where member of mutate operation.
-     * @return the where member of mutate operation
-     */
-    public List<Condition> getWhere() {
-        return where;
-    }
-
-    @Override
-    public String getOp() {
-        return op;
-    }
-
-    @Override
-    public TableSchema getTableSchema() {
-        return tableSchema;
-    }
-
-    /**
-     * For the use of serialization.
-     * @return the table member of update operation
-     */
-    @JsonProperty
-    public String getTable() {
-        return tableSchema.name();
-    }
-}
+/*
+ * 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.operations;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import org.onosproject.ovsdb.rfc.notation.Condition;
+import org.onosproject.ovsdb.rfc.notation.Mutation;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * mutate operation.Refer to RFC 7047 Section 5.2.
+ */
+public final class Mutate implements Operation {
+
+    @JsonIgnore
+    private final TableSchema tableSchema;
+    private final String op;
+    private final List<Condition> where;
+    private final List<Mutation> mutations;
+
+    /**
+     * Constructs a Mutate object.
+     * @param schema TableSchema entity
+     * @param where the List of Condition entity
+     * @param mutations the List of Mutation entity
+     */
+    public Mutate(TableSchema schema, List<Condition> where,
+                  List<Mutation> mutations) {
+        checkNotNull(schema, "TableSchema cannot be null");
+        checkNotNull(mutations, "mutations cannot be null");
+        checkNotNull(where, "where cannot be null");
+        this.tableSchema = schema;
+        this.op = Operations.MUTATE.op();
+        this.where = where;
+        this.mutations = mutations;
+    }
+
+    /**
+     * Returns the mutations member of mutate operation.
+     * @return the mutations member of mutate operation
+     */
+    public List<Mutation> getMutations() {
+        return mutations;
+    }
+
+    /**
+     * Returns the where member of mutate operation.
+     * @return the where member of mutate operation
+     */
+    public List<Condition> getWhere() {
+        return where;
+    }
+
+    @Override
+    public String getOp() {
+        return op;
+    }
+
+    @Override
+    public TableSchema getTableSchema() {
+        return tableSchema;
+    }
+
+    /**
+     * For the use of serialization.
+     * @return the table member of update operation
+     */
+    @JsonProperty
+    public String getTable() {
+        return tableSchema.name();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java
index 7c75710..ba1ec74 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Select.java
@@ -1,89 +1,89 @@
-/*
- * 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.operations;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.List;
-
-import org.onosproject.ovsdb.rfc.notation.Condition;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-
-/**
- * select operation.Refer to RFC 7047 Section 5.2.
- */
-public final class Select implements Operation {
-
-    @JsonIgnore
-    private final TableSchema tableSchema;
-    private final String op;
-    private final List<Condition> where;
-    private final List<String> columns;
-
-    /**
-     * Constructs a Select object.
-     * @param schema TableSchema entity
-     * @param where the List of Condition entity
-     * @param columns the List of column name
-     */
-    public Select(TableSchema schema, List<Condition> where, List<String> columns) {
-        checkNotNull(schema, "TableSchema cannot be null");
-        checkNotNull(where, "where cannot be null");
-        checkNotNull(columns, "columns cannot be null");
-        this.tableSchema = schema;
-        this.op = Operations.SELECT.op();
-        this.where = where;
-        this.columns = columns;
-    }
-
-    /**
-     * Returns the columns member of select operation.
-     * @return the columns member of select operation
-     */
-    public List<String> getColumns() {
-        return columns;
-    }
-
-    /**
-     * Returns the where member of select operation.
-     * @return the where member of select operation
-     */
-    public List<Condition> getWhere() {
-        return where;
-    }
-
-    @Override
-    public String getOp() {
-        return op;
-    }
-
-    @Override
-    public TableSchema getTableSchema() {
-        return tableSchema;
-    }
-
-    /**
-     * For the use of serialization.
-     * @return the table member of update operation
-     */
-    @JsonProperty
-    public String getTable() {
-        return tableSchema.name();
-    }
-}
+/*
+ * 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.operations;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.List;
+
+import org.onosproject.ovsdb.rfc.notation.Condition;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * select operation.Refer to RFC 7047 Section 5.2.
+ */
+public final class Select implements Operation {
+
+    @JsonIgnore
+    private final TableSchema tableSchema;
+    private final String op;
+    private final List<Condition> where;
+    private final List<String> columns;
+
+    /**
+     * Constructs a Select object.
+     * @param schema TableSchema entity
+     * @param where the List of Condition entity
+     * @param columns the List of column name
+     */
+    public Select(TableSchema schema, List<Condition> where, List<String> columns) {
+        checkNotNull(schema, "TableSchema cannot be null");
+        checkNotNull(where, "where cannot be null");
+        checkNotNull(columns, "columns cannot be null");
+        this.tableSchema = schema;
+        this.op = Operations.SELECT.op();
+        this.where = where;
+        this.columns = columns;
+    }
+
+    /**
+     * Returns the columns member of select operation.
+     * @return the columns member of select operation
+     */
+    public List<String> getColumns() {
+        return columns;
+    }
+
+    /**
+     * Returns the where member of select operation.
+     * @return the where member of select operation
+     */
+    public List<Condition> getWhere() {
+        return where;
+    }
+
+    @Override
+    public String getOp() {
+        return op;
+    }
+
+    @Override
+    public TableSchema getTableSchema() {
+        return tableSchema;
+    }
+
+    /**
+     * For the use of serialization.
+     * @return the table member of update operation
+     */
+    @JsonProperty
+    public String getTable() {
+        return tableSchema.name();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java
index 8f21f9c..81a1cab 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/operations/Update.java
@@ -1,111 +1,111 @@
-/*
- * 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.operations;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-
-import org.onosproject.ovsdb.rfc.notation.Column;
-import org.onosproject.ovsdb.rfc.notation.Condition;
-import org.onosproject.ovsdb.rfc.notation.Row;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-import org.onosproject.ovsdb.rfc.utils.TransValueUtil;
-
-import com.fasterxml.jackson.annotation.JsonIgnore;
-import com.fasterxml.jackson.annotation.JsonProperty;
-import com.google.common.collect.Maps;
-
-/**
- * update operation.Refer to RFC 7047 Section 5.2.
- */
-public final class Update implements Operation {
-
-    @JsonIgnore
-    private final TableSchema tableSchema;
-    private final String op;
-    private final Map<String, Object> row;
-    private final List<Condition> where;
-
-    /**
-     * Constructs a Update object.
-     * @param schema TableSchema entity
-     * @param row Row entity
-     * @param where the List of Condition entity
-     */
-    public Update(TableSchema schema, Row row, List<Condition> where) {
-        checkNotNull(schema, "TableSchema cannot be null");
-        checkNotNull(row, "row cannot be null");
-        checkNotNull(where, "where cannot be null");
-        this.tableSchema = schema;
-        this.op = Operations.UPDATE.op();
-        this.row = Maps.newHashMap();
-        this.where = where;
-        generateOperationRow(row);
-    }
-
-    /**
-     * Row entity convert into the row format of update operation. Refer to RFC
-     * 7047 Section 5.2.
-     * @param row Row entity
-     */
-    private void generateOperationRow(Row row) {
-        Collection<Column> columns = row.getColumns();
-        for (Column column : columns) {
-            String columnName = column.columnName();
-            Object value = column.data();
-            Object formatValue = TransValueUtil.getFormatData(value);
-            this.row.put(columnName, formatValue);
-        }
-    }
-
-    /**
-     * Returns the row member of update operation.
-     * @return the row member of update operation
-     */
-    public Map<String, Object> getRow() {
-        return row;
-    }
-
-    /**
-     * Returns the where member of update operation.
-     * @return the where member of update operation
-     */
-    public List<Condition> getWhere() {
-        return where;
-    }
-
-    @Override
-    public String getOp() {
-        return op;
-    }
-
-    @Override
-    public TableSchema getTableSchema() {
-        return tableSchema;
-    }
-
-    /**
-     * For the use of serialization.
-     * @return the table member of update operation
-     */
-    @JsonProperty
-    public String getTable() {
-        return tableSchema.name();
-    }
-}
+/*
+ * 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.operations;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Condition;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+import org.onosproject.ovsdb.rfc.utils.TransValueUtil;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.Maps;
+
+/**
+ * update operation.Refer to RFC 7047 Section 5.2.
+ */
+public final class Update implements Operation {
+
+    @JsonIgnore
+    private final TableSchema tableSchema;
+    private final String op;
+    private final Map<String, Object> row;
+    private final List<Condition> where;
+
+    /**
+     * Constructs a Update object.
+     * @param schema TableSchema entity
+     * @param row Row entity
+     * @param where the List of Condition entity
+     */
+    public Update(TableSchema schema, Row row, List<Condition> where) {
+        checkNotNull(schema, "TableSchema cannot be null");
+        checkNotNull(row, "row cannot be null");
+        checkNotNull(where, "where cannot be null");
+        this.tableSchema = schema;
+        this.op = Operations.UPDATE.op();
+        this.row = Maps.newHashMap();
+        this.where = where;
+        generateOperationRow(row);
+    }
+
+    /**
+     * Row entity convert into the row format of update operation. Refer to RFC
+     * 7047 Section 5.2.
+     * @param row Row entity
+     */
+    private void generateOperationRow(Row row) {
+        Collection<Column> columns = row.getColumns();
+        for (Column column : columns) {
+            String columnName = column.columnName();
+            Object value = column.data();
+            Object formatValue = TransValueUtil.getFormatData(value);
+            this.row.put(columnName, formatValue);
+        }
+    }
+
+    /**
+     * Returns the row member of update operation.
+     * @return the row member of update operation
+     */
+    public Map<String, Object> getRow() {
+        return row;
+    }
+
+    /**
+     * Returns the where member of update operation.
+     * @return the where member of update operation
+     */
+    public List<Condition> getWhere() {
+        return where;
+    }
+
+    @Override
+    public String getOp() {
+        return op;
+    }
+
+    @Override
+    public TableSchema getTableSchema() {
+        return tableSchema;
+    }
+
+    /**
+     * For the use of serialization.
+     * @return the table member of update operation
+     */
+    @JsonProperty
+    public String getTable() {
+        return tableSchema.name();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java
index da60813..210181a 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/BaseTypeFactory.java
@@ -1,214 +1,214 @@
-/*
- * 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.schema.type;
-
-import java.util.Set;
-
-import org.onosproject.ovsdb.rfc.error.AbnormalJsonNodeException;
-import org.onosproject.ovsdb.rfc.schema.type.UuidBaseType.RefType;
-import org.onosproject.ovsdb.rfc.utils.ObjectMapperUtil;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.google.common.collect.Sets;
-
-/**
- * BaseType Factory class.
- */
-public final class BaseTypeFactory {
-
-    /**
-     * Constructs a BaseTypeFactory object. This class should not be
-     * instantiated.
-     */
-    private BaseTypeFactory() {
-    }
-
-    /**
-     * Create a BaseType from the JsonNode.
-     * @param baseTypeJson the BaseType JsonNode
-     * @param keyorval the key node or value node
-     * @return BaseType
-     */
-    public static BaseType getBaseTypeFromJson(JsonNode baseTypeJson, String keyorval) {
-        if (baseTypeJson.isValueNode()) {
-            String type = baseTypeJson.asText().trim();
-            return fromTypeStr(type);
-        } else {
-            if (!baseTypeJson.has(keyorval)) {
-                String message = "Abnormal BaseType JsonNode, it should contain 'key' or 'value' node but was not found"
-                        + ObjectMapperUtil.convertToString(baseTypeJson);
-                throw new AbnormalJsonNodeException(message);
-            }
-            return fromJsonNode(baseTypeJson.get(keyorval));
-        }
-    }
-
-    /**
-     * Get BaseType by the type value of JsonNode.
-     * @param type the type value of JsonNode
-     * @return BaseType
-     */
-    private static BaseType fromTypeStr(String type) {
-        switch (type) {
-        case "boolean":
-            return new BooleanBaseType();
-        case "integer":
-            return new IntegerBaseType();
-        case "real":
-            return new RealBaseType();
-        case "string":
-            return new StringBaseType();
-        case "uuid":
-            return new UuidBaseType();
-        default:
-            return null;
-        }
-    }
-
-    /**
-     * json like "string" or json like {"type" : "string", "enum": ["set",
-     * ["access", "native-tagged"]]}" for key or value.
-     * @param type JsonNode
-     */
-    private static BaseType fromJsonNode(JsonNode type) {
-        if (type.isTextual()) {
-            return fromTypeStr(type.asText());
-        } else if (type.isObject() && type.has("type")) {
-            String typeStr = type.get("type").asText();
-            switch (typeStr) {
-            case "boolean":
-                return new BooleanBaseType();
-            case "integer":
-                return getIntegerBaseType(type);
-            case "real":
-                return getRealBaseType(type);
-            case "string":
-                return getStringBaseType(type);
-            case "uuid":
-                return getUuidBaseType(type);
-            default:
-                return null;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Get IntegerBaseType by the type value of JsonNode which contains the
-     * constraints.
-     * @param type the type value of JsonNode
-     * @return IntegerBaseType
-     */
-    private static IntegerBaseType getIntegerBaseType(JsonNode type) {
-        int min = Integer.MIN_VALUE;
-        int max = Integer.MAX_VALUE;
-        Set<Integer> enums = Sets.newHashSet();
-        JsonNode node = type.get("minInteger");
-        if (node != null) {
-            min = node.asInt();
-        }
-        node = type.get("maxInteger");
-        if (node != null) {
-            max = node.asInt();
-        }
-        if (type.has("enum")) {
-            JsonNode anEnum = type.get("enum").get(1);
-            for (JsonNode n : anEnum) {
-                enums.add(n.asInt());
-            }
-        }
-        return new IntegerBaseType(min, max, enums);
-    }
-
-    /**
-     * Get RealBaseType by the type value of JsonNode which contains the
-     * constraints.
-     * @param type the type value of JsonNode
-     * @return RealBaseType
-     */
-    private static RealBaseType getRealBaseType(JsonNode type) {
-        double min = Double.MIN_VALUE;
-        double max = Double.MAX_VALUE;
-        Set<Double> enums = Sets.newHashSet();
-        JsonNode node = type.get("minReal");
-        if (node != null) {
-            min = node.asDouble();
-        }
-        node = type.get("maxReal");
-        if (node != null) {
-            max = node.asDouble();
-        }
-        if (type.has("enum")) {
-            JsonNode anEnum = type.get("enum").get(1);
-            for (JsonNode n : anEnum) {
-                enums.add(n.asDouble());
-            }
-        }
-        return new RealBaseType(min, max, enums);
-    }
-
-    /**
-     * Get StringBaseType by the type value of JsonNode which contains the
-     * constraints.
-     * @param type the type value of JsonNode
-     * @return StringBaseType
-     */
-    private static StringBaseType getStringBaseType(JsonNode type) {
-        int minLength = Integer.MIN_VALUE;
-        int maxLength = Integer.MAX_VALUE;
-        Set<String> enums = Sets.newHashSet();
-        JsonNode node = type.get("minLength");
-        if (node != null) {
-            minLength = node.asInt();
-        }
-        node = type.get("maxLength");
-        if (node != null) {
-            maxLength = node.asInt();
-        }
-        if (type.has("enum")) {
-            JsonNode enumVal = type.get("enum");
-            if (enumVal.isArray()) {
-                JsonNode anEnum = enumVal.get(1);
-                for (JsonNode n : anEnum) {
-                    enums.add(n.asText());
-                }
-            } else if (enumVal.isTextual()) {
-                enums.add(enumVal.asText());
-            }
-        }
-        return new StringBaseType(minLength, maxLength, enums);
-    }
-
-    /**
-     * Get UuidBaseType by the type value of JsonNode which contains the
-     * constraints.
-     * @param type the type value of JsonNode
-     * @return UuidBaseType
-     */
-    private static UuidBaseType getUuidBaseType(JsonNode type) {
-        String refTable = null;
-        String refType = RefType.STRONG.refType();
-        JsonNode node = type.get("refTable");
-        if (node != null) {
-            refTable = node.asText();
-        }
-        node = type.get("refType");
-        if (node != null) {
-            refType = node.asText();
-        }
-        return new UuidBaseType(refTable, refType);
-    }
-}
+/*
+ * 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.schema.type;
+
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.error.AbnormalJsonNodeException;
+import org.onosproject.ovsdb.rfc.schema.type.UuidBaseType.RefType;
+import org.onosproject.ovsdb.rfc.utils.ObjectMapperUtil;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.Sets;
+
+/**
+ * BaseType Factory class.
+ */
+public final class BaseTypeFactory {
+
+    /**
+     * Constructs a BaseTypeFactory object. This class should not be
+     * instantiated.
+     */
+    private BaseTypeFactory() {
+    }
+
+    /**
+     * Create a BaseType from the JsonNode.
+     * @param baseTypeJson the BaseType JsonNode
+     * @param keyorval the key node or value node
+     * @return BaseType
+     */
+    public static BaseType getBaseTypeFromJson(JsonNode baseTypeJson, String keyorval) {
+        if (baseTypeJson.isValueNode()) {
+            String type = baseTypeJson.asText().trim();
+            return fromTypeStr(type);
+        } else {
+            if (!baseTypeJson.has(keyorval)) {
+                String message = "Abnormal BaseType JsonNode, it should contain 'key' or 'value' node but was not found"
+                        + ObjectMapperUtil.convertToString(baseTypeJson);
+                throw new AbnormalJsonNodeException(message);
+            }
+            return fromJsonNode(baseTypeJson.get(keyorval));
+        }
+    }
+
+    /**
+     * Get BaseType by the type value of JsonNode.
+     * @param type the type value of JsonNode
+     * @return BaseType
+     */
+    private static BaseType fromTypeStr(String type) {
+        switch (type) {
+        case "boolean":
+            return new BooleanBaseType();
+        case "integer":
+            return new IntegerBaseType();
+        case "real":
+            return new RealBaseType();
+        case "string":
+            return new StringBaseType();
+        case "uuid":
+            return new UuidBaseType();
+        default:
+            return null;
+        }
+    }
+
+    /**
+     * json like "string" or json like {"type" : "string", "enum": ["set",
+     * ["access", "native-tagged"]]}" for key or value.
+     * @param type JsonNode
+     */
+    private static BaseType fromJsonNode(JsonNode type) {
+        if (type.isTextual()) {
+            return fromTypeStr(type.asText());
+        } else if (type.isObject() && type.has("type")) {
+            String typeStr = type.get("type").asText();
+            switch (typeStr) {
+            case "boolean":
+                return new BooleanBaseType();
+            case "integer":
+                return getIntegerBaseType(type);
+            case "real":
+                return getRealBaseType(type);
+            case "string":
+                return getStringBaseType(type);
+            case "uuid":
+                return getUuidBaseType(type);
+            default:
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get IntegerBaseType by the type value of JsonNode which contains the
+     * constraints.
+     * @param type the type value of JsonNode
+     * @return IntegerBaseType
+     */
+    private static IntegerBaseType getIntegerBaseType(JsonNode type) {
+        int min = Integer.MIN_VALUE;
+        int max = Integer.MAX_VALUE;
+        Set<Integer> enums = Sets.newHashSet();
+        JsonNode node = type.get("minInteger");
+        if (node != null) {
+            min = node.asInt();
+        }
+        node = type.get("maxInteger");
+        if (node != null) {
+            max = node.asInt();
+        }
+        if (type.has("enum")) {
+            JsonNode anEnum = type.get("enum").get(1);
+            for (JsonNode n : anEnum) {
+                enums.add(n.asInt());
+            }
+        }
+        return new IntegerBaseType(min, max, enums);
+    }
+
+    /**
+     * Get RealBaseType by the type value of JsonNode which contains the
+     * constraints.
+     * @param type the type value of JsonNode
+     * @return RealBaseType
+     */
+    private static RealBaseType getRealBaseType(JsonNode type) {
+        double min = Double.MIN_VALUE;
+        double max = Double.MAX_VALUE;
+        Set<Double> enums = Sets.newHashSet();
+        JsonNode node = type.get("minReal");
+        if (node != null) {
+            min = node.asDouble();
+        }
+        node = type.get("maxReal");
+        if (node != null) {
+            max = node.asDouble();
+        }
+        if (type.has("enum")) {
+            JsonNode anEnum = type.get("enum").get(1);
+            for (JsonNode n : anEnum) {
+                enums.add(n.asDouble());
+            }
+        }
+        return new RealBaseType(min, max, enums);
+    }
+
+    /**
+     * Get StringBaseType by the type value of JsonNode which contains the
+     * constraints.
+     * @param type the type value of JsonNode
+     * @return StringBaseType
+     */
+    private static StringBaseType getStringBaseType(JsonNode type) {
+        int minLength = Integer.MIN_VALUE;
+        int maxLength = Integer.MAX_VALUE;
+        Set<String> enums = Sets.newHashSet();
+        JsonNode node = type.get("minLength");
+        if (node != null) {
+            minLength = node.asInt();
+        }
+        node = type.get("maxLength");
+        if (node != null) {
+            maxLength = node.asInt();
+        }
+        if (type.has("enum")) {
+            JsonNode enumVal = type.get("enum");
+            if (enumVal.isArray()) {
+                JsonNode anEnum = enumVal.get(1);
+                for (JsonNode n : anEnum) {
+                    enums.add(n.asText());
+                }
+            } else if (enumVal.isTextual()) {
+                enums.add(enumVal.asText());
+            }
+        }
+        return new StringBaseType(minLength, maxLength, enums);
+    }
+
+    /**
+     * Get UuidBaseType by the type value of JsonNode which contains the
+     * constraints.
+     * @param type the type value of JsonNode
+     * @return UuidBaseType
+     */
+    private static UuidBaseType getUuidBaseType(JsonNode type) {
+        String refTable = null;
+        String refType = RefType.STRONG.refType();
+        JsonNode node = type.get("refTable");
+        if (node != null) {
+            refTable = node.asText();
+        }
+        node = type.get("refType");
+        if (node != null) {
+            refType = node.asText();
+        }
+        return new UuidBaseType(refTable, refType);
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java
index 1af6974..33c08c5 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/schema/type/ColumnTypeFactory.java
@@ -1,123 +1,123 @@
-/*
- * 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.schema.type;
-
-import org.onosproject.ovsdb.rfc.error.AbnormalJsonNodeException;
-import org.onosproject.ovsdb.rfc.utils.ObjectMapperUtil;
-
-import com.fasterxml.jackson.databind.JsonNode;
-
-/**
- * ColumnType Factory class.
- */
-public final class ColumnTypeFactory {
-
-    /**
-     * Constructs a ColumnTypeFactory object. This class should not be
-     * instantiated.
-     */
-    private ColumnTypeFactory() {
-    }
-
-    /**
-     * Those Json's key/value pairs.
-     */
-    public enum Type {
-        KEY("key"), VALUE("value");
-
-        private final String type;
-
-        private Type(String type) {
-            this.type = type;
-        }
-
-        /**
-         * Returns the type for Type.
-         * @return the type
-         */
-        public String type() {
-            return type;
-        }
-    }
-
-    /**
-     * JsonNode like
-     * "flow_tables":{"type":{"key":{"maxInteger":254,"minInteger":0,"type":
-     * "integer"},"min":0,"value":{"type":"uuid","refTable":"Flow_Table"},"max":
-     * "unlimited"}}.
-     * @param columnTypeJson the ColumnType JsonNode
-     * @return ColumnType
-     */
-    public static ColumnType getColumnTypeFromJson(JsonNode columnTypeJson) {
-        if (!columnTypeJson.isObject() || !columnTypeJson.has(Type.VALUE.type())) {
-            return createAtomicColumnType(columnTypeJson);
-        } else if (!columnTypeJson.isValueNode() && columnTypeJson.has(Type.VALUE.type())) {
-            return createKeyValuedColumnType(columnTypeJson);
-        }
-        String message = "Abnormal ColumnType JsonNode, it should be AtomicColumnType or KeyValuedColumnType"
-                + ObjectMapperUtil.convertToString(columnTypeJson);
-        throw new AbnormalJsonNodeException(message);
-    }
-
-    /**
-     * Create AtomicColumnType entity.
-     * @param json JsonNode
-     * @return AtomicColumnType entity
-     */
-    private static AtomicColumnType createAtomicColumnType(JsonNode json) {
-        BaseType baseType = BaseTypeFactory.getBaseTypeFromJson(json, Type.KEY.type());
-        int min = 1;
-        int max = 1;
-        JsonNode node = json.get("min");
-        if (node != null && node.isNumber()) {
-            min = node.asInt();
-        }
-        node = json.get("max");
-        if (node != null) {
-            if (node.isNumber()) {
-                max = node.asInt();
-            } else if (node.isTextual() && "unlimited".equals(node.asText())) {
-                max = Integer.MAX_VALUE;
-            }
-        }
-        return new AtomicColumnType(baseType, min, max);
-    }
-
-    /**
-     * Create KeyValuedColumnType entity.
-     * @param json JsonNode
-     * @return KeyValuedColumnType entity
-     */
-    private static KeyValuedColumnType createKeyValuedColumnType(JsonNode json) {
-        BaseType keyType = BaseTypeFactory.getBaseTypeFromJson(json, Type.KEY.type());
-        BaseType valueType = BaseTypeFactory.getBaseTypeFromJson(json, Type.VALUE.type());
-        int min = 1;
-        int max = 1;
-        JsonNode node = json.get("min");
-        if (node != null && node.isNumber()) {
-            min = node.asInt();
-        }
-        node = json.get("max");
-        if (node != null) {
-            if (node.isNumber()) {
-                max = node.asInt();
-            } else if (node.isTextual() && "unlimited".equals(node.asText())) {
-                max = Integer.MAX_VALUE;
-            }
-        }
-        return new KeyValuedColumnType(keyType, valueType, min, max);
-    }
-}
+/*
+ * 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.schema.type;
+
+import org.onosproject.ovsdb.rfc.error.AbnormalJsonNodeException;
+import org.onosproject.ovsdb.rfc.utils.ObjectMapperUtil;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * ColumnType Factory class.
+ */
+public final class ColumnTypeFactory {
+
+    /**
+     * Constructs a ColumnTypeFactory object. This class should not be
+     * instantiated.
+     */
+    private ColumnTypeFactory() {
+    }
+
+    /**
+     * Those Json's key/value pairs.
+     */
+    public enum Type {
+        KEY("key"), VALUE("value");
+
+        private final String type;
+
+        private Type(String type) {
+            this.type = type;
+        }
+
+        /**
+         * Returns the type for Type.
+         * @return the type
+         */
+        public String type() {
+            return type;
+        }
+    }
+
+    /**
+     * JsonNode like
+     * "flow_tables":{"type":{"key":{"maxInteger":254,"minInteger":0,"type":
+     * "integer"},"min":0,"value":{"type":"uuid","refTable":"Flow_Table"},"max":
+     * "unlimited"}}.
+     * @param columnTypeJson the ColumnType JsonNode
+     * @return ColumnType
+     */
+    public static ColumnType getColumnTypeFromJson(JsonNode columnTypeJson) {
+        if (!columnTypeJson.isObject() || !columnTypeJson.has(Type.VALUE.type())) {
+            return createAtomicColumnType(columnTypeJson);
+        } else if (!columnTypeJson.isValueNode() && columnTypeJson.has(Type.VALUE.type())) {
+            return createKeyValuedColumnType(columnTypeJson);
+        }
+        String message = "Abnormal ColumnType JsonNode, it should be AtomicColumnType or KeyValuedColumnType"
+                + ObjectMapperUtil.convertToString(columnTypeJson);
+        throw new AbnormalJsonNodeException(message);
+    }
+
+    /**
+     * Create AtomicColumnType entity.
+     * @param json JsonNode
+     * @return AtomicColumnType entity
+     */
+    private static AtomicColumnType createAtomicColumnType(JsonNode json) {
+        BaseType baseType = BaseTypeFactory.getBaseTypeFromJson(json, Type.KEY.type());
+        int min = 1;
+        int max = 1;
+        JsonNode node = json.get("min");
+        if (node != null && node.isNumber()) {
+            min = node.asInt();
+        }
+        node = json.get("max");
+        if (node != null) {
+            if (node.isNumber()) {
+                max = node.asInt();
+            } else if (node.isTextual() && "unlimited".equals(node.asText())) {
+                max = Integer.MAX_VALUE;
+            }
+        }
+        return new AtomicColumnType(baseType, min, max);
+    }
+
+    /**
+     * Create KeyValuedColumnType entity.
+     * @param json JsonNode
+     * @return KeyValuedColumnType entity
+     */
+    private static KeyValuedColumnType createKeyValuedColumnType(JsonNode json) {
+        BaseType keyType = BaseTypeFactory.getBaseTypeFromJson(json, Type.KEY.type());
+        BaseType valueType = BaseTypeFactory.getBaseTypeFromJson(json, Type.VALUE.type());
+        int min = 1;
+        int max = 1;
+        JsonNode node = json.get("min");
+        if (node != null && node.isNumber()) {
+            min = node.asInt();
+        }
+        node = json.get("max");
+        if (node != null) {
+            if (node.isNumber()) {
+                max = node.asInt();
+            } else if (node.isTextual() && "unlimited".equals(node.asText())) {
+                max = Integer.MAX_VALUE;
+            }
+        }
+        return new KeyValuedColumnType(keyType, valueType, min, max);
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java
index f2e5150..2bfe2e7 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/OvsdbTable.java
@@ -1,41 +1,41 @@
-/*
- * 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.table;
-
-/**
- * Ovsdb table name. Refer to RFC7047's Section 9.2.
- */
-public enum OvsdbTable {
-    INTERFACE("Interface"), BRIDGE("Bridge"), CONTROLLER("Controller"),
-    PORT("Port"), OPENVSWITCH("Open_vSwitch"), FLWTABLE("Flow_Table"),
-    QOS("Qos"), QUEUE("Queue"), MIRROR("Mirror"), MANAGER("Manager"),
-    NETFLOW("NetFlow"), SSL("SSL"), SFLOW("sFlow"), IPFIX("IPFIX"),
-    FLOWSAMPLECOLLECTORSET("Flow_Sample_Collector_Set");
-
-    private final String tableName;
-
-    private OvsdbTable(String tableName) {
-        this.tableName = tableName;
-    }
-
-    /**
-     * Returns the table name for OvsdbTable.
-     * @return the table name
-     */
-    public String tableName() {
-        return tableName;
-    }
-}
+/*
+ * 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.table;
+
+/**
+ * Ovsdb table name. Refer to RFC7047's Section 9.2.
+ */
+public enum OvsdbTable {
+    INTERFACE("Interface"), BRIDGE("Bridge"), CONTROLLER("Controller"),
+    PORT("Port"), OPENVSWITCH("Open_vSwitch"), FLWTABLE("Flow_Table"),
+    QOS("Qos"), QUEUE("Queue"), MIRROR("Mirror"), MANAGER("Manager"),
+    NETFLOW("NetFlow"), SSL("SSL"), SFLOW("sFlow"), IPFIX("IPFIX"),
+    FLOWSAMPLECOLLECTORSET("Flow_Sample_Collector_Set");
+
+    private final String tableName;
+
+    private OvsdbTable(String tableName) {
+        this.tableName = tableName;
+    }
+
+    /**
+     * Returns the table name for OvsdbTable.
+     * @return the table name
+     */
+    public String tableName() {
+        return tableName;
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java
index f308266..8b35642 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/table/VersionNum.java
@@ -1,47 +1,47 @@
-/*
- * 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.table;
-
-/**
- * The version number of tables and columns.
- */
-public enum VersionNum {
-    VERSION100("1.0.0"), VERSION102("1.0.2"), VERSION103("1.0.3"),
-    VERSION104("1.0.4"), VERSION106("1.0.6"), VERSION110("1.1.0"),
-    VERSION130("1.3.0"), VERSION200("2.0.0"), VERSION300("3.0.0"),
-    VERSION330("3.3.0"), VERSION350("3.5.0"), VERSION400("4.0.0"),
-    VERSION510("5.1.0"), VERSION520("5.2.0"), VERSION600("6.0.0"),
-    VERSION610("6.1.0"), VERSION620("6.2.0"), VERSION630("6.3.0"),
-    VERSION640("6.4.0"), VERSION650("6.5.0"), VERSION660("6.6.0"),
-    VERSION670("6.7.0"), VERSION680("6.8.0"), VERSION690("6.9.0"),
-    VERSION6100("6.10.0"), VERSION6111("6.11.1"), VERSION710("7.1.0"),
-    VERSION720("7.2.0"), VERSION721("7.2.1"), VERSION730("7.3.0"),
-    VERSION740("7.4.0"), VERSION750("7.5.0"), VERSION770("7.7.0");
-
-    private final String versionNum;
-
-    private VersionNum(String versionNum) {
-        this.versionNum = versionNum;
-    }
-
-    /**
-     * Returns the version number for VersionNum.
-     * @return the version number
-     */
-    public String versionNum() {
-        return versionNum;
-    }
-}
+/*
+ * 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.table;
+
+/**
+ * The version number of tables and columns.
+ */
+public enum VersionNum {
+    VERSION100("1.0.0"), VERSION102("1.0.2"), VERSION103("1.0.3"),
+    VERSION104("1.0.4"), VERSION106("1.0.6"), VERSION110("1.1.0"),
+    VERSION130("1.3.0"), VERSION200("2.0.0"), VERSION300("3.0.0"),
+    VERSION330("3.3.0"), VERSION350("3.5.0"), VERSION400("4.0.0"),
+    VERSION510("5.1.0"), VERSION520("5.2.0"), VERSION600("6.0.0"),
+    VERSION610("6.1.0"), VERSION620("6.2.0"), VERSION630("6.3.0"),
+    VERSION640("6.4.0"), VERSION650("6.5.0"), VERSION660("6.6.0"),
+    VERSION670("6.7.0"), VERSION680("6.8.0"), VERSION690("6.9.0"),
+    VERSION6100("6.10.0"), VERSION6111("6.11.1"), VERSION710("7.1.0"),
+    VERSION720("7.2.0"), VERSION721("7.2.1"), VERSION730("7.3.0"),
+    VERSION740("7.4.0"), VERSION750("7.5.0"), VERSION770("7.7.0");
+
+    private final String versionNum;
+
+    private VersionNum(String versionNum) {
+        this.versionNum = versionNum;
+    }
+
+    /**
+     * Returns the version number for VersionNum.
+     * @return the version number
+     */
+    public String versionNum() {
+        return versionNum;
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java
index a65ed12..ed7c9e6 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/AbstractOvsdbTableService.java
@@ -1,284 +1,284 @@
-/*
- * 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.tableservice;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-import org.onosproject.ovsdb.rfc.error.ColumnSchemaNotFoundException;
-import org.onosproject.ovsdb.rfc.error.TableSchemaNotFoundException;
-import org.onosproject.ovsdb.rfc.error.VersionMismatchException;
-import org.onosproject.ovsdb.rfc.notation.Column;
-import org.onosproject.ovsdb.rfc.notation.Row;
-import org.onosproject.ovsdb.rfc.notation.UUID;
-import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
-import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-import org.onosproject.ovsdb.rfc.table.OvsdbTable;
-import org.onosproject.ovsdb.rfc.table.VersionNum;
-import org.onosproject.ovsdb.rfc.utils.VersionUtil;
-
-/**
- * Representation of conversion between Ovsdb table and Row.
- */
-public abstract class AbstractOvsdbTableService implements OvsdbTableService {
-
-    private final DatabaseSchema dbSchema;
-    private final Row row;
-    private final TableDescription tableDesc;
-
-    /**
-     * Constructs a AbstractOvsdbTableService object.
-     * @param dbSchema DatabaseSchema entity
-     * @param row Row entity
-     * @param table table name
-     * @param formVersion the initial version
-     */
-    public AbstractOvsdbTableService(DatabaseSchema dbSchema, Row row, OvsdbTable table,
-                                     VersionNum formVersion) {
-        checkNotNull(dbSchema, "database schema cannot be null");
-        checkNotNull(row, "row cannot be null");
-        checkNotNull(table, "table cannot be null");
-        checkNotNull(formVersion, "the initial version cannot be null");
-        this.dbSchema = dbSchema;
-        row.setTableName(table.tableName());
-        this.row = row;
-        TableDescription tableDesc = new TableDescription(table, formVersion);
-        this.tableDesc = tableDesc;
-    }
-
-    /**
-     * Check whether the parameter of dbSchema is valid and check whether the
-     * table is existent in Database Schema.
-     */
-    private boolean isValid() {
-        if (dbSchema == null) {
-            return false;
-        }
-        if (!dbSchema.name().equalsIgnoreCase(tableDesc.database())) {
-            return false;
-        }
-        checkTableSchemaVersion();
-        return true;
-    }
-
-    /**
-     * Check the table version.
-     */
-    private void checkTableSchemaVersion() {
-        String fromVersion = tableDesc.fromVersion();
-        String untilVersion = tableDesc.untilVersion();
-        String schemaVersion = dbSchema.version();
-        checkVersion(schemaVersion, fromVersion, untilVersion);
-    }
-
-    /**
-     * Check the column version.
-     * @param columnDesc ColumnDescription entity
-     */
-    private void checkColumnSchemaVersion(ColumnDescription columnDesc) {
-        String fromVersion = columnDesc.fromVersion();
-        String untilVersion = columnDesc.untilVersion();
-        String schemaVersion = dbSchema.version();
-        checkVersion(schemaVersion, fromVersion, untilVersion);
-    }
-
-    /**
-     * Check whether the DatabaseSchema version between the initial version and
-     * the end of the version.
-     * @param schemaVersion DatabaseSchema version
-     * @param fromVersion The initial version
-     * @param untilVersion The end of the version
-     * @throws VersionMismatchException this is a version mismatch exception
-     */
-    private void checkVersion(String schemaVersion, String fromVersion, String untilVersion) {
-        VersionUtil.versionMatch(fromVersion);
-        VersionUtil.versionMatch(untilVersion);
-        if (!fromVersion.equals(VersionUtil.DEFAULT_VERSION_STRING)) {
-            if (VersionUtil.versionCompare(schemaVersion, fromVersion) < 0) {
-                String message = VersionMismatchException.createFromMessage(schemaVersion,
-                                                                            fromVersion);
-                throw new VersionMismatchException(message);
-            }
-        }
-        if (!untilVersion.equals(VersionUtil.DEFAULT_VERSION_STRING)) {
-            if (VersionUtil.versionCompare(untilVersion, schemaVersion) < 0) {
-                String message = VersionMismatchException.createToMessage(schemaVersion,
-                                                                          untilVersion);
-                throw new VersionMismatchException(message);
-            }
-        }
-    }
-
-    /**
-     * Returns TableSchema from dbSchema by table name.
-     * @return TableSchema
-     */
-    private TableSchema getTableSchema() {
-        String tableName = tableDesc.name();
-        return dbSchema.getTableSchema(tableName);
-    }
-
-    /**
-     * Returns ColumnSchema from TableSchema by column name.
-     * @param columnName column name
-     * @return ColumnSchema
-     */
-    private ColumnSchema getColumnSchema(String columnName) {
-        TableSchema tableSchema = getTableSchema();
-        if (tableSchema == null) {
-            String message = TableSchemaNotFoundException.createMessage(tableDesc.name(),
-                                                                        dbSchema.name());
-            throw new TableSchemaNotFoundException(message);
-        }
-        ColumnSchema columnSchema = tableSchema.getColumnSchema(columnName);
-        if (columnSchema == null) {
-            String message = ColumnSchemaNotFoundException.createMessage(columnName,
-                                                                         tableSchema.name());
-            throw new ColumnSchemaNotFoundException(message);
-        }
-        return columnSchema;
-    }
-
-    @Override
-    public Column getColumnHandler(ColumnDescription columnDesc) {
-        if (!isValid()) {
-            return null;
-        }
-        String columnName = columnDesc.name();
-        checkColumnSchemaVersion(columnDesc);
-        ColumnSchema columnSchema = getColumnSchema(columnName);
-        if (row == null) {
-            return null;
-        }
-        return row.getColumn(columnSchema.name());
-    }
-
-    @Override
-    public Object getDataHandler(ColumnDescription columnDesc) {
-        if (!isValid()) {
-            return null;
-        }
-        String columnName = columnDesc.name();
-        checkColumnSchemaVersion(columnDesc);
-        ColumnSchema columnSchema = getColumnSchema(columnName);
-        if (row == null || row.getColumn(columnSchema.name()) == null) {
-            return null;
-        }
-        return row.getColumn(columnSchema.name()).data();
-    }
-
-    @Override
-    public void setDataHandler(ColumnDescription columnDesc, Object obj) {
-        if (!isValid()) {
-            return;
-        }
-        String columnName = columnDesc.name();
-        checkColumnSchemaVersion(columnDesc);
-        ColumnSchema columnSchema = getColumnSchema(columnName);
-        Column column = new Column(columnSchema.name(), obj);
-        row.addColumn(columnName, column);
-    }
-
-    @Override
-    public UUID getTableUuid() {
-        if (!isValid()) {
-            return null;
-        }
-        ColumnDescription columnDesc = new ColumnDescription("_uuid", "getTableUuid");
-        return (UUID) getDataHandler(columnDesc);
-    }
-
-    @Override
-    public Column getTableUuidColumn() {
-        if (!isValid()) {
-            return null;
-        }
-        ColumnDescription columnDesc = new ColumnDescription("_uuid", "getTableUuidColumn");
-        return (Column) getColumnHandler(columnDesc);
-    }
-
-    @Override
-    public UUID getTableVersion() {
-        if (!isValid()) {
-            return null;
-        }
-        ColumnDescription columnDesc = new ColumnDescription("_version", "getTableVersion");
-        return (UUID) getDataHandler(columnDesc);
-    }
-
-    @Override
-    public Column getTableVersionColumn() {
-        if (!isValid()) {
-            return null;
-        }
-        ColumnDescription columnDesc = new ColumnDescription("_version", "getTableVersionColumn");
-        return (Column) getColumnHandler(columnDesc);
-    }
-
-    /**
-     * Get DatabaseSchema entity.
-     * @return DatabaseSchema entity
-     */
-    public DatabaseSchema dbSchema() {
-        return dbSchema;
-    }
-
-    /**
-     * Get Row entity.
-     * @return Row entity
-     */
-    public Row getRow() {
-        if (!isValid()) {
-            return null;
-        }
-        return this.row;
-    }
-
-    /**
-     * Get TableDescription entity.
-     * @return TableDescription entity
-     */
-    public TableDescription tableDesc() {
-        return tableDesc;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(row);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof AbstractOvsdbTableService) {
-            final AbstractOvsdbTableService other = (AbstractOvsdbTableService) obj;
-            return Objects.equals(this.row, other.row);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        TableSchema schema = (TableSchema) getTableSchema();
-        String tableName = schema.name();
-        return toStringHelper(this).add("tableName", tableName).add("row", row).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.ovsdb.rfc.tableservice;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onosproject.ovsdb.rfc.error.ColumnSchemaNotFoundException;
+import org.onosproject.ovsdb.rfc.error.TableSchemaNotFoundException;
+import org.onosproject.ovsdb.rfc.error.VersionMismatchException;
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+import org.onosproject.ovsdb.rfc.table.OvsdbTable;
+import org.onosproject.ovsdb.rfc.table.VersionNum;
+import org.onosproject.ovsdb.rfc.utils.VersionUtil;
+
+/**
+ * Representation of conversion between Ovsdb table and Row.
+ */
+public abstract class AbstractOvsdbTableService implements OvsdbTableService {
+
+    private final DatabaseSchema dbSchema;
+    private final Row row;
+    private final TableDescription tableDesc;
+
+    /**
+     * Constructs a AbstractOvsdbTableService object.
+     * @param dbSchema DatabaseSchema entity
+     * @param row Row entity
+     * @param table table name
+     * @param formVersion the initial version
+     */
+    public AbstractOvsdbTableService(DatabaseSchema dbSchema, Row row, OvsdbTable table,
+                                     VersionNum formVersion) {
+        checkNotNull(dbSchema, "database schema cannot be null");
+        checkNotNull(row, "row cannot be null");
+        checkNotNull(table, "table cannot be null");
+        checkNotNull(formVersion, "the initial version cannot be null");
+        this.dbSchema = dbSchema;
+        row.setTableName(table.tableName());
+        this.row = row;
+        TableDescription tableDesc = new TableDescription(table, formVersion);
+        this.tableDesc = tableDesc;
+    }
+
+    /**
+     * Check whether the parameter of dbSchema is valid and check whether the
+     * table is existent in Database Schema.
+     */
+    private boolean isValid() {
+        if (dbSchema == null) {
+            return false;
+        }
+        if (!dbSchema.name().equalsIgnoreCase(tableDesc.database())) {
+            return false;
+        }
+        checkTableSchemaVersion();
+        return true;
+    }
+
+    /**
+     * Check the table version.
+     */
+    private void checkTableSchemaVersion() {
+        String fromVersion = tableDesc.fromVersion();
+        String untilVersion = tableDesc.untilVersion();
+        String schemaVersion = dbSchema.version();
+        checkVersion(schemaVersion, fromVersion, untilVersion);
+    }
+
+    /**
+     * Check the column version.
+     * @param columnDesc ColumnDescription entity
+     */
+    private void checkColumnSchemaVersion(ColumnDescription columnDesc) {
+        String fromVersion = columnDesc.fromVersion();
+        String untilVersion = columnDesc.untilVersion();
+        String schemaVersion = dbSchema.version();
+        checkVersion(schemaVersion, fromVersion, untilVersion);
+    }
+
+    /**
+     * Check whether the DatabaseSchema version between the initial version and
+     * the end of the version.
+     * @param schemaVersion DatabaseSchema version
+     * @param fromVersion The initial version
+     * @param untilVersion The end of the version
+     * @throws VersionMismatchException this is a version mismatch exception
+     */
+    private void checkVersion(String schemaVersion, String fromVersion, String untilVersion) {
+        VersionUtil.versionMatch(fromVersion);
+        VersionUtil.versionMatch(untilVersion);
+        if (!fromVersion.equals(VersionUtil.DEFAULT_VERSION_STRING)) {
+            if (VersionUtil.versionCompare(schemaVersion, fromVersion) < 0) {
+                String message = VersionMismatchException.createFromMessage(schemaVersion,
+                                                                            fromVersion);
+                throw new VersionMismatchException(message);
+            }
+        }
+        if (!untilVersion.equals(VersionUtil.DEFAULT_VERSION_STRING)) {
+            if (VersionUtil.versionCompare(untilVersion, schemaVersion) < 0) {
+                String message = VersionMismatchException.createToMessage(schemaVersion,
+                                                                          untilVersion);
+                throw new VersionMismatchException(message);
+            }
+        }
+    }
+
+    /**
+     * Returns TableSchema from dbSchema by table name.
+     * @return TableSchema
+     */
+    private TableSchema getTableSchema() {
+        String tableName = tableDesc.name();
+        return dbSchema.getTableSchema(tableName);
+    }
+
+    /**
+     * Returns ColumnSchema from TableSchema by column name.
+     * @param columnName column name
+     * @return ColumnSchema
+     */
+    private ColumnSchema getColumnSchema(String columnName) {
+        TableSchema tableSchema = getTableSchema();
+        if (tableSchema == null) {
+            String message = TableSchemaNotFoundException.createMessage(tableDesc.name(),
+                                                                        dbSchema.name());
+            throw new TableSchemaNotFoundException(message);
+        }
+        ColumnSchema columnSchema = tableSchema.getColumnSchema(columnName);
+        if (columnSchema == null) {
+            String message = ColumnSchemaNotFoundException.createMessage(columnName,
+                                                                         tableSchema.name());
+            throw new ColumnSchemaNotFoundException(message);
+        }
+        return columnSchema;
+    }
+
+    @Override
+    public Column getColumnHandler(ColumnDescription columnDesc) {
+        if (!isValid()) {
+            return null;
+        }
+        String columnName = columnDesc.name();
+        checkColumnSchemaVersion(columnDesc);
+        ColumnSchema columnSchema = getColumnSchema(columnName);
+        if (row == null) {
+            return null;
+        }
+        return row.getColumn(columnSchema.name());
+    }
+
+    @Override
+    public Object getDataHandler(ColumnDescription columnDesc) {
+        if (!isValid()) {
+            return null;
+        }
+        String columnName = columnDesc.name();
+        checkColumnSchemaVersion(columnDesc);
+        ColumnSchema columnSchema = getColumnSchema(columnName);
+        if (row == null || row.getColumn(columnSchema.name()) == null) {
+            return null;
+        }
+        return row.getColumn(columnSchema.name()).data();
+    }
+
+    @Override
+    public void setDataHandler(ColumnDescription columnDesc, Object obj) {
+        if (!isValid()) {
+            return;
+        }
+        String columnName = columnDesc.name();
+        checkColumnSchemaVersion(columnDesc);
+        ColumnSchema columnSchema = getColumnSchema(columnName);
+        Column column = new Column(columnSchema.name(), obj);
+        row.addColumn(columnName, column);
+    }
+
+    @Override
+    public UUID getTableUuid() {
+        if (!isValid()) {
+            return null;
+        }
+        ColumnDescription columnDesc = new ColumnDescription("_uuid", "getTableUuid");
+        return (UUID) getDataHandler(columnDesc);
+    }
+
+    @Override
+    public Column getTableUuidColumn() {
+        if (!isValid()) {
+            return null;
+        }
+        ColumnDescription columnDesc = new ColumnDescription("_uuid", "getTableUuidColumn");
+        return (Column) getColumnHandler(columnDesc);
+    }
+
+    @Override
+    public UUID getTableVersion() {
+        if (!isValid()) {
+            return null;
+        }
+        ColumnDescription columnDesc = new ColumnDescription("_version", "getTableVersion");
+        return (UUID) getDataHandler(columnDesc);
+    }
+
+    @Override
+    public Column getTableVersionColumn() {
+        if (!isValid()) {
+            return null;
+        }
+        ColumnDescription columnDesc = new ColumnDescription("_version", "getTableVersionColumn");
+        return (Column) getColumnHandler(columnDesc);
+    }
+
+    /**
+     * Get DatabaseSchema entity.
+     * @return DatabaseSchema entity
+     */
+    public DatabaseSchema dbSchema() {
+        return dbSchema;
+    }
+
+    /**
+     * Get Row entity.
+     * @return Row entity
+     */
+    public Row getRow() {
+        if (!isValid()) {
+            return null;
+        }
+        return this.row;
+    }
+
+    /**
+     * Get TableDescription entity.
+     * @return TableDescription entity
+     */
+    public TableDescription tableDesc() {
+        return tableDesc;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(row);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof AbstractOvsdbTableService) {
+            final AbstractOvsdbTableService other = (AbstractOvsdbTableService) obj;
+            return Objects.equals(this.row, other.row);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        TableSchema schema = (TableSchema) getTableSchema();
+        String tableName = schema.name();
+        return toStringHelper(this).add("tableName", tableName).add("row", row).toString();
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java
index 1ce2870..58b656e 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/tableservice/OvsdbTableService.java
@@ -1,70 +1,70 @@
-/*
- * 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.tableservice;
-
-import org.onosproject.ovsdb.rfc.notation.Column;
-import org.onosproject.ovsdb.rfc.notation.UUID;
-
-/**
- * Representation of conversion between Ovsdb table and Row.
- */
-public interface OvsdbTableService {
-
-    /**
-     * Get Column from row.
-     * @param columndesc Column description
-     * @return Column
-     */
-    public Column getColumnHandler(ColumnDescription columndesc);
-
-    /**
-     * Get Data from row.
-     * @param columndesc Column description
-     * @return Object column data
-     */
-    public Object getDataHandler(ColumnDescription columndesc);
-
-    /**
-     * Set column data of row.
-     * @param columndesc Column description
-     * @param obj column data
-     */
-    public void setDataHandler(ColumnDescription columndesc, Object obj);
-
-    /**
-     * Returns UUID which column name is _uuid.
-     * @return UUID
-     */
-    public UUID getTableUuid();
-
-    /**
-     * Returns UUID Column which column name is _uuid.
-     * @return UUID Column
-     */
-    public Column getTableUuidColumn();
-
-    /**
-     * Returns UUID which column name is _version.
-     * @return UUID
-     */
-    public UUID getTableVersion();
-
-    /**
-     * Returns UUID Column which column name is _version.
-     * @return UUID Column
-     */
-    public Column getTableVersionColumn();
-}
+/*
+ * 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.tableservice;
+
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+
+/**
+ * Representation of conversion between Ovsdb table and Row.
+ */
+public interface OvsdbTableService {
+
+    /**
+     * Get Column from row.
+     * @param columndesc Column description
+     * @return Column
+     */
+    public Column getColumnHandler(ColumnDescription columndesc);
+
+    /**
+     * Get Data from row.
+     * @param columndesc Column description
+     * @return Object column data
+     */
+    public Object getDataHandler(ColumnDescription columndesc);
+
+    /**
+     * Set column data of row.
+     * @param columndesc Column description
+     * @param obj column data
+     */
+    public void setDataHandler(ColumnDescription columndesc, Object obj);
+
+    /**
+     * Returns UUID which column name is _uuid.
+     * @return UUID
+     */
+    public UUID getTableUuid();
+
+    /**
+     * Returns UUID Column which column name is _uuid.
+     * @return UUID Column
+     */
+    public Column getTableUuidColumn();
+
+    /**
+     * Returns UUID which column name is _version.
+     * @return UUID
+     */
+    public UUID getTableVersion();
+
+    /**
+     * Returns UUID Column which column name is _version.
+     * @return UUID Column
+     */
+    public Column getTableVersionColumn();
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java
index 7283d8e..5d06354 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/FromJsonUtil.java
@@ -1,320 +1,320 @@
-/*
- * 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 java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.onosproject.ovsdb.rfc.error.AbnormalJsonNodeException;
-import org.onosproject.ovsdb.rfc.error.UnsupportedException;
-import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
-import org.onosproject.ovsdb.rfc.jsonrpc.JsonRpcResponse;
-import org.onosproject.ovsdb.rfc.message.OperationResult;
-import org.onosproject.ovsdb.rfc.message.RowUpdate;
-import org.onosproject.ovsdb.rfc.message.TableUpdate;
-import org.onosproject.ovsdb.rfc.message.TableUpdates;
-import org.onosproject.ovsdb.rfc.message.UpdateNotification;
-import org.onosproject.ovsdb.rfc.notation.Column;
-import org.onosproject.ovsdb.rfc.notation.Row;
-import org.onosproject.ovsdb.rfc.notation.UUID;
-import org.onosproject.ovsdb.rfc.operations.Operation;
-import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
-import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-import org.onosproject.ovsdb.rfc.schema.type.ColumnTypeFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-/**
- * JsonNode utility class. convert JsonNode into Object.
- */
-public final class FromJsonUtil {
-
-    private static final Logger log = LoggerFactory.getLogger(FromJsonUtil.class);
-
-    /**
-     * Constructs a FromJsonUtil object. Utility classes should not have a
-     * public or default constructor, otherwise IDE will compile unsuccessfully.
-     * This class should not be instantiated.
-     */
-    private FromJsonUtil() {
-    }
-
-    /**
-     * Verify whether the jsonNode is normal.
-     * @param jsonNode JsonNode
-     * @param nodeStr the node name of JsonNode
-     */
-    private static void validateJsonNode(JsonNode jsonNode, String nodeStr) {
-        if (!jsonNode.isObject() || !jsonNode.has(nodeStr)) {
-            String message = "Abnormal DatabaseSchema JsonNode, it should contain " + nodeStr
-                    + " node but was not found";
-            throw new AbnormalJsonNodeException(message);
-        }
-    }
-
-    /**
-     * convert JsonNode into DatabaseSchema.
-     * @param dbName database name
-     * @param dbJson the JsonNode of get_schema result
-     * @return DatabaseSchema
-     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
-     */
-    public static DatabaseSchema jsonNodeToDbSchema(String dbName, JsonNode dbJson) {
-        validateJsonNode(dbJson, "tables");
-        validateJsonNode(dbJson, "version");
-        String dbVersion = dbJson.get("version").asText();
-        Map<String, TableSchema> tables = new HashMap<>();
-        Iterator<Map.Entry<String, JsonNode>> tablesIter = dbJson.get("tables").fields();
-        while (tablesIter.hasNext()) {
-            Map.Entry<String, JsonNode> table = tablesIter.next();
-            tables.put(table.getKey(), jsonNodeToTableSchema(table.getKey(), table.getValue()));
-        }
-        return new DatabaseSchema(dbName, dbVersion, tables);
-    }
-
-    /**
-     * convert JsonNode into TableSchema.
-     * @param tableName table name
-     * @param tableJson table JsonNode
-     * @return TableSchema
-     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
-     */
-    private static TableSchema jsonNodeToTableSchema(String tableName, JsonNode tableJson) {
-        validateJsonNode(tableJson, "columns");
-        Map<String, ColumnSchema> columns = new HashMap<>();
-        Iterator<Map.Entry<String, JsonNode>> columnsIter = tableJson.get("columns").fields();
-        while (columnsIter.hasNext()) {
-            Map.Entry<String, JsonNode> column = columnsIter.next();
-            columns.put(column.getKey(), jsonNodeToColumnSchema(column.getKey(), column.getValue()));
-        }
-        return new TableSchema(tableName, columns);
-    }
-
-    /**
-     * convert JsonNode into ColumnSchema.
-     * @param name column name
-     * @param columnJson column JsonNode
-     * @return ColumnSchema
-     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
-     */
-    private static ColumnSchema jsonNodeToColumnSchema(String name, JsonNode columnJson) {
-        validateJsonNode(columnJson, "type");
-        return new ColumnSchema(name, ColumnTypeFactory.getColumnTypeFromJson(columnJson
-                .get("type")));
-    }
-
-    /**
-     * convert JsonNode into the returnType of methods in OvsdbRPC class.
-     * @param resultJsonNode the result JsonNode
-     * @param methodName the method name of methods in OvsdbRPC class
-     * @param objectMapper ObjectMapper entity
-     * @return Object
-     * @throws UnsupportedException this is an unsupported exception
-     */
-    private static Object convertResultType(JsonNode resultJsonNode, String methodName,
-                                            ObjectMapper objectMapper) {
-        switch (methodName) {
-        case "getSchema":
-        case "monitor":
-            return resultJsonNode;
-        case "echo":
-        case "listDbs":
-            return objectMapper.convertValue(resultJsonNode, objectMapper.getTypeFactory()
-                    .constructParametricType(List.class, String.class));
-        case "transact":
-            return objectMapper.convertValue(resultJsonNode, objectMapper.getTypeFactory()
-                    .constructParametricType(List.class, JsonNode.class));
-        default:
-            throw new UnsupportedException("does not support this rpc method" + methodName);
-        }
-    }
-
-    /**
-     * convert JsonNode into the returnType of methods in OvsdbRPC class.
-     * @param jsonNode the result JsonNode
-     * @param methodName the method name of methods in OvsdbRPC class
-     * @return Object
-     */
-    public static Object jsonResultParser(JsonNode jsonNode, String methodName) {
-        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
-        JsonNode error = jsonNode.get("error");
-        if (error != null && !error.isNull()) {
-            log.error("jsonRpcResponse error : {}", error.toString());
-        }
-        JsonNode resultJsonNode = jsonNode.get("result");
-        Object result = convertResultType(resultJsonNode, methodName, objectMapper);
-        return result;
-    }
-
-    /**
-     * When monitor the ovsdb tables, if a table update, ovs send update
-     * notification, then call callback function.
-     * @param jsonNode the result JsonNode
-     * @param callback the callback function
-     * @throws UnsupportedException this is an unsupported exception
-     */
-    public static void jsonCallbackRequestParser(JsonNode jsonNode, Callback callback) {
-        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
-        JsonNode params = jsonNode.get("params");
-        Object param = null;
-        String methodName = jsonNode.get("method").asText();
-        switch (methodName) {
-        case "update":
-            param = objectMapper.convertValue(params, UpdateNotification.class);
-            callback.update((UpdateNotification) param);
-            break;
-        default:
-            throw new UnsupportedException("does not support this callback method: " + methodName);
-        }
-    }
-
-    /**
-     * Ovs send echo request to keep the heart, need we return echo result.
-     * @param jsonNode the result JsonNode
-     * @return JsonRpcResponse String
-     */
-    public static String getEchoRequestStr(JsonNode jsonNode) {
-        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
-        String str = null;
-        if (jsonNode.get("method").asText().equals("echo")) {
-            JsonRpcResponse response = new JsonRpcResponse(jsonNode.get("id").asText());
-            try {
-                str = objectMapper.writeValueAsString(response);
-            } catch (JsonProcessingException e) {
-                log.error("JsonProcessingException while converting JsonNode into string: ", e);
-            }
-        }
-        return str;
-    }
-
-    /**
-     * Convert the List of Operation result into List of OperationResult .
-     * @param input the List of JsonNode
-     * @param operations the List of Operation
-     * @return the List of OperationResult
-     */
-    public static List<OperationResult> jsonNodeToOperationResult(List<JsonNode> input,
-                                                                  List<Operation> operations) {
-        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper(false);
-        List<OperationResult> operationResults = new ArrayList<OperationResult>();
-        for (int i = 0; i < input.size(); i++) {
-            JsonNode jsonNode = input.get(i);
-            Operation operation = operations.get(i);
-            if (jsonNode != null && jsonNode.size() > 0) {
-                if (i >= operations.size() || operation.getOp() != "select") {
-                    OperationResult or = objectMapper.convertValue(jsonNode, OperationResult.class);
-                    operationResults.add(or);
-                } else {
-                    List<Row> rows = createRows(operation.getTableSchema(), jsonNode);
-                    OperationResult or = new OperationResult(rows);
-                    operationResults.add(or);
-                }
-            }
-        }
-        return operationResults;
-    }
-
-    /**
-     * Convert Operation JsonNode into Rows.
-     * @param tableSchema TableSchema entity
-     * @param rowsNode JsonNode
-     * @return ArrayList<Row> the List of Row
-     */
-    private static ArrayList<Row> createRows(TableSchema tableSchema, JsonNode rowsNode) {
-        validateJsonNode(rowsNode, "rows");
-        ArrayList<Row> rows = Lists.newArrayList();
-        for (JsonNode rowNode : rowsNode.get("rows")) {
-            rows.add(createRow(tableSchema, rowNode));
-        }
-        return rows;
-    }
-
-    /**
-     * convert the params of Update Notification into TableUpdates.
-     * @param updatesJson the params of Update Notification
-     * @param dbSchema DatabaseSchema entity
-     * @return TableUpdates
-     */
-    public static TableUpdates jsonNodeToTableUpdates(JsonNode updatesJson, DatabaseSchema dbSchema) {
-        Map<String, TableUpdate> tableUpdateMap = Maps.newHashMap();
-        Iterator<Map.Entry<String, JsonNode>> tableUpdatesItr = updatesJson.fields();
-        while (tableUpdatesItr.hasNext()) {
-            Map.Entry<String, JsonNode> entry = tableUpdatesItr.next();
-            TableSchema tableSchema = dbSchema.getTableSchema(entry.getKey());
-            TableUpdate tableUpdate = jsonNodeToTableUpdate(tableSchema, entry.getValue());
-            tableUpdateMap.put(entry.getKey(), tableUpdate);
-        }
-        return TableUpdates.tableUpdates(tableUpdateMap);
-    }
-
-    /**
-     * convert the params of Update Notification into TableUpdate.
-     * @param tableSchema TableSchema entity
-     * @param updateJson the table-update in params of Update Notification
-     * @return TableUpdate
-     */
-    public static TableUpdate jsonNodeToTableUpdate(TableSchema tableSchema, JsonNode updateJson) {
-        Map<UUID, RowUpdate> rows = Maps.newHashMap();
-        Iterator<Map.Entry<String, JsonNode>> tableUpdateItr = updateJson.fields();
-        while (tableUpdateItr.hasNext()) {
-            Map.Entry<String, JsonNode> oldNewRow = tableUpdateItr.next();
-            String uuidStr = oldNewRow.getKey();
-            UUID uuid = UUID.uuid(uuidStr);
-            JsonNode newR = oldNewRow.getValue().get("new");
-            JsonNode oldR = oldNewRow.getValue().get("old");
-            Row newRow = newR != null ? createRow(tableSchema, newR) : null;
-            Row oldRow = oldR != null ? createRow(tableSchema, oldR) : null;
-            RowUpdate rowUpdate = new RowUpdate(uuid, oldRow, newRow);
-            rows.put(uuid, rowUpdate);
-        }
-        return TableUpdate.tableUpdate(rows);
-    }
-
-    /**
-     * Convert Operation JsonNode into Row.
-     * @param tableSchema TableSchema entity
-     * @param rowNode JsonNode
-     * @return Row
-     */
-    private static Row createRow(TableSchema tableSchema, JsonNode rowNode) {
-        if (tableSchema == null) {
-            return null;
-        }
-        Map<String, Column> columns = Maps.newHashMap();
-        Iterator<Map.Entry<String, JsonNode>> rowIter = rowNode.fields();
-        while (rowIter.hasNext()) {
-            Map.Entry<String, JsonNode> next = rowIter.next();
-            ColumnSchema columnSchema = tableSchema.getColumnSchema(next.getKey());
-            if (columnSchema != null) {
-                String columnName = columnSchema.name();
-                Object obj = TransValueUtil.getValueFromJson(next.getValue(), columnSchema.type());
-                columns.put(columnName, new Column(columnName, obj));
-            }
-        }
-        return new Row(tableSchema.name(), columns);
-    }
-
-}
+/*
+ * 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 java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.onosproject.ovsdb.rfc.error.AbnormalJsonNodeException;
+import org.onosproject.ovsdb.rfc.error.UnsupportedException;
+import org.onosproject.ovsdb.rfc.jsonrpc.Callback;
+import org.onosproject.ovsdb.rfc.jsonrpc.JsonRpcResponse;
+import org.onosproject.ovsdb.rfc.message.OperationResult;
+import org.onosproject.ovsdb.rfc.message.RowUpdate;
+import org.onosproject.ovsdb.rfc.message.TableUpdate;
+import org.onosproject.ovsdb.rfc.message.TableUpdates;
+import org.onosproject.ovsdb.rfc.message.UpdateNotification;
+import org.onosproject.ovsdb.rfc.notation.Column;
+import org.onosproject.ovsdb.rfc.notation.Row;
+import org.onosproject.ovsdb.rfc.notation.UUID;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.schema.ColumnSchema;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+import org.onosproject.ovsdb.rfc.schema.type.ColumnTypeFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * JsonNode utility class. convert JsonNode into Object.
+ */
+public final class FromJsonUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(FromJsonUtil.class);
+
+    /**
+     * Constructs a FromJsonUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully.
+     * This class should not be instantiated.
+     */
+    private FromJsonUtil() {
+    }
+
+    /**
+     * Verify whether the jsonNode is normal.
+     * @param jsonNode JsonNode
+     * @param nodeStr the node name of JsonNode
+     */
+    private static void validateJsonNode(JsonNode jsonNode, String nodeStr) {
+        if (!jsonNode.isObject() || !jsonNode.has(nodeStr)) {
+            String message = "Abnormal DatabaseSchema JsonNode, it should contain " + nodeStr
+                    + " node but was not found";
+            throw new AbnormalJsonNodeException(message);
+        }
+    }
+
+    /**
+     * convert JsonNode into DatabaseSchema.
+     * @param dbName database name
+     * @param dbJson the JsonNode of get_schema result
+     * @return DatabaseSchema
+     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
+     */
+    public static DatabaseSchema jsonNodeToDbSchema(String dbName, JsonNode dbJson) {
+        validateJsonNode(dbJson, "tables");
+        validateJsonNode(dbJson, "version");
+        String dbVersion = dbJson.get("version").asText();
+        Map<String, TableSchema> tables = new HashMap<>();
+        Iterator<Map.Entry<String, JsonNode>> tablesIter = dbJson.get("tables").fields();
+        while (tablesIter.hasNext()) {
+            Map.Entry<String, JsonNode> table = tablesIter.next();
+            tables.put(table.getKey(), jsonNodeToTableSchema(table.getKey(), table.getValue()));
+        }
+        return new DatabaseSchema(dbName, dbVersion, tables);
+    }
+
+    /**
+     * convert JsonNode into TableSchema.
+     * @param tableName table name
+     * @param tableJson table JsonNode
+     * @return TableSchema
+     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
+     */
+    private static TableSchema jsonNodeToTableSchema(String tableName, JsonNode tableJson) {
+        validateJsonNode(tableJson, "columns");
+        Map<String, ColumnSchema> columns = new HashMap<>();
+        Iterator<Map.Entry<String, JsonNode>> columnsIter = tableJson.get("columns").fields();
+        while (columnsIter.hasNext()) {
+            Map.Entry<String, JsonNode> column = columnsIter.next();
+            columns.put(column.getKey(), jsonNodeToColumnSchema(column.getKey(), column.getValue()));
+        }
+        return new TableSchema(tableName, columns);
+    }
+
+    /**
+     * convert JsonNode into ColumnSchema.
+     * @param name column name
+     * @param columnJson column JsonNode
+     * @return ColumnSchema
+     * @throws AbnormalJsonNodeException this is an abnormal JsonNode exception
+     */
+    private static ColumnSchema jsonNodeToColumnSchema(String name, JsonNode columnJson) {
+        validateJsonNode(columnJson, "type");
+        return new ColumnSchema(name, ColumnTypeFactory.getColumnTypeFromJson(columnJson
+                .get("type")));
+    }
+
+    /**
+     * convert JsonNode into the returnType of methods in OvsdbRPC class.
+     * @param resultJsonNode the result JsonNode
+     * @param methodName the method name of methods in OvsdbRPC class
+     * @param objectMapper ObjectMapper entity
+     * @return Object
+     * @throws UnsupportedException this is an unsupported exception
+     */
+    private static Object convertResultType(JsonNode resultJsonNode, String methodName,
+                                            ObjectMapper objectMapper) {
+        switch (methodName) {
+        case "getSchema":
+        case "monitor":
+            return resultJsonNode;
+        case "echo":
+        case "listDbs":
+            return objectMapper.convertValue(resultJsonNode, objectMapper.getTypeFactory()
+                    .constructParametricType(List.class, String.class));
+        case "transact":
+            return objectMapper.convertValue(resultJsonNode, objectMapper.getTypeFactory()
+                    .constructParametricType(List.class, JsonNode.class));
+        default:
+            throw new UnsupportedException("does not support this rpc method" + methodName);
+        }
+    }
+
+    /**
+     * convert JsonNode into the returnType of methods in OvsdbRPC class.
+     * @param jsonNode the result JsonNode
+     * @param methodName the method name of methods in OvsdbRPC class
+     * @return Object
+     */
+    public static Object jsonResultParser(JsonNode jsonNode, String methodName) {
+        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
+        JsonNode error = jsonNode.get("error");
+        if (error != null && !error.isNull()) {
+            log.error("jsonRpcResponse error : {}", error.toString());
+        }
+        JsonNode resultJsonNode = jsonNode.get("result");
+        Object result = convertResultType(resultJsonNode, methodName, objectMapper);
+        return result;
+    }
+
+    /**
+     * When monitor the ovsdb tables, if a table update, ovs send update
+     * notification, then call callback function.
+     * @param jsonNode the result JsonNode
+     * @param callback the callback function
+     * @throws UnsupportedException this is an unsupported exception
+     */
+    public static void jsonCallbackRequestParser(JsonNode jsonNode, Callback callback) {
+        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
+        JsonNode params = jsonNode.get("params");
+        Object param = null;
+        String methodName = jsonNode.get("method").asText();
+        switch (methodName) {
+        case "update":
+            param = objectMapper.convertValue(params, UpdateNotification.class);
+            callback.update((UpdateNotification) param);
+            break;
+        default:
+            throw new UnsupportedException("does not support this callback method: " + methodName);
+        }
+    }
+
+    /**
+     * Ovs send echo request to keep the heart, need we return echo result.
+     * @param jsonNode the result JsonNode
+     * @return JsonRpcResponse String
+     */
+    public static String getEchoRequestStr(JsonNode jsonNode) {
+        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper();
+        String str = null;
+        if (jsonNode.get("method").asText().equals("echo")) {
+            JsonRpcResponse response = new JsonRpcResponse(jsonNode.get("id").asText());
+            try {
+                str = objectMapper.writeValueAsString(response);
+            } catch (JsonProcessingException e) {
+                log.error("JsonProcessingException while converting JsonNode into string: ", e);
+            }
+        }
+        return str;
+    }
+
+    /**
+     * Convert the List of Operation result into List of OperationResult .
+     * @param input the List of JsonNode
+     * @param operations the List of Operation
+     * @return the List of OperationResult
+     */
+    public static List<OperationResult> jsonNodeToOperationResult(List<JsonNode> input,
+                                                                  List<Operation> operations) {
+        ObjectMapper objectMapper = ObjectMapperUtil.getObjectMapper(false);
+        List<OperationResult> operationResults = new ArrayList<OperationResult>();
+        for (int i = 0; i < input.size(); i++) {
+            JsonNode jsonNode = input.get(i);
+            Operation operation = operations.get(i);
+            if (jsonNode != null && jsonNode.size() > 0) {
+                if (i >= operations.size() || operation.getOp() != "select") {
+                    OperationResult or = objectMapper.convertValue(jsonNode, OperationResult.class);
+                    operationResults.add(or);
+                } else {
+                    List<Row> rows = createRows(operation.getTableSchema(), jsonNode);
+                    OperationResult or = new OperationResult(rows);
+                    operationResults.add(or);
+                }
+            }
+        }
+        return operationResults;
+    }
+
+    /**
+     * Convert Operation JsonNode into Rows.
+     * @param tableSchema TableSchema entity
+     * @param rowsNode JsonNode
+     * @return ArrayList<Row> the List of Row
+     */
+    private static ArrayList<Row> createRows(TableSchema tableSchema, JsonNode rowsNode) {
+        validateJsonNode(rowsNode, "rows");
+        ArrayList<Row> rows = Lists.newArrayList();
+        for (JsonNode rowNode : rowsNode.get("rows")) {
+            rows.add(createRow(tableSchema, rowNode));
+        }
+        return rows;
+    }
+
+    /**
+     * convert the params of Update Notification into TableUpdates.
+     * @param updatesJson the params of Update Notification
+     * @param dbSchema DatabaseSchema entity
+     * @return TableUpdates
+     */
+    public static TableUpdates jsonNodeToTableUpdates(JsonNode updatesJson, DatabaseSchema dbSchema) {
+        Map<String, TableUpdate> tableUpdateMap = Maps.newHashMap();
+        Iterator<Map.Entry<String, JsonNode>> tableUpdatesItr = updatesJson.fields();
+        while (tableUpdatesItr.hasNext()) {
+            Map.Entry<String, JsonNode> entry = tableUpdatesItr.next();
+            TableSchema tableSchema = dbSchema.getTableSchema(entry.getKey());
+            TableUpdate tableUpdate = jsonNodeToTableUpdate(tableSchema, entry.getValue());
+            tableUpdateMap.put(entry.getKey(), tableUpdate);
+        }
+        return TableUpdates.tableUpdates(tableUpdateMap);
+    }
+
+    /**
+     * convert the params of Update Notification into TableUpdate.
+     * @param tableSchema TableSchema entity
+     * @param updateJson the table-update in params of Update Notification
+     * @return TableUpdate
+     */
+    public static TableUpdate jsonNodeToTableUpdate(TableSchema tableSchema, JsonNode updateJson) {
+        Map<UUID, RowUpdate> rows = Maps.newHashMap();
+        Iterator<Map.Entry<String, JsonNode>> tableUpdateItr = updateJson.fields();
+        while (tableUpdateItr.hasNext()) {
+            Map.Entry<String, JsonNode> oldNewRow = tableUpdateItr.next();
+            String uuidStr = oldNewRow.getKey();
+            UUID uuid = UUID.uuid(uuidStr);
+            JsonNode newR = oldNewRow.getValue().get("new");
+            JsonNode oldR = oldNewRow.getValue().get("old");
+            Row newRow = newR != null ? createRow(tableSchema, newR) : null;
+            Row oldRow = oldR != null ? createRow(tableSchema, oldR) : null;
+            RowUpdate rowUpdate = new RowUpdate(uuid, oldRow, newRow);
+            rows.put(uuid, rowUpdate);
+        }
+        return TableUpdate.tableUpdate(rows);
+    }
+
+    /**
+     * Convert Operation JsonNode into Row.
+     * @param tableSchema TableSchema entity
+     * @param rowNode JsonNode
+     * @return Row
+     */
+    private static Row createRow(TableSchema tableSchema, JsonNode rowNode) {
+        if (tableSchema == null) {
+            return null;
+        }
+        Map<String, Column> columns = Maps.newHashMap();
+        Iterator<Map.Entry<String, JsonNode>> rowIter = rowNode.fields();
+        while (rowIter.hasNext()) {
+            Map.Entry<String, JsonNode> next = rowIter.next();
+            ColumnSchema columnSchema = tableSchema.getColumnSchema(next.getKey());
+            if (columnSchema != null) {
+                String columnName = columnSchema.name();
+                Object obj = TransValueUtil.getValueFromJson(next.getValue(), columnSchema.type());
+                columns.put(columnName, new Column(columnName, obj));
+            }
+        }
+        return new Row(tableSchema.name(), columns);
+    }
+
+}
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.");
+        }
+    }
+
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java
index 5ab2b7a..00e7dbe 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/MutationUtil.java
@@ -1,92 +1,92 @@
-package org.onosproject.ovsdb.rfc.utils;
-
-import org.onosproject.ovsdb.rfc.notation.Mutation;
-import org.onosproject.ovsdb.rfc.notation.Mutation.Mutator;
-
-public final class MutationUtil {
-
-    /**
-     * Constructs a MutationUtil object. Utility classes should not have a
-     * public or default constructor, otherwise IDE will compile unsuccessfully. This
-     * class should not be instantiated.
-     */
-    private MutationUtil() {
-    }
-
-    /**
-     * Returns a Mutation that means += .
-     * @param columnName column name
-     * @param data column value
-     * @return Mutation
-     */
-    public static Mutation sum(String columnName, Object data) {
-        Object value = TransValueUtil.getFormatData(data);
-        return new Mutation(columnName, Mutator.SUM, value);
-    }
-
-    /**
-     * Returns a Mutation that means -= .
-     * @param columnName column name
-     * @param data column value
-     * @return Mutation
-     */
-    public static Mutation difference(String columnName, Object data) {
-        Object value = TransValueUtil.getFormatData(data);
-        return new Mutation(columnName, Mutator.DIFFERENCE, value);
-    }
-
-    /**
-     * Returns a Mutation that means *= .
-     * @param columnName column name
-     * @param data column value
-     * @return Mutation
-     */
-    public static Mutation product(String columnName, Object data) {
-        Object value = TransValueUtil.getFormatData(data);
-        return new Mutation(columnName, Mutator.PRODUCT, value);
-    }
-
-    /**
-     * Returns a Mutation that means /= .
-     * @param columnName column name
-     * @param data column value
-     * @return Mutation
-     */
-    public static Mutation quotient(String columnName, Object data) {
-        Object value = TransValueUtil.getFormatData(data);
-        return new Mutation(columnName, Mutator.QUOTIENT, value);
-    }
-
-    /**
-     * Returns a Mutation that means %= .
-     * @param columnName column name
-     * @param data column value
-     * @return Mutation
-     */
-    public static Mutation remainder(String columnName, Object data) {
-        Object value = TransValueUtil.getFormatData(data);
-        return new Mutation(columnName, Mutator.REMAINDER, value);
-    }
-
-    /**
-     * Returns a Mutation that means insert .
-     * @param columnName column name
-     * @param data column value
-     * @return Mutation
-     */
-    public static Mutation insert(String columnName, Object data) {
-        Object value = TransValueUtil.getFormatData(data);
-        return new Mutation(columnName, Mutator.INSERT, value);
-    }
-
-    /**
-     * Returns a Mutation that means delete .
-     * @param columnName column name
-     * @param data column value
-     * @return Mutation
-     */
-    public static Mutation delete(String columnName, Object data) {
-        Object value = TransValueUtil.getFormatData(data);
-        return new Mutation(columnName, Mutator.DELETE, value);
-    }
-}
+package org.onosproject.ovsdb.rfc.utils;
+
+import org.onosproject.ovsdb.rfc.notation.Mutation;
+import org.onosproject.ovsdb.rfc.notation.Mutation.Mutator;
+
+public final class MutationUtil {
+
+    /**
+     * Constructs a MutationUtil object. Utility classes should not have a
+     * public or default constructor, otherwise IDE will compile unsuccessfully. This
+     * class should not be instantiated.
+     */
+    private MutationUtil() {
+    }
+
+    /**
+     * Returns a Mutation that means += .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation sum(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.SUM, value);
+    }
+
+    /**
+     * Returns a Mutation that means -= .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation difference(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.DIFFERENCE, value);
+    }
+
+    /**
+     * Returns a Mutation that means *= .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation product(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.PRODUCT, value);
+    }
+
+    /**
+     * Returns a Mutation that means /= .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation quotient(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.QUOTIENT, value);
+    }
+
+    /**
+     * Returns a Mutation that means %= .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation remainder(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.REMAINDER, value);
+    }
+
+    /**
+     * Returns a Mutation that means insert .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation insert(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.INSERT, value);
+    }
+
+    /**
+     * Returns a Mutation that means delete .
+     * @param columnName column name
+     * @param data column value
+     * @return Mutation
+     */
+    public static Mutation delete(String columnName, Object data) {
+        Object value = TransValueUtil.getFormatData(data);
+        return new Mutation(columnName, Mutator.DELETE, value);
+    }
+}
diff --git a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java
index fd62581..486b39b 100644
--- a/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java
+++ b/ovsdb/rfc/src/main/java/org/onosproject/ovsdb/rfc/utils/ParamUtil.java
@@ -1,86 +1,86 @@
-/*
- * 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 java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.onosproject.ovsdb.rfc.message.MonitorRequest;
-import org.onosproject.ovsdb.rfc.message.MonitorSelect;
-import org.onosproject.ovsdb.rfc.operations.Operation;
-import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
-import org.onosproject.ovsdb.rfc.schema.TableSchema;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-/**
- * Params utility class. Params of the request object, refer to RFC7047's
- * Section 4.1.
- */
-public final class ParamUtil {
-
-    /**
-     * Constructs a ParamUtil object. Utility classes should not have a public
-     * or default constructor, otherwise IDE will compile unsuccessfully. This
-     * class should not be instantiated.
-     */
-    private ParamUtil() {
-    }
-
-    /**
-     * Returns MonitorRequest, refer to RFC7047's Section 4.1.5.
-     * @param tableSchema entity
-     * @return MonitorRequest
-     */
-    private static MonitorRequest getAllColumnsMonitorRequest(TableSchema tableSchema) {
-        String tableName = tableSchema.name();
-        Set<String> columns = tableSchema.getColumnNames();
-        MonitorSelect select = new MonitorSelect(true, true, true, true);
-        MonitorRequest monitorRequest = new MonitorRequest(tableName, columns, select);
-        return monitorRequest;
-    }
-
-    /**
-     * Returns params of monitor method, refer to RFC7047's Section 4.1.5.
-     * @param monotorId json-value, refer to RFC7047's Section 4.1.5.
-     * @param dbSchema DatabaseSchema entity
-     * @return List of Object, the params of monitor request
-     */
-    public static List<Object> getMonitorParams(String monotorId, DatabaseSchema dbSchema) {
-        Set<String> tables = dbSchema.getTableNames();
-        Map<String, MonitorRequest> mrMap = Maps.newHashMap();
-        for (String tableName : tables) {
-            TableSchema tableSchema = dbSchema.getTableSchema(tableName);
-            MonitorRequest monitorRequest = getAllColumnsMonitorRequest(tableSchema);
-            mrMap.put(tableName, monitorRequest);
-        }
-        return Lists.newArrayList(dbSchema.name(), monotorId, mrMap);
-    }
-
-    /**
-     * Returns params of transact method, refer to RFC7047's Section 4.1.3.
-     * @param dbSchema DatabaseSchema entity
-     * @param operations operation*, refer to RFC7047's Section 4.1.3.
-     * @return List of Object, the params of transact request
-     */
-    public static List<Object> getTransactParams(DatabaseSchema dbSchema, List<Operation> operations) {
-        List<Object> lists = Lists.newArrayList(dbSchema.name());
-        lists.addAll(operations);
-        return lists;
-    }
-}
+/*
+ * 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 java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.ovsdb.rfc.message.MonitorRequest;
+import org.onosproject.ovsdb.rfc.message.MonitorSelect;
+import org.onosproject.ovsdb.rfc.operations.Operation;
+import org.onosproject.ovsdb.rfc.schema.DatabaseSchema;
+import org.onosproject.ovsdb.rfc.schema.TableSchema;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+/**
+ * Params utility class. Params of the request object, refer to RFC7047's
+ * Section 4.1.
+ */
+public final class ParamUtil {
+
+    /**
+     * Constructs a ParamUtil object. Utility classes should not have a public
+     * or default constructor, otherwise IDE will compile unsuccessfully. This
+     * class should not be instantiated.
+     */
+    private ParamUtil() {
+    }
+
+    /**
+     * Returns MonitorRequest, refer to RFC7047's Section 4.1.5.
+     * @param tableSchema entity
+     * @return MonitorRequest
+     */
+    private static MonitorRequest getAllColumnsMonitorRequest(TableSchema tableSchema) {
+        String tableName = tableSchema.name();
+        Set<String> columns = tableSchema.getColumnNames();
+        MonitorSelect select = new MonitorSelect(true, true, true, true);
+        MonitorRequest monitorRequest = new MonitorRequest(tableName, columns, select);
+        return monitorRequest;
+    }
+
+    /**
+     * Returns params of monitor method, refer to RFC7047's Section 4.1.5.
+     * @param monotorId json-value, refer to RFC7047's Section 4.1.5.
+     * @param dbSchema DatabaseSchema entity
+     * @return List of Object, the params of monitor request
+     */
+    public static List<Object> getMonitorParams(String monotorId, DatabaseSchema dbSchema) {
+        Set<String> tables = dbSchema.getTableNames();
+        Map<String, MonitorRequest> mrMap = Maps.newHashMap();
+        for (String tableName : tables) {
+            TableSchema tableSchema = dbSchema.getTableSchema(tableName);
+            MonitorRequest monitorRequest = getAllColumnsMonitorRequest(tableSchema);
+            mrMap.put(tableName, monitorRequest);
+        }
+        return Lists.newArrayList(dbSchema.name(), monotorId, mrMap);
+    }
+
+    /**
+     * Returns params of transact method, refer to RFC7047's Section 4.1.3.
+     * @param dbSchema DatabaseSchema entity
+     * @param operations operation*, refer to RFC7047's Section 4.1.3.
+     * @return List of Object, the params of transact request
+     */
+    public static List<Object> getTransactParams(DatabaseSchema dbSchema, List<Operation> operations) {
+        List<Object> lists = Lists.newArrayList(dbSchema.name());
+        lists.addAll(operations);
+        return lists;
+    }
+}
