diff --git a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
index 044397e..3979e1e 100644
--- a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
+++ b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/SubnetWebResource.java
@@ -1,365 +1,365 @@
-/*
- * 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.vtnweb.resources;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpAddress.Version;
-import org.onlab.packet.IpPrefix;
-import org.onlab.util.ItemNotFoundException;
-import org.onosproject.rest.AbstractWebResource;
-import org.onosproject.vtnrsc.AllocationPool;
-import org.onosproject.vtnrsc.DefaultAllocationPool;
-import org.onosproject.vtnrsc.DefaultHostRoute;
-import org.onosproject.vtnrsc.DefaultSubnet;
-import org.onosproject.vtnrsc.HostRoute;
-import org.onosproject.vtnrsc.Subnet;
-import org.onosproject.vtnrsc.SubnetId;
-import org.onosproject.vtnrsc.TenantId;
-import org.onosproject.vtnrsc.TenantNetworkId;
-import org.onosproject.vtnrsc.Subnet.Mode;
-import org.onosproject.vtnrsc.subnet.SubnetService;
-import org.onosproject.vtnrsc.web.SubnetCodec;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-@Path("subnets")
-public class SubnetWebResource extends AbstractWebResource {
-    private final Logger log = LoggerFactory.getLogger(SubnetWebResource.class);
-    public static final String SUBNET_NOT_CREATE = "Subnets is failed to create!";
-    public static final String SUBNET_NOT_FOUND = "Subnets is failed to update!";
-    public static final String JSON_NOT_NULL = "JsonNode can not be null";
-
-    @GET
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response listSubnets() {
-        Iterable<Subnet> subnets = get(SubnetService.class).getSubnets();
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("subnets", new SubnetCodec().encode(subnets, this));
-        return ok(result.toString()).build();
-    }
-
-    @GET
-    @Path("{subnetUUID}")
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response getSubnet(@PathParam("subnetUUID") String id) {
-
-        if (!get(SubnetService.class).exists(SubnetId.subnetId(id))) {
-            return ok("The subnet does not exists").build();
-        }
-        Subnet sub = nullIsNotFound(get(SubnetService.class)
-                                            .getSubnet(SubnetId.subnetId(id)),
-                                    SUBNET_NOT_FOUND);
-
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("subnet", new SubnetCodec().encode(sub, this));
-        return ok(result.toString()).build();
-    }
-
-    @POST
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response createSubnet(final InputStream input) {
-
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode subnode = mapper.readTree(input);
-            Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
-            Boolean result = nullIsNotFound((get(SubnetService.class)
-                                                    .createSubnets(subnets)),
-                                            SUBNET_NOT_CREATE);
-
-            if (!result) {
-                return Response.status(204).entity(SUBNET_NOT_CREATE).build();
-            }
-            return Response.status(202).entity(result.toString()).build();
-        } catch (Exception e) {
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @PUT
-    @Path("{subnetUUID}")
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response updateSubnet(@PathParam("id") String id,
-                                 final InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode subnode = mapper.readTree(input);
-            Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
-            Boolean result = nullIsNotFound(get(SubnetService.class)
-                    .updateSubnets(subnets), SUBNET_NOT_FOUND);
-            if (!result) {
-                return Response.status(204).entity(SUBNET_NOT_FOUND).build();
-            }
-            return Response.status(203).entity(result.toString()).build();
-        } catch (Exception e) {
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @Path("{subnetUUID}")
-    @DELETE
-    public Response deleteSingleSubnet(@PathParam("subnetUUID") String id)
-            throws IOException {
-        try {
-            SubnetId subId = SubnetId.subnetId(id);
-            Set<SubnetId> subIds = new HashSet<>();
-            subIds.add(subId);
-            get(SubnetService.class).removeSubnets(subIds);
-            return Response.status(201).entity("SUCCESS").build();
-        } catch (Exception e) {
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    private Iterable<Subnet> createOrUpdateByInputStream(JsonNode subnode) {
-        checkNotNull(subnode, JSON_NOT_NULL);
-        Iterable<Subnet> subnets = null;
-        JsonNode subnetNodes = subnode.get("subnets");
-        if (subnetNodes == null) {
-            subnetNodes = subnode.get("subnet");
-        }
-        log.debug("subnetNodes is {}", subnetNodes.toString());
-        if (subnetNodes.isArray()) {
-            subnets = changeJsonToSubs(subnetNodes);
-        } else {
-            subnets = changeJsonToSub(subnetNodes);
-        }
-        return subnets;
-    }
-
-    /**
-     * Returns a collection of subnets from subnetNodes.
-     *
-     * @param subnetNodes the subnet json node
-     * @return subnets a collection of subnets
-     */
-    public Iterable<Subnet> changeJsonToSubs(JsonNode subnetNodes) {
-        checkNotNull(subnetNodes, JSON_NOT_NULL);
-        Map<SubnetId, Subnet> subMap = new HashMap<>();
-        for (JsonNode subnetNode : subnetNodes) {
-            if (!subnetNode.hasNonNull("id")) {
-                return null;
-            }
-            SubnetId id = SubnetId.subnetId(subnetNode.get("id").asText());
-            String subnetName = subnetNode.get("name").asText();
-            TenantId tenantId = TenantId
-                    .tenantId(subnetNode.get("tenant_id").asText());
-            TenantNetworkId networkId = TenantNetworkId
-                    .networkId(subnetNode.get("network_id").asText());
-            Version ipVersion = Version
-                    .valueOf(subnetNode.get("ip_version").asText());
-            IpPrefix cidr = IpPrefix.valueOf(subnetNode.get("cidr").asText());
-            IpAddress gatewayIp = IpAddress
-                    .valueOf(subnetNode.get("gateway_ip").asText());
-            Boolean dhcpEnabled = subnetNode.get("enable_dhcp").asBoolean();
-            Boolean shared = subnetNode.get("shared").asBoolean();
-            JsonNode hostRoutes = subnetNode.get("host_routes");
-            Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
-            JsonNode allocationPools = subnetNode.get("allocation_pools");
-            Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
-            Mode ipV6AddressMode = Mode
-                    .valueOf(subnetNode.get("ipv6_address_mode").asText());
-            Mode ipV6RaMode = Mode
-                    .valueOf(subnetNode.get("ipv6_ra_mode").asText());
-            Subnet subnet = new DefaultSubnet(id, subnetName, networkId,
-                                              tenantId, ipVersion, cidr,
-                                              gatewayIp, dhcpEnabled, shared,
-                                              Sets.newHashSet(hostRoutesIt), ipV6AddressMode,
-                                              ipV6RaMode, Sets.newHashSet(allocationPoolsIt));
-            subMap.put(id, subnet);
-        }
-        return Collections.unmodifiableCollection(subMap.values());
-    }
-
-    /**
-     * Returns a collection of subnets from subnetNodes.
-     *
-     * @param subnetNodes the subnet json node
-     * @return subnets a collection of subnets
-     */
-    public Iterable<Subnet> changeJsonToSub(JsonNode subnetNodes) {
-        checkNotNull(subnetNodes, JSON_NOT_NULL);
-        checkArgument(subnetNodes.get("enable_dhcp").isBoolean(), "enable_dhcp should be boolean");
-        checkArgument(subnetNodes.get("shared").isBoolean(), "shared should be boolean");
-        Map<SubnetId, Subnet> subMap = new HashMap<>();
-        if (!subnetNodes.hasNonNull("id")) {
-            return null;
-        }
-        SubnetId id = SubnetId.subnetId(subnetNodes.get("id").asText());
-        String subnetName = subnetNodes.get("name").asText();
-        TenantId tenantId = TenantId
-                .tenantId(subnetNodes.get("tenant_id").asText());
-        TenantNetworkId networkId = TenantNetworkId
-                .networkId(subnetNodes.get("network_id").asText());
-        String version = subnetNodes.get("ip_version").asText();
-        Version ipVersion;
-        switch (version) {
-        case "4":
-            ipVersion = Version.INET;
-            break;
-        case "6":
-            ipVersion = Version.INET;
-            break;
-        default:
-            throw new IllegalArgumentException("ipVersion should be 4 or 6.");
-        }
-
-        IpPrefix cidr = IpPrefix.valueOf(subnetNodes.get("cidr").asText());
-        IpAddress gatewayIp = IpAddress
-                .valueOf(subnetNodes.get("gateway_ip").asText());
-        Boolean dhcpEnabled = subnetNodes.get("enable_dhcp").asBoolean();
-        Boolean shared = subnetNodes.get("shared").asBoolean();
-        JsonNode hostRoutes = subnetNodes.get("host_routes");
-        Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
-        JsonNode allocationPools = subnetNodes.get("allocation_pools");
-        Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
-
-        Mode ipV6AddressMode = getMode(subnetNodes.get("ipv6_address_mode")
-                .asText());
-        Mode ipV6RaMode = getMode(subnetNodes.get("ipv6_ra_mode").asText());
-
-        Subnet subnet = new DefaultSubnet(id, subnetName, networkId, tenantId,
-                                          ipVersion, cidr, gatewayIp,
-                                          dhcpEnabled, shared, Sets.newHashSet(hostRoutesIt),
-                                          ipV6AddressMode, ipV6RaMode,
-                                          Sets.newHashSet(allocationPoolsIt));
-        subMap.put(id, subnet);
-        return Collections.unmodifiableCollection(subMap.values());
-    }
-
-    /**
-     * Gets ipv6_address_mode or ipv6_ra_mode type.
-     *
-     * @param mode the String value in JsonNode
-     * @return ipV6Mode Mode of the ipV6Mode
-     */
-    private Mode getMode(String mode) {
-        Mode ipV6Mode;
-        if (mode == null) {
-            return null;
-        }
-        switch (mode) {
-        case "dhcpv6-stateful":
-            ipV6Mode = Mode.DHCPV6_STATEFUL;
-            break;
-        case "dhcpv6-stateless":
-            ipV6Mode = Mode.DHCPV6_STATELESS;
-            break;
-        case "slaac":
-            ipV6Mode = Mode.SLAAC;
-            break;
-        default:
-            ipV6Mode = null;
-        }
-        return ipV6Mode;
-    }
-
-    /**
-     * Changes JsonNode alocPools to a collection of the alocPools.
-     *
-     * @param allocationPools the allocationPools JsonNode
-     * @return a collection of allocationPools
-     */
-    public Iterable<AllocationPool> jsonNodeToAllocationPools(JsonNode allocationPools) {
-        checkNotNull(allocationPools, JSON_NOT_NULL);
-        ConcurrentMap<Integer, AllocationPool> alocplMaps = Maps
-                .newConcurrentMap();
-        Integer i = 0;
-        for (JsonNode node : allocationPools) {
-            IpAddress startIp = IpAddress.valueOf(node.get("start").asText());
-            IpAddress endIp = IpAddress.valueOf(node.get("end").asText());
-            AllocationPool alocPls = new DefaultAllocationPool(startIp, endIp);
-            alocplMaps.putIfAbsent(i, alocPls);
-            i++;
-        }
-        return Collections.unmodifiableCollection(alocplMaps.values());
-    }
-
-    /**
-     * Changes hostRoutes JsonNode to a collection of the hostRoutes.
-     *
-     * @param hostRoutes the hostRoutes json node
-     * @return a collection of hostRoutes
-     */
-    public Iterable<HostRoute> jsonNodeToHostRoutes(JsonNode hostRoutes) {
-        checkNotNull(hostRoutes, JSON_NOT_NULL);
-        ConcurrentMap<Integer, HostRoute> hostRouteMaps = Maps
-                .newConcurrentMap();
-        Integer i = 0;
-        for (JsonNode node : hostRoutes) {
-            IpAddress nexthop = IpAddress.valueOf(node.get("nexthop").asText());
-            IpPrefix destination = IpPrefix.valueOf(node.get("destination")
-                    .asText());
-            HostRoute hostRoute = new DefaultHostRoute(nexthop, destination);
-            hostRouteMaps.putIfAbsent(i, hostRoute);
-            i++;
-        }
-        return Collections.unmodifiableCollection(hostRouteMaps.values());
-    }
-
-    /**
-     * Returns the specified item if that items is null; otherwise throws not
-     * found exception.
-     *
-     * @param item item to check
-     * @param <T> item type
-     * @param message not found message
-     * @return item if not null
-     * @throws org.onlab.util.ItemNotFoundException if item is null
-     */
-    protected <T> T nullIsNotFound(T item, String message) {
-        if (item == null) {
-            throw new ItemNotFoundException(message);
-        }
-        return item;
-    }
-
-}
+/*
+ * 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.vtnweb.resources;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpAddress.Version;
+import org.onlab.packet.IpPrefix;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.vtnrsc.AllocationPool;
+import org.onosproject.vtnrsc.DefaultAllocationPool;
+import org.onosproject.vtnrsc.DefaultHostRoute;
+import org.onosproject.vtnrsc.DefaultSubnet;
+import org.onosproject.vtnrsc.HostRoute;
+import org.onosproject.vtnrsc.Subnet;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.Subnet.Mode;
+import org.onosproject.vtnrsc.subnet.SubnetService;
+import org.onosproject.vtnrsc.web.SubnetCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+@Path("subnets")
+public class SubnetWebResource extends AbstractWebResource {
+    private final Logger log = LoggerFactory.getLogger(SubnetWebResource.class);
+    public static final String SUBNET_NOT_CREATE = "Subnets is failed to create!";
+    public static final String SUBNET_NOT_FOUND = "Subnets is failed to update!";
+    public static final String JSON_NOT_NULL = "JsonNode can not be null";
+
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response listSubnets() {
+        Iterable<Subnet> subnets = get(SubnetService.class).getSubnets();
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("subnets", new SubnetCodec().encode(subnets, this));
+        return ok(result.toString()).build();
+    }
+
+    @GET
+    @Path("{subnetUUID}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getSubnet(@PathParam("subnetUUID") String id) {
+
+        if (!get(SubnetService.class).exists(SubnetId.subnetId(id))) {
+            return ok("The subnet does not exists").build();
+        }
+        Subnet sub = nullIsNotFound(get(SubnetService.class)
+                                            .getSubnet(SubnetId.subnetId(id)),
+                                    SUBNET_NOT_FOUND);
+
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("subnet", new SubnetCodec().encode(sub, this));
+        return ok(result.toString()).build();
+    }
+
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response createSubnet(final InputStream input) {
+
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode subnode = mapper.readTree(input);
+            Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
+            Boolean result = nullIsNotFound((get(SubnetService.class)
+                                                    .createSubnets(subnets)),
+                                            SUBNET_NOT_CREATE);
+
+            if (!result) {
+                return Response.status(204).entity(SUBNET_NOT_CREATE).build();
+            }
+            return Response.status(202).entity(result.toString()).build();
+        } catch (Exception e) {
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @PUT
+    @Path("{subnetUUID}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateSubnet(@PathParam("id") String id,
+                                 final InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode subnode = mapper.readTree(input);
+            Iterable<Subnet> subnets = createOrUpdateByInputStream(subnode);
+            Boolean result = nullIsNotFound(get(SubnetService.class)
+                    .updateSubnets(subnets), SUBNET_NOT_FOUND);
+            if (!result) {
+                return Response.status(204).entity(SUBNET_NOT_FOUND).build();
+            }
+            return Response.status(203).entity(result.toString()).build();
+        } catch (Exception e) {
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @Path("{subnetUUID}")
+    @DELETE
+    public Response deleteSingleSubnet(@PathParam("subnetUUID") String id)
+            throws IOException {
+        try {
+            SubnetId subId = SubnetId.subnetId(id);
+            Set<SubnetId> subIds = new HashSet<>();
+            subIds.add(subId);
+            get(SubnetService.class).removeSubnets(subIds);
+            return Response.status(201).entity("SUCCESS").build();
+        } catch (Exception e) {
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    private Iterable<Subnet> createOrUpdateByInputStream(JsonNode subnode) {
+        checkNotNull(subnode, JSON_NOT_NULL);
+        Iterable<Subnet> subnets = null;
+        JsonNode subnetNodes = subnode.get("subnets");
+        if (subnetNodes == null) {
+            subnetNodes = subnode.get("subnet");
+        }
+        log.debug("subnetNodes is {}", subnetNodes.toString());
+        if (subnetNodes.isArray()) {
+            subnets = changeJsonToSubs(subnetNodes);
+        } else {
+            subnets = changeJsonToSub(subnetNodes);
+        }
+        return subnets;
+    }
+
+    /**
+     * Returns a collection of subnets from subnetNodes.
+     *
+     * @param subnetNodes the subnet json node
+     * @return subnets a collection of subnets
+     */
+    public Iterable<Subnet> changeJsonToSubs(JsonNode subnetNodes) {
+        checkNotNull(subnetNodes, JSON_NOT_NULL);
+        Map<SubnetId, Subnet> subMap = new HashMap<>();
+        for (JsonNode subnetNode : subnetNodes) {
+            if (!subnetNode.hasNonNull("id")) {
+                return null;
+            }
+            SubnetId id = SubnetId.subnetId(subnetNode.get("id").asText());
+            String subnetName = subnetNode.get("name").asText();
+            TenantId tenantId = TenantId
+                    .tenantId(subnetNode.get("tenant_id").asText());
+            TenantNetworkId networkId = TenantNetworkId
+                    .networkId(subnetNode.get("network_id").asText());
+            Version ipVersion = Version
+                    .valueOf(subnetNode.get("ip_version").asText());
+            IpPrefix cidr = IpPrefix.valueOf(subnetNode.get("cidr").asText());
+            IpAddress gatewayIp = IpAddress
+                    .valueOf(subnetNode.get("gateway_ip").asText());
+            Boolean dhcpEnabled = subnetNode.get("enable_dhcp").asBoolean();
+            Boolean shared = subnetNode.get("shared").asBoolean();
+            JsonNode hostRoutes = subnetNode.get("host_routes");
+            Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
+            JsonNode allocationPools = subnetNode.get("allocation_pools");
+            Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
+            Mode ipV6AddressMode = Mode
+                    .valueOf(subnetNode.get("ipv6_address_mode").asText());
+            Mode ipV6RaMode = Mode
+                    .valueOf(subnetNode.get("ipv6_ra_mode").asText());
+            Subnet subnet = new DefaultSubnet(id, subnetName, networkId,
+                                              tenantId, ipVersion, cidr,
+                                              gatewayIp, dhcpEnabled, shared,
+                                              Sets.newHashSet(hostRoutesIt), ipV6AddressMode,
+                                              ipV6RaMode, Sets.newHashSet(allocationPoolsIt));
+            subMap.put(id, subnet);
+        }
+        return Collections.unmodifiableCollection(subMap.values());
+    }
+
+    /**
+     * Returns a collection of subnets from subnetNodes.
+     *
+     * @param subnetNodes the subnet json node
+     * @return subnets a collection of subnets
+     */
+    public Iterable<Subnet> changeJsonToSub(JsonNode subnetNodes) {
+        checkNotNull(subnetNodes, JSON_NOT_NULL);
+        checkArgument(subnetNodes.get("enable_dhcp").isBoolean(), "enable_dhcp should be boolean");
+        checkArgument(subnetNodes.get("shared").isBoolean(), "shared should be boolean");
+        Map<SubnetId, Subnet> subMap = new HashMap<>();
+        if (!subnetNodes.hasNonNull("id")) {
+            return null;
+        }
+        SubnetId id = SubnetId.subnetId(subnetNodes.get("id").asText());
+        String subnetName = subnetNodes.get("name").asText();
+        TenantId tenantId = TenantId
+                .tenantId(subnetNodes.get("tenant_id").asText());
+        TenantNetworkId networkId = TenantNetworkId
+                .networkId(subnetNodes.get("network_id").asText());
+        String version = subnetNodes.get("ip_version").asText();
+        Version ipVersion;
+        switch (version) {
+        case "4":
+            ipVersion = Version.INET;
+            break;
+        case "6":
+            ipVersion = Version.INET;
+            break;
+        default:
+            throw new IllegalArgumentException("ipVersion should be 4 or 6.");
+        }
+
+        IpPrefix cidr = IpPrefix.valueOf(subnetNodes.get("cidr").asText());
+        IpAddress gatewayIp = IpAddress
+                .valueOf(subnetNodes.get("gateway_ip").asText());
+        Boolean dhcpEnabled = subnetNodes.get("enable_dhcp").asBoolean();
+        Boolean shared = subnetNodes.get("shared").asBoolean();
+        JsonNode hostRoutes = subnetNodes.get("host_routes");
+        Iterable<HostRoute> hostRoutesIt = jsonNodeToHostRoutes(hostRoutes);
+        JsonNode allocationPools = subnetNodes.get("allocation_pools");
+        Iterable<AllocationPool> allocationPoolsIt = jsonNodeToAllocationPools(allocationPools);
+
+        Mode ipV6AddressMode = getMode(subnetNodes.get("ipv6_address_mode")
+                .asText());
+        Mode ipV6RaMode = getMode(subnetNodes.get("ipv6_ra_mode").asText());
+
+        Subnet subnet = new DefaultSubnet(id, subnetName, networkId, tenantId,
+                                          ipVersion, cidr, gatewayIp,
+                                          dhcpEnabled, shared, Sets.newHashSet(hostRoutesIt),
+                                          ipV6AddressMode, ipV6RaMode,
+                                          Sets.newHashSet(allocationPoolsIt));
+        subMap.put(id, subnet);
+        return Collections.unmodifiableCollection(subMap.values());
+    }
+
+    /**
+     * Gets ipv6_address_mode or ipv6_ra_mode type.
+     *
+     * @param mode the String value in JsonNode
+     * @return ipV6Mode Mode of the ipV6Mode
+     */
+    private Mode getMode(String mode) {
+        Mode ipV6Mode;
+        if (mode == null) {
+            return null;
+        }
+        switch (mode) {
+        case "dhcpv6-stateful":
+            ipV6Mode = Mode.DHCPV6_STATEFUL;
+            break;
+        case "dhcpv6-stateless":
+            ipV6Mode = Mode.DHCPV6_STATELESS;
+            break;
+        case "slaac":
+            ipV6Mode = Mode.SLAAC;
+            break;
+        default:
+            ipV6Mode = null;
+        }
+        return ipV6Mode;
+    }
+
+    /**
+     * Changes JsonNode alocPools to a collection of the alocPools.
+     *
+     * @param allocationPools the allocationPools JsonNode
+     * @return a collection of allocationPools
+     */
+    public Iterable<AllocationPool> jsonNodeToAllocationPools(JsonNode allocationPools) {
+        checkNotNull(allocationPools, JSON_NOT_NULL);
+        ConcurrentMap<Integer, AllocationPool> alocplMaps = Maps
+                .newConcurrentMap();
+        Integer i = 0;
+        for (JsonNode node : allocationPools) {
+            IpAddress startIp = IpAddress.valueOf(node.get("start").asText());
+            IpAddress endIp = IpAddress.valueOf(node.get("end").asText());
+            AllocationPool alocPls = new DefaultAllocationPool(startIp, endIp);
+            alocplMaps.putIfAbsent(i, alocPls);
+            i++;
+        }
+        return Collections.unmodifiableCollection(alocplMaps.values());
+    }
+
+    /**
+     * Changes hostRoutes JsonNode to a collection of the hostRoutes.
+     *
+     * @param hostRoutes the hostRoutes json node
+     * @return a collection of hostRoutes
+     */
+    public Iterable<HostRoute> jsonNodeToHostRoutes(JsonNode hostRoutes) {
+        checkNotNull(hostRoutes, JSON_NOT_NULL);
+        ConcurrentMap<Integer, HostRoute> hostRouteMaps = Maps
+                .newConcurrentMap();
+        Integer i = 0;
+        for (JsonNode node : hostRoutes) {
+            IpAddress nexthop = IpAddress.valueOf(node.get("nexthop").asText());
+            IpPrefix destination = IpPrefix.valueOf(node.get("destination")
+                    .asText());
+            HostRoute hostRoute = new DefaultHostRoute(nexthop, destination);
+            hostRouteMaps.putIfAbsent(i, hostRoute);
+            i++;
+        }
+        return Collections.unmodifiableCollection(hostRouteMaps.values());
+    }
+
+    /**
+     * Returns the specified item if that items is null; otherwise throws not
+     * found exception.
+     *
+     * @param item item to check
+     * @param <T> item type
+     * @param message not found message
+     * @return item if not null
+     * @throws org.onlab.util.ItemNotFoundException if item is null
+     */
+    protected <T> T nullIsNotFound(T item, String message) {
+        if (item == null) {
+            throw new ItemNotFoundException(message);
+        }
+        return item;
+    }
+
+}
diff --git a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
index cd2ac29..b3888db 100644
--- a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
+++ b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/TenantNetworkWebResource.java
@@ -1,371 +1,371 @@
-/*
- * 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.vtnweb.resources;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkArgument;
-import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
-import static javax.ws.rs.core.Response.Status.OK;
-
-import java.io.InputStream;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.onlab.util.ItemNotFoundException;
-import org.onosproject.rest.AbstractWebResource;
-import org.onosproject.vtnrsc.DefaultTenantNetwork;
-import org.onosproject.vtnrsc.PhysicalNetwork;
-import org.onosproject.vtnrsc.SegmentationId;
-import org.onosproject.vtnrsc.TenantId;
-import org.onosproject.vtnrsc.TenantNetwork;
-import org.onosproject.vtnrsc.TenantNetworkId;
-import org.onosproject.vtnrsc.TenantNetwork.State;
-import org.onosproject.vtnrsc.TenantNetwork.Type;
-import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
-import org.onosproject.vtnrsc.web.TenantNetworkCodec;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Maps;
-
-/**
- * REST resource for interacting with the inventory of networks.
- */
-@Path("networks")
-public class TenantNetworkWebResource extends AbstractWebResource {
-    public static final String NETWORK_NOT_FOUND = "Network is not found";
-    public static final String NETWORK_ID_EXIST = "Network id is existed";
-    public static final String NETWORK_ID_NOT_EXIST = "Network id is not existed";
-    public static final String CREATE_NETWORK = "create network";
-    public static final String UPDATE_NETWORK = "update network";
-    public static final String DELETE_NETWORK = "delete network";
-    public static final String JSON_NOT_NULL = "JsonNode can not be null";
-
-    protected static final Logger log = LoggerFactory
-            .getLogger(TenantNetworkWebResource.class);
-    private final ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
-            .newConcurrentMap();
-
-    @GET
-    @Produces({ MediaType.APPLICATION_JSON })
-    public Response getNetworks(@QueryParam("id") String queryId,
-                                @QueryParam("name") String queryName,
-                                @QueryParam("admin_state_up") String queryadminStateUp,
-                                @QueryParam("status") String querystate,
-                                @QueryParam("shared") String queryshared,
-                                @QueryParam("tenant_id") String querytenantId,
-                                @QueryParam("router:external") String routerExternal,
-                                @QueryParam("provider:network_type") String type,
-                                @QueryParam("provider:physical_network") String physicalNetwork,
-                                @QueryParam("provider:segmentation_id") String segmentationId) {
-        Iterable<TenantNetwork> networks = get(TenantNetworkService.class)
-                .getNetworks();
-        Iterator<TenantNetwork> networkors = networks.iterator();
-        while (networkors.hasNext()) {
-            TenantNetwork network = networkors.next();
-            if ((queryId == null || queryId.equals(network.id().toString()))
-                    && (queryName == null || queryName.equals(network.name()))
-                    && (queryadminStateUp == null || queryadminStateUp
-                            .equals(network.adminStateUp()))
-                    && (querystate == null || querystate.equals(network.state()
-                            .toString()))
-                    && (queryshared == null || queryshared.equals(network
-                            .shared()))
-                    && (querytenantId == null || querytenantId.equals(network
-                            .tenantId().toString()))
-                    && (routerExternal == null || routerExternal.equals(network
-                            .routerExternal()))
-                    && (type == null || type.equals(network.type()))
-                    && (physicalNetwork == null || physicalNetwork
-                            .equals(network.physicalNetwork()))
-                    && (segmentationId == null || segmentationId.equals(network
-                            .segmentationId()))) {
-                networksMap.putIfAbsent(network.id(), network);
-            }
-        }
-        networks = Collections.unmodifiableCollection(networksMap.values());
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("networks", new TenantNetworkCodec().encode(networks, this));
-
-        return ok(result.toString()).build();
-    }
-
-    private State isState(String state) {
-        if (state.equals("ACTIVE")) {
-            return TenantNetwork.State.ACTIVE;
-        } else if (state.equals("BUILD")) {
-            return TenantNetwork.State.BUILD;
-        } else if (state.equals("DOWN")) {
-            return TenantNetwork.State.DOWN;
-        } else if (state.equals("ERROR")) {
-            return TenantNetwork.State.ERROR;
-        } else {
-            return null;
-        }
-    }
-
-    private Type isType(String type) {
-        if (type.equals("LOCAL")) {
-            return TenantNetwork.Type.LOCAL;
-        } else {
-            return null;
-        }
-    }
-
-    @GET
-    @Path("{id}")
-    @Produces({ MediaType.APPLICATION_JSON })
-    public Response getNetwork(@PathParam("id") String id) {
-
-        if (!get(TenantNetworkService.class).exists(TenantNetworkId
-                                                            .networkId(id))) {
-            return ok("The tenantNetwork does not exists").build();
-        }
-        TenantNetwork network = nullIsNotFound(get(TenantNetworkService.class)
-                .getNetwork(TenantNetworkId.networkId(id)), NETWORK_NOT_FOUND);
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("network", new TenantNetworkCodec().encode(network, this));
-
-        return ok(result.toString()).build();
-
-    }
-
-    @POST
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response createNetworks(InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode cfg = mapper.readTree(input);
-            JsonNode nodes = null;
-            Iterable<TenantNetwork> networks = null;
-            if (cfg.get("network") != null) {
-                nodes = cfg.get("network");
-                if (nodes.isArray()) {
-                    networks = changeJson2objs(nodes);
-                } else {
-                    networks = changeJson2obj(CREATE_NETWORK, null, nodes);
-                }
-            } else if (cfg.get("networks") != null) {
-                nodes = cfg.get("networks");
-                networks = changeJson2objs(nodes);
-            }
-            Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
-                                                       .createNetworks(networks)),
-                                               NETWORK_NOT_FOUND);
-
-            if (!issuccess) {
-                return Response.status(INTERNAL_SERVER_ERROR)
-                        .entity(NETWORK_ID_EXIST).build();
-            }
-            return Response.status(OK).entity(issuccess.toString()).build();
-        } catch (Exception e) {
-            log.error("Creates tenantNetwork exception {}.", e.toString());
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @PUT
-    @Path("{id}")
-    @Produces(MediaType.APPLICATION_JSON)
-    @Consumes(MediaType.APPLICATION_JSON)
-    public Response updateNetworks(@PathParam("id") String id, InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode cfg = mapper.readTree(input);
-            JsonNode nodes = null;
-            Iterable<TenantNetwork> networks = null;
-            if (cfg.get("network") != null) {
-                nodes = cfg.get("network");
-                if (nodes.isArray()) {
-                    networks = changeJson2objs(nodes);
-                } else {
-                    networks = changeJson2obj(UPDATE_NETWORK,
-                                              TenantNetworkId.networkId(id),
-                                              nodes);
-                }
-            } else if (cfg.get("networks") != null) {
-                nodes = cfg.get("networks");
-                networks = changeJson2objs(nodes);
-            }
-            Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
-                                                       .updateNetworks(networks)),
-                                               NETWORK_NOT_FOUND);
-            if (!issuccess) {
-                return Response.status(INTERNAL_SERVER_ERROR)
-                        .entity(NETWORK_ID_NOT_EXIST).build();
-            }
-            return Response.status(OK).entity(issuccess.toString()).build();
-        } catch (Exception e) {
-            log.error("Updates tenantNetwork failed because of exception {}.",
-                      e.toString());
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @DELETE
-    @Path("{id}")
-    public Response deleteNetworks(@PathParam("id") String id) {
-        log.debug("Deletes network by identifier {}.", id);
-        Set<TenantNetworkId> networkSet = new HashSet<>();
-        networkSet.add(TenantNetworkId.networkId(id));
-        Boolean issuccess = nullIsNotFound(get(TenantNetworkService.class)
-                .removeNetworks(networkSet), NETWORK_NOT_FOUND);
-        if (!issuccess) {
-            log.debug("Network identifier {} is not existed", id);
-            return Response.status(INTERNAL_SERVER_ERROR)
-                    .entity(NETWORK_ID_NOT_EXIST).build();
-        }
-        return Response.status(OK).entity(issuccess.toString()).build();
-    }
-
-    /**
-     * Returns a collection of tenantNetworks.
-     *
-     * @param flag the flag
-     * @param networkId network identifier
-     * @param node the network json node
-     * @return a collection of tenantNetworks
-     */
-    public Iterable<TenantNetwork> changeJson2obj(String flag,
-                                                  TenantNetworkId networkId,
-                                                  JsonNode node) {
-        checkNotNull(node, JSON_NOT_NULL);
-        TenantNetwork network = null;
-        ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
-                .newConcurrentMap();
-        if (node != null) {
-            checkArgument(node.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
-            checkArgument(node.get("shared").isBoolean(), "shared should be boolean");
-            checkArgument(node.get("router:external").isBoolean(), "router:external should be boolean");
-            String name = node.get("name").asText();
-            boolean adminStateUp = node.get("admin_state_up").asBoolean();
-            String state = node.get("status").asText();
-            boolean shared = node.get("shared").asBoolean();
-            String tenantId = node.get("tenant_id").asText();
-            boolean routerExternal = node.get("router:external").asBoolean();
-            String type = node.get("provider:network_type").asText();
-            String physicalNetwork = node.get("provider:physical_network")
-                    .asText();
-            String segmentationId = node.get("provider:segmentation_id")
-                    .asText();
-            TenantNetworkId id = null;
-            if (flag == CREATE_NETWORK) {
-                id = TenantNetworkId.networkId(node.get("id").asText());
-            } else if (flag == UPDATE_NETWORK) {
-                id = networkId;
-            }
-            network = new DefaultTenantNetwork(
-                                               id,
-                                               name,
-                                               adminStateUp,
-                                               isState(state),
-                                               shared,
-                                               TenantId.tenantId(tenantId),
-                                               routerExternal,
-                                               isType(type),
-                                               PhysicalNetwork
-                                                       .physicalNetwork(physicalNetwork),
-                                               SegmentationId
-                                                       .segmentationId(segmentationId));
-            networksMap.putIfAbsent(id, network);
-        }
-        return Collections.unmodifiableCollection(networksMap.values());
-    }
-
-    /**
-     * Returns a collection of tenantNetworks.
-     *
-     * @param nodes the network jsonnodes
-     * @return a collection of tenantNetworks
-     */
-    public Iterable<TenantNetwork> changeJson2objs(JsonNode nodes) {
-        checkNotNull(nodes, JSON_NOT_NULL);
-        TenantNetwork network = null;
-        ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
-                .newConcurrentMap();
-        if (nodes != null) {
-            for (JsonNode node : nodes) {
-                String id = node.get("id").asText();
-                String name = node.get("name").asText();
-                boolean adminStateUp = node.get("admin_state_up").asBoolean();
-                String state = node.get("status").asText();
-                boolean shared = node.get("shared").asBoolean();
-                String tenantId = node.get("tenant_id").asText();
-                boolean routerExternal = node.get("router:external")
-                        .asBoolean();
-                String type = node.get("provider:network_type").asText();
-                String physicalNetwork = node.get("provider:physical_network")
-                        .asText();
-                String segmentationId = node.get("provider:segmentation_id")
-                        .asText();
-                network = new DefaultTenantNetwork(
-                                                   TenantNetworkId
-                                                           .networkId(id),
-                                                   name,
-                                                   adminStateUp,
-                                                   isState(state),
-                                                   shared,
-                                                   TenantId.tenantId(tenantId),
-                                                   routerExternal,
-                                                   isType(type),
-                                                   PhysicalNetwork
-                                                           .physicalNetwork(physicalNetwork),
-                                                   SegmentationId
-                                                           .segmentationId(segmentationId));
-                networksMap.putIfAbsent(TenantNetworkId.networkId(id), network);
-            }
-        }
-        return Collections.unmodifiableCollection(networksMap.values());
-    }
-
-    /**
-     * Returns the specified item if that items is null; otherwise throws not
-     * found exception.
-     *
-     * @param item item to check
-     * @param <T> item type
-     * @param message not found message
-     * @return item if not null
-     * @throws org.onlab.util.ItemNotFoundException if item is null
-     */
-    protected <T> T nullIsNotFound(T item, String message) {
-        if (item == null) {
-            throw new ItemNotFoundException(message);
-        }
-        return item;
-    }
-}
+/*
+ * 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.vtnweb.resources;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkArgument;
+import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+import static javax.ws.rs.core.Response.Status.OK;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.vtnrsc.DefaultTenantNetwork;
+import org.onosproject.vtnrsc.PhysicalNetwork;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.TenantNetwork.State;
+import org.onosproject.vtnrsc.TenantNetwork.Type;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.web.TenantNetworkCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Maps;
+
+/**
+ * REST resource for interacting with the inventory of networks.
+ */
+@Path("networks")
+public class TenantNetworkWebResource extends AbstractWebResource {
+    public static final String NETWORK_NOT_FOUND = "Network is not found";
+    public static final String NETWORK_ID_EXIST = "Network id is existed";
+    public static final String NETWORK_ID_NOT_EXIST = "Network id is not existed";
+    public static final String CREATE_NETWORK = "create network";
+    public static final String UPDATE_NETWORK = "update network";
+    public static final String DELETE_NETWORK = "delete network";
+    public static final String JSON_NOT_NULL = "JsonNode can not be null";
+
+    protected static final Logger log = LoggerFactory
+            .getLogger(TenantNetworkWebResource.class);
+    private final ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
+            .newConcurrentMap();
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response getNetworks(@QueryParam("id") String queryId,
+                                @QueryParam("name") String queryName,
+                                @QueryParam("admin_state_up") String queryadminStateUp,
+                                @QueryParam("status") String querystate,
+                                @QueryParam("shared") String queryshared,
+                                @QueryParam("tenant_id") String querytenantId,
+                                @QueryParam("router:external") String routerExternal,
+                                @QueryParam("provider:network_type") String type,
+                                @QueryParam("provider:physical_network") String physicalNetwork,
+                                @QueryParam("provider:segmentation_id") String segmentationId) {
+        Iterable<TenantNetwork> networks = get(TenantNetworkService.class)
+                .getNetworks();
+        Iterator<TenantNetwork> networkors = networks.iterator();
+        while (networkors.hasNext()) {
+            TenantNetwork network = networkors.next();
+            if ((queryId == null || queryId.equals(network.id().toString()))
+                    && (queryName == null || queryName.equals(network.name()))
+                    && (queryadminStateUp == null || queryadminStateUp
+                            .equals(network.adminStateUp()))
+                    && (querystate == null || querystate.equals(network.state()
+                            .toString()))
+                    && (queryshared == null || queryshared.equals(network
+                            .shared()))
+                    && (querytenantId == null || querytenantId.equals(network
+                            .tenantId().toString()))
+                    && (routerExternal == null || routerExternal.equals(network
+                            .routerExternal()))
+                    && (type == null || type.equals(network.type()))
+                    && (physicalNetwork == null || physicalNetwork
+                            .equals(network.physicalNetwork()))
+                    && (segmentationId == null || segmentationId.equals(network
+                            .segmentationId()))) {
+                networksMap.putIfAbsent(network.id(), network);
+            }
+        }
+        networks = Collections.unmodifiableCollection(networksMap.values());
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("networks", new TenantNetworkCodec().encode(networks, this));
+
+        return ok(result.toString()).build();
+    }
+
+    private State isState(String state) {
+        if (state.equals("ACTIVE")) {
+            return TenantNetwork.State.ACTIVE;
+        } else if (state.equals("BUILD")) {
+            return TenantNetwork.State.BUILD;
+        } else if (state.equals("DOWN")) {
+            return TenantNetwork.State.DOWN;
+        } else if (state.equals("ERROR")) {
+            return TenantNetwork.State.ERROR;
+        } else {
+            return null;
+        }
+    }
+
+    private Type isType(String type) {
+        if (type.equals("LOCAL")) {
+            return TenantNetwork.Type.LOCAL;
+        } else {
+            return null;
+        }
+    }
+
+    @GET
+    @Path("{id}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response getNetwork(@PathParam("id") String id) {
+
+        if (!get(TenantNetworkService.class).exists(TenantNetworkId
+                                                            .networkId(id))) {
+            return ok("The tenantNetwork does not exists").build();
+        }
+        TenantNetwork network = nullIsNotFound(get(TenantNetworkService.class)
+                .getNetwork(TenantNetworkId.networkId(id)), NETWORK_NOT_FOUND);
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("network", new TenantNetworkCodec().encode(network, this));
+
+        return ok(result.toString()).build();
+
+    }
+
+    @POST
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response createNetworks(InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            JsonNode nodes = null;
+            Iterable<TenantNetwork> networks = null;
+            if (cfg.get("network") != null) {
+                nodes = cfg.get("network");
+                if (nodes.isArray()) {
+                    networks = changeJson2objs(nodes);
+                } else {
+                    networks = changeJson2obj(CREATE_NETWORK, null, nodes);
+                }
+            } else if (cfg.get("networks") != null) {
+                nodes = cfg.get("networks");
+                networks = changeJson2objs(nodes);
+            }
+            Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
+                                                       .createNetworks(networks)),
+                                               NETWORK_NOT_FOUND);
+
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(NETWORK_ID_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Creates tenantNetwork exception {}.", e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @PUT
+    @Path("{id}")
+    @Produces(MediaType.APPLICATION_JSON)
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateNetworks(@PathParam("id") String id, InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            JsonNode nodes = null;
+            Iterable<TenantNetwork> networks = null;
+            if (cfg.get("network") != null) {
+                nodes = cfg.get("network");
+                if (nodes.isArray()) {
+                    networks = changeJson2objs(nodes);
+                } else {
+                    networks = changeJson2obj(UPDATE_NETWORK,
+                                              TenantNetworkId.networkId(id),
+                                              nodes);
+                }
+            } else if (cfg.get("networks") != null) {
+                nodes = cfg.get("networks");
+                networks = changeJson2objs(nodes);
+            }
+            Boolean issuccess = nullIsNotFound((get(TenantNetworkService.class)
+                                                       .updateNetworks(networks)),
+                                               NETWORK_NOT_FOUND);
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(NETWORK_ID_NOT_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Updates tenantNetwork failed because of exception {}.",
+                      e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @DELETE
+    @Path("{id}")
+    public Response deleteNetworks(@PathParam("id") String id) {
+        log.debug("Deletes network by identifier {}.", id);
+        Set<TenantNetworkId> networkSet = new HashSet<>();
+        networkSet.add(TenantNetworkId.networkId(id));
+        Boolean issuccess = nullIsNotFound(get(TenantNetworkService.class)
+                .removeNetworks(networkSet), NETWORK_NOT_FOUND);
+        if (!issuccess) {
+            log.debug("Network identifier {} is not existed", id);
+            return Response.status(INTERNAL_SERVER_ERROR)
+                    .entity(NETWORK_ID_NOT_EXIST).build();
+        }
+        return Response.status(OK).entity(issuccess.toString()).build();
+    }
+
+    /**
+     * Returns a collection of tenantNetworks.
+     *
+     * @param flag the flag
+     * @param networkId network identifier
+     * @param node the network json node
+     * @return a collection of tenantNetworks
+     */
+    public Iterable<TenantNetwork> changeJson2obj(String flag,
+                                                  TenantNetworkId networkId,
+                                                  JsonNode node) {
+        checkNotNull(node, JSON_NOT_NULL);
+        TenantNetwork network = null;
+        ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
+                .newConcurrentMap();
+        if (node != null) {
+            checkArgument(node.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
+            checkArgument(node.get("shared").isBoolean(), "shared should be boolean");
+            checkArgument(node.get("router:external").isBoolean(), "router:external should be boolean");
+            String name = node.get("name").asText();
+            boolean adminStateUp = node.get("admin_state_up").asBoolean();
+            String state = node.get("status").asText();
+            boolean shared = node.get("shared").asBoolean();
+            String tenantId = node.get("tenant_id").asText();
+            boolean routerExternal = node.get("router:external").asBoolean();
+            String type = node.get("provider:network_type").asText();
+            String physicalNetwork = node.get("provider:physical_network")
+                    .asText();
+            String segmentationId = node.get("provider:segmentation_id")
+                    .asText();
+            TenantNetworkId id = null;
+            if (flag == CREATE_NETWORK) {
+                id = TenantNetworkId.networkId(node.get("id").asText());
+            } else if (flag == UPDATE_NETWORK) {
+                id = networkId;
+            }
+            network = new DefaultTenantNetwork(
+                                               id,
+                                               name,
+                                               adminStateUp,
+                                               isState(state),
+                                               shared,
+                                               TenantId.tenantId(tenantId),
+                                               routerExternal,
+                                               isType(type),
+                                               PhysicalNetwork
+                                                       .physicalNetwork(physicalNetwork),
+                                               SegmentationId
+                                                       .segmentationId(segmentationId));
+            networksMap.putIfAbsent(id, network);
+        }
+        return Collections.unmodifiableCollection(networksMap.values());
+    }
+
+    /**
+     * Returns a collection of tenantNetworks.
+     *
+     * @param nodes the network jsonnodes
+     * @return a collection of tenantNetworks
+     */
+    public Iterable<TenantNetwork> changeJson2objs(JsonNode nodes) {
+        checkNotNull(nodes, JSON_NOT_NULL);
+        TenantNetwork network = null;
+        ConcurrentMap<TenantNetworkId, TenantNetwork> networksMap = Maps
+                .newConcurrentMap();
+        if (nodes != null) {
+            for (JsonNode node : nodes) {
+                String id = node.get("id").asText();
+                String name = node.get("name").asText();
+                boolean adminStateUp = node.get("admin_state_up").asBoolean();
+                String state = node.get("status").asText();
+                boolean shared = node.get("shared").asBoolean();
+                String tenantId = node.get("tenant_id").asText();
+                boolean routerExternal = node.get("router:external")
+                        .asBoolean();
+                String type = node.get("provider:network_type").asText();
+                String physicalNetwork = node.get("provider:physical_network")
+                        .asText();
+                String segmentationId = node.get("provider:segmentation_id")
+                        .asText();
+                network = new DefaultTenantNetwork(
+                                                   TenantNetworkId
+                                                           .networkId(id),
+                                                   name,
+                                                   adminStateUp,
+                                                   isState(state),
+                                                   shared,
+                                                   TenantId.tenantId(tenantId),
+                                                   routerExternal,
+                                                   isType(type),
+                                                   PhysicalNetwork
+                                                           .physicalNetwork(physicalNetwork),
+                                                   SegmentationId
+                                                           .segmentationId(segmentationId));
+                networksMap.putIfAbsent(TenantNetworkId.networkId(id), network);
+            }
+        }
+        return Collections.unmodifiableCollection(networksMap.values());
+    }
+
+    /**
+     * Returns the specified item if that items is null; otherwise throws not
+     * found exception.
+     *
+     * @param item item to check
+     * @param <T> item type
+     * @param message not found message
+     * @return item if not null
+     * @throws org.onlab.util.ItemNotFoundException if item is null
+     */
+    protected <T> T nullIsNotFound(T item, String message) {
+        if (item == null) {
+            throw new ItemNotFoundException(message);
+        }
+        return item;
+    }
+}
diff --git a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
index 1cb1444..d0b7ed2 100644
--- a/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
+++ b/apps/vtnweb/src/main/java/org/onosproject/vtnweb/resources/VirtualPortWebResource.java
@@ -1,410 +1,410 @@
-/*
- * 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.vtnweb.resources;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
-import static javax.ws.rs.core.Response.Status.OK;
-
-import java.io.InputStream;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.util.ItemNotFoundException;
-import org.onosproject.net.DeviceId;
-import org.onosproject.rest.AbstractWebResource;
-import org.onosproject.vtnrsc.AllowedAddressPair;
-import org.onosproject.vtnrsc.BindingHostId;
-import org.onosproject.vtnrsc.DefaultVirtualPort;
-import org.onosproject.vtnrsc.FixedIp;
-import org.onosproject.vtnrsc.SecurityGroup;
-import org.onosproject.vtnrsc.SubnetId;
-import org.onosproject.vtnrsc.TenantId;
-import org.onosproject.vtnrsc.TenantNetworkId;
-import org.onosproject.vtnrsc.VirtualPort;
-import org.onosproject.vtnrsc.VirtualPort.State;
-import org.onosproject.vtnrsc.VirtualPortId;
-import org.onosproject.vtnrsc.virtualport.VirtualPortService;
-import org.onosproject.vtnrsc.web.VirtualPortCodec;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
-/**
- * REST resource for interacting with the inventory of infrastructure
- * virtualPort.
- */
-@Path("ports")
-public class VirtualPortWebResource extends AbstractWebResource {
-    public static final String VPORT_NOT_FOUND = "VirtualPort is not found";
-    public static final String VPORT_ID_EXIST = "VirtualPort id is exist";
-    public static final String VPORT_ID_NOT_EXIST = "VirtualPort id is not exist";
-    public static final String JSON_NOT_NULL = "JsonNode can not be null";
-    protected static final Logger log = LoggerFactory
-            .getLogger(VirtualPortService.class);
-
-    @GET
-    @Produces({ MediaType.APPLICATION_JSON })
-    public Response getPorts() {
-        Iterable<VirtualPort> virtualPorts = get(VirtualPortService.class)
-                .getPorts();
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("ports", new VirtualPortCodec().encode(virtualPorts, this));
-        return ok(result.toString()).build();
-    }
-
-    @GET
-    @Path("{id}")
-    @Produces({ MediaType.APPLICATION_JSON })
-    public Response getportsById(@PathParam("id") String id) {
-
-        if (!get(VirtualPortService.class).exists(VirtualPortId.portId(id))) {
-            return ok("The virtualPort does not exists").build();
-        }
-        VirtualPort virtualPort = nullIsNotFound(get(VirtualPortService.class)
-                .getPort(VirtualPortId.portId(id)), VPORT_NOT_FOUND);
-        ObjectNode result = new ObjectMapper().createObjectNode();
-        result.set("port", new VirtualPortCodec().encode(virtualPort, this));
-        return ok(result.toString()).build();
-    }
-
-    @POST
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response createPorts(InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode cfg = mapper.readTree(input);
-            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
-            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
-                    .createPorts(vPorts), VPORT_NOT_FOUND);
-            if (!issuccess) {
-                return Response.status(INTERNAL_SERVER_ERROR)
-                        .entity(VPORT_ID_NOT_EXIST).build();
-            }
-            return Response.status(OK).entity(issuccess.toString()).build();
-        } catch (Exception e) {
-            log.error("Creates VirtualPort failed because of exception {}",
-                      e.toString());
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @Path("{portUUID}")
-    @DELETE
-    public Response deletePorts(@PathParam("portUUID") String id) {
-        Set<VirtualPortId> vPortIds = new HashSet<>();
-        try {
-            if (id != null) {
-                vPortIds.add(VirtualPortId.portId(id));
-            }
-            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
-                    .removePorts(vPortIds), VPORT_NOT_FOUND);
-            if (!issuccess) {
-                return Response.status(INTERNAL_SERVER_ERROR)
-                        .entity(VPORT_ID_NOT_EXIST).build();
-            }
-            return Response.status(OK).entity(issuccess.toString()).build();
-        } catch (Exception e) {
-            log.error("Deletes VirtualPort failed because of exception {}",
-                      e.toString());
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    @PUT
-    @Path("{id}")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @Produces(MediaType.APPLICATION_JSON)
-    public Response updatePorts(@PathParam("id") String id, InputStream input) {
-        try {
-            ObjectMapper mapper = new ObjectMapper();
-            JsonNode cfg = mapper.readTree(input);
-            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
-            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
-                    .updatePorts(vPorts), VPORT_NOT_FOUND);
-            if (!issuccess) {
-                return Response.status(INTERNAL_SERVER_ERROR)
-                        .entity(VPORT_ID_NOT_EXIST).build();
-            }
-            return Response.status(OK).entity(issuccess.toString()).build();
-        } catch (Exception e) {
-            log.error("Updates failed because of exception {}", e.toString());
-            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
-                    .build();
-        }
-    }
-
-    /**
-     * Returns a Object of the currently known infrastructure virtualPort.
-     *
-     * @param vPortNode the virtualPort json node
-     * @return a collection of virtualPorts
-     */
-    public Iterable<VirtualPort> createOrUpdateByInputStream(JsonNode vPortNode) {
-        checkNotNull(vPortNode, JSON_NOT_NULL);
-        JsonNode vPortNodes = vPortNode.get("ports");
-        if (vPortNodes == null) {
-            vPortNodes = vPortNode.get("port");
-        }
-        if (vPortNodes.isArray()) {
-            return changeJsonToPorts(vPortNodes);
-        } else {
-            return changeJsonToPort(vPortNodes);
-        }
-    }
-
-    /**
-     * Returns the iterable collection of virtualports from subnetNodes.
-     *
-     * @param vPortNodes the virtualPort json node
-     * @return virtualPorts a collection of virtualPorts
-     */
-    public Iterable<VirtualPort> changeJsonToPorts(JsonNode vPortNodes) {
-        checkNotNull(vPortNodes, JSON_NOT_NULL);
-        Map<VirtualPortId, VirtualPort> portMap = new HashMap<>();
-        Map<String, String> strMap = new HashMap<>();
-        for (JsonNode vPortnode : vPortNodes) {
-            VirtualPortId id = VirtualPortId.portId(vPortnode.get("id")
-                    .asText());
-            String name = vPortnode.get("name").asText();
-            TenantId tenantId = TenantId.tenantId(vPortnode.get("tenant_id")
-                    .asText());
-            TenantNetworkId networkId = TenantNetworkId.networkId(vPortnode
-                    .get("network_id").asText());
-            checkArgument(vPortnode.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
-            Boolean adminStateUp = vPortnode.get("admin_state_up").asBoolean();
-            String state = vPortnode.get("status").asText();
-            MacAddress macAddress = MacAddress.valueOf(vPortnode
-                    .get("mac_address").asText());
-            DeviceId deviceId = DeviceId.deviceId(vPortnode.get("device_id")
-                    .asText());
-            String deviceOwner = vPortnode.get("device_owner").asText();
-            JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
-            Set<FixedIp> fixedIps = new HashSet<>();
-            for (JsonNode fixedIpNode : fixedIpNodes) {
-                FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
-                fixedIps.add(fixedIp);
-            }
-
-            BindingHostId bindingHostId = BindingHostId
-                    .bindingHostId(vPortnode.get("binding:host_id").asText());
-            String bindingVnicType = vPortnode.get("binding:vnic_type")
-                    .asText();
-            String bindingVifType = vPortnode.get("binding:vif_type").asText();
-            String bindingVifDetails = vPortnode.get("binding:vif_details")
-                    .asText();
-            JsonNode allowedAddressPairJsonNode = vPortnode
-                    .get("allowed_address_pairs");
-            Collection<AllowedAddressPair> allowedAddressPairs =
-                    jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
-            JsonNode securityGroupNode = vPortnode.get("security_groups");
-            Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
-            strMap.put("name", name);
-            strMap.put("deviceOwner", deviceOwner);
-            strMap.put("bindingVnicType", bindingVnicType);
-            strMap.put("bindingVifType", bindingVifType);
-            strMap.put("bindingVifDetails", bindingVifDetails);
-            VirtualPort vPort = new DefaultVirtualPort(id, networkId,
-                                                       adminStateUp, strMap,
-                                                       isState(state),
-                                                       macAddress, tenantId,
-                                                       deviceId, fixedIps,
-                                                       bindingHostId,
-                                                       Sets.newHashSet(allowedAddressPairs),
-                                                       Sets.newHashSet(securityGroups));
-            portMap.put(id, vPort);
-        }
-        return Collections.unmodifiableCollection(portMap.values());
-    }
-
-    /**
-     * Returns a collection of virtualPorts from subnetNodes.
-     *
-     * @param vPortNodes the virtualPort json node
-     * @return virtualPorts a collection of virtualPorts
-     */
-    public Iterable<VirtualPort> changeJsonToPort(JsonNode vPortNodes) {
-        checkNotNull(vPortNodes, JSON_NOT_NULL);
-        Map<VirtualPortId, VirtualPort> vportMap = new HashMap<>();
-        Map<String, String> strMap = new HashMap<>();
-        VirtualPortId id = VirtualPortId.portId(vPortNodes.get("id").asText());
-        String name = vPortNodes.get("name").asText();
-        TenantId tenantId = TenantId.tenantId(vPortNodes.get("tenant_id")
-                .asText());
-        TenantNetworkId networkId = TenantNetworkId.networkId(vPortNodes
-                .get("network_id").asText());
-        Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
-        String state = vPortNodes.get("status").asText();
-        MacAddress macAddress = MacAddress.valueOf(vPortNodes
-                .get("mac_address").asText());
-        DeviceId deviceId = DeviceId.deviceId(vPortNodes.get("device_id")
-                .asText());
-        String deviceOwner = vPortNodes.get("device_owner").asText();
-        JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
-        Set<FixedIp> fixedIps = new HashSet<>();
-        for (JsonNode fixedIpNode : fixedIpNodes) {
-            FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
-            fixedIps.add(fixedIp);
-        }
-
-        BindingHostId bindingHostId = BindingHostId
-                .bindingHostId(vPortNodes.get("binding:host_id").asText());
-        String bindingVnicType = vPortNodes.get("binding:vnic_type").asText();
-        String bindingVifType = vPortNodes.get("binding:vif_type").asText();
-        String bindingVifDetails = vPortNodes.get("binding:vif_details")
-                .asText();
-        JsonNode allowedAddressPairJsonNode = vPortNodes
-                .get("allowed_address_pairs");
-        Collection<AllowedAddressPair> allowedAddressPairs =
-                jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
-        JsonNode securityGroupNode = vPortNodes.get("security_groups");
-        Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
-        strMap.put("name", name);
-        strMap.put("deviceOwner", deviceOwner);
-        strMap.put("bindingVnicType", bindingVnicType);
-        strMap.put("bindingVifType", bindingVifType);
-        strMap.put("bindingVifDetails", bindingVifDetails);
-        VirtualPort vPort = new DefaultVirtualPort(id, networkId, adminStateUp,
-                                                   strMap, isState(state),
-                                                   macAddress, tenantId,
-                                                   deviceId, fixedIps,
-                                                   bindingHostId,
-                                                   Sets.newHashSet(allowedAddressPairs),
-                                                   Sets.newHashSet(securityGroups));
-        vportMap.put(id, vPort);
-
-        return Collections.unmodifiableCollection(vportMap.values());
-    }
-
-    /**
-     * Returns a Object of the currently known infrastructure virtualPort.
-     *
-     * @param allowedAddressPairs the allowedAddressPairs json node
-     * @return a collection of allowedAddressPair
-     */
-    public Collection<AllowedAddressPair> jsonNodeToAllowedAddressPair(JsonNode allowedAddressPairs) {
-        checkNotNull(allowedAddressPairs, JSON_NOT_NULL);
-        ConcurrentMap<Integer, AllowedAddressPair> allowMaps = Maps
-                .newConcurrentMap();
-        int i = 0;
-        for (JsonNode node : allowedAddressPairs) {
-            IpAddress ip = IpAddress.valueOf(node.get("ip_address").asText());
-            MacAddress mac = MacAddress.valueOf(node.get("mac_address")
-                    .asText());
-            AllowedAddressPair allows = AllowedAddressPair
-                    .allowedAddressPair(ip, mac);
-            allowMaps.put(i, allows);
-            i++;
-        }
-        log.debug("The jsonNode of allowedAddressPairallow is {}"
-                + allowedAddressPairs.toString());
-        return Collections.unmodifiableCollection(allowMaps.values());
-    }
-
-    /**
-     * Returns a collection of virtualPorts.
-     *
-     * @param securityGroups the virtualPort jsonnode
-     * @return a collection of securityGroups
-     */
-    public Collection<SecurityGroup> jsonNodeToSecurityGroup(JsonNode securityGroups) {
-        checkNotNull(securityGroups, JSON_NOT_NULL);
-        ConcurrentMap<Integer, SecurityGroup> securMaps = Maps
-                .newConcurrentMap();
-        int i = 0;
-        for (JsonNode node : securityGroups) {
-            SecurityGroup securityGroup = SecurityGroup
-                    .securityGroup(node.asText());
-            securMaps.put(i, securityGroup);
-            i++;
-        }
-        return Collections.unmodifiableCollection(securMaps.values());
-    }
-
-    /**
-     * Returns a collection of fixedIps.
-     *
-     * @param fixedIpNode the fixedIp jsonnode
-     * @return a collection of SecurityGroup
-     */
-    public FixedIp jsonNodeToFixedIps(JsonNode fixedIpNode) {
-        SubnetId subnetId = SubnetId.subnetId(fixedIpNode.get("subnet_id")
-                .asText());
-        IpAddress ipAddress = IpAddress.valueOf(fixedIpNode.get("ip_address")
-                .asText());
-        FixedIp fixedIps = FixedIp.fixedIp(subnetId, ipAddress);
-        return fixedIps;
-    }
-
-    /**
-     * Returns VirtualPort State.
-     *
-     * @param state the virtualport state
-     * @return the virtualPort state
-     */
-    private State isState(String state) {
-        if (state.equals("ACTIVE")) {
-            return VirtualPort.State.ACTIVE;
-        } else {
-            return VirtualPort.State.DOWN;
-        }
-
-    }
-
-    /**
-     * Returns the specified item if that items is null; otherwise throws not
-     * found exception.
-     *
-     * @param item item to check
-     * @param <T> item type
-     * @param message not found message
-     * @return item if not null
-     * @throws org.onlab.util.ItemNotFoundException if item is null
-     */
-    protected <T> T nullIsNotFound(T item, String message) {
-        if (item == null) {
-            throw new ItemNotFoundException(message);
-        }
-        return item;
-    }
-}
+/*
+ * 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.vtnweb.resources;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
+import static javax.ws.rs.core.Response.Status.OK;
+
+import java.io.InputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.net.DeviceId;
+import org.onosproject.rest.AbstractWebResource;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+import org.onosproject.vtnrsc.BindingHostId;
+import org.onosproject.vtnrsc.DefaultVirtualPort;
+import org.onosproject.vtnrsc.FixedIp;
+import org.onosproject.vtnrsc.SecurityGroup;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPort.State;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.onosproject.vtnrsc.web.VirtualPortCodec;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+/**
+ * REST resource for interacting with the inventory of infrastructure
+ * virtualPort.
+ */
+@Path("ports")
+public class VirtualPortWebResource extends AbstractWebResource {
+    public static final String VPORT_NOT_FOUND = "VirtualPort is not found";
+    public static final String VPORT_ID_EXIST = "VirtualPort id is exist";
+    public static final String VPORT_ID_NOT_EXIST = "VirtualPort id is not exist";
+    public static final String JSON_NOT_NULL = "JsonNode can not be null";
+    protected static final Logger log = LoggerFactory
+            .getLogger(VirtualPortService.class);
+
+    @GET
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response getPorts() {
+        Iterable<VirtualPort> virtualPorts = get(VirtualPortService.class)
+                .getPorts();
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("ports", new VirtualPortCodec().encode(virtualPorts, this));
+        return ok(result.toString()).build();
+    }
+
+    @GET
+    @Path("{id}")
+    @Produces({ MediaType.APPLICATION_JSON })
+    public Response getportsById(@PathParam("id") String id) {
+
+        if (!get(VirtualPortService.class).exists(VirtualPortId.portId(id))) {
+            return ok("The virtualPort does not exists").build();
+        }
+        VirtualPort virtualPort = nullIsNotFound(get(VirtualPortService.class)
+                .getPort(VirtualPortId.portId(id)), VPORT_NOT_FOUND);
+        ObjectNode result = new ObjectMapper().createObjectNode();
+        result.set("port", new VirtualPortCodec().encode(virtualPort, this));
+        return ok(result.toString()).build();
+    }
+
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response createPorts(InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
+            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
+                    .createPorts(vPorts), VPORT_NOT_FOUND);
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(VPORT_ID_NOT_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Creates VirtualPort failed because of exception {}",
+                      e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @Path("{portUUID}")
+    @DELETE
+    public Response deletePorts(@PathParam("portUUID") String id) {
+        Set<VirtualPortId> vPortIds = new HashSet<>();
+        try {
+            if (id != null) {
+                vPortIds.add(VirtualPortId.portId(id));
+            }
+            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
+                    .removePorts(vPortIds), VPORT_NOT_FOUND);
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(VPORT_ID_NOT_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Deletes VirtualPort failed because of exception {}",
+                      e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    @PUT
+    @Path("{id}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response updatePorts(@PathParam("id") String id, InputStream input) {
+        try {
+            ObjectMapper mapper = new ObjectMapper();
+            JsonNode cfg = mapper.readTree(input);
+            Iterable<VirtualPort> vPorts = createOrUpdateByInputStream(cfg);
+            Boolean issuccess = nullIsNotFound(get(VirtualPortService.class)
+                    .updatePorts(vPorts), VPORT_NOT_FOUND);
+            if (!issuccess) {
+                return Response.status(INTERNAL_SERVER_ERROR)
+                        .entity(VPORT_ID_NOT_EXIST).build();
+            }
+            return Response.status(OK).entity(issuccess.toString()).build();
+        } catch (Exception e) {
+            log.error("Updates failed because of exception {}", e.toString());
+            return Response.status(INTERNAL_SERVER_ERROR).entity(e.toString())
+                    .build();
+        }
+    }
+
+    /**
+     * Returns a Object of the currently known infrastructure virtualPort.
+     *
+     * @param vPortNode the virtualPort json node
+     * @return a collection of virtualPorts
+     */
+    public Iterable<VirtualPort> createOrUpdateByInputStream(JsonNode vPortNode) {
+        checkNotNull(vPortNode, JSON_NOT_NULL);
+        JsonNode vPortNodes = vPortNode.get("ports");
+        if (vPortNodes == null) {
+            vPortNodes = vPortNode.get("port");
+        }
+        if (vPortNodes.isArray()) {
+            return changeJsonToPorts(vPortNodes);
+        } else {
+            return changeJsonToPort(vPortNodes);
+        }
+    }
+
+    /**
+     * Returns the iterable collection of virtualports from subnetNodes.
+     *
+     * @param vPortNodes the virtualPort json node
+     * @return virtualPorts a collection of virtualPorts
+     */
+    public Iterable<VirtualPort> changeJsonToPorts(JsonNode vPortNodes) {
+        checkNotNull(vPortNodes, JSON_NOT_NULL);
+        Map<VirtualPortId, VirtualPort> portMap = new HashMap<>();
+        Map<String, String> strMap = new HashMap<>();
+        for (JsonNode vPortnode : vPortNodes) {
+            VirtualPortId id = VirtualPortId.portId(vPortnode.get("id")
+                    .asText());
+            String name = vPortnode.get("name").asText();
+            TenantId tenantId = TenantId.tenantId(vPortnode.get("tenant_id")
+                    .asText());
+            TenantNetworkId networkId = TenantNetworkId.networkId(vPortnode
+                    .get("network_id").asText());
+            checkArgument(vPortnode.get("admin_state_up").isBoolean(), "admin_state_up should be boolean");
+            Boolean adminStateUp = vPortnode.get("admin_state_up").asBoolean();
+            String state = vPortnode.get("status").asText();
+            MacAddress macAddress = MacAddress.valueOf(vPortnode
+                    .get("mac_address").asText());
+            DeviceId deviceId = DeviceId.deviceId(vPortnode.get("device_id")
+                    .asText());
+            String deviceOwner = vPortnode.get("device_owner").asText();
+            JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
+            Set<FixedIp> fixedIps = new HashSet<>();
+            for (JsonNode fixedIpNode : fixedIpNodes) {
+                FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
+                fixedIps.add(fixedIp);
+            }
+
+            BindingHostId bindingHostId = BindingHostId
+                    .bindingHostId(vPortnode.get("binding:host_id").asText());
+            String bindingVnicType = vPortnode.get("binding:vnic_type")
+                    .asText();
+            String bindingVifType = vPortnode.get("binding:vif_type").asText();
+            String bindingVifDetails = vPortnode.get("binding:vif_details")
+                    .asText();
+            JsonNode allowedAddressPairJsonNode = vPortnode
+                    .get("allowed_address_pairs");
+            Collection<AllowedAddressPair> allowedAddressPairs =
+                    jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
+            JsonNode securityGroupNode = vPortnode.get("security_groups");
+            Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
+            strMap.put("name", name);
+            strMap.put("deviceOwner", deviceOwner);
+            strMap.put("bindingVnicType", bindingVnicType);
+            strMap.put("bindingVifType", bindingVifType);
+            strMap.put("bindingVifDetails", bindingVifDetails);
+            VirtualPort vPort = new DefaultVirtualPort(id, networkId,
+                                                       adminStateUp, strMap,
+                                                       isState(state),
+                                                       macAddress, tenantId,
+                                                       deviceId, fixedIps,
+                                                       bindingHostId,
+                                                       Sets.newHashSet(allowedAddressPairs),
+                                                       Sets.newHashSet(securityGroups));
+            portMap.put(id, vPort);
+        }
+        return Collections.unmodifiableCollection(portMap.values());
+    }
+
+    /**
+     * Returns a collection of virtualPorts from subnetNodes.
+     *
+     * @param vPortNodes the virtualPort json node
+     * @return virtualPorts a collection of virtualPorts
+     */
+    public Iterable<VirtualPort> changeJsonToPort(JsonNode vPortNodes) {
+        checkNotNull(vPortNodes, JSON_NOT_NULL);
+        Map<VirtualPortId, VirtualPort> vportMap = new HashMap<>();
+        Map<String, String> strMap = new HashMap<>();
+        VirtualPortId id = VirtualPortId.portId(vPortNodes.get("id").asText());
+        String name = vPortNodes.get("name").asText();
+        TenantId tenantId = TenantId.tenantId(vPortNodes.get("tenant_id")
+                .asText());
+        TenantNetworkId networkId = TenantNetworkId.networkId(vPortNodes
+                .get("network_id").asText());
+        Boolean adminStateUp = vPortNodes.get("admin_state_up").asBoolean();
+        String state = vPortNodes.get("status").asText();
+        MacAddress macAddress = MacAddress.valueOf(vPortNodes
+                .get("mac_address").asText());
+        DeviceId deviceId = DeviceId.deviceId(vPortNodes.get("device_id")
+                .asText());
+        String deviceOwner = vPortNodes.get("device_owner").asText();
+        JsonNode fixedIpNodes = vPortNodes.get("fixed_ips");
+        Set<FixedIp> fixedIps = new HashSet<>();
+        for (JsonNode fixedIpNode : fixedIpNodes) {
+            FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
+            fixedIps.add(fixedIp);
+        }
+
+        BindingHostId bindingHostId = BindingHostId
+                .bindingHostId(vPortNodes.get("binding:host_id").asText());
+        String bindingVnicType = vPortNodes.get("binding:vnic_type").asText();
+        String bindingVifType = vPortNodes.get("binding:vif_type").asText();
+        String bindingVifDetails = vPortNodes.get("binding:vif_details")
+                .asText();
+        JsonNode allowedAddressPairJsonNode = vPortNodes
+                .get("allowed_address_pairs");
+        Collection<AllowedAddressPair> allowedAddressPairs =
+                jsonNodeToAllowedAddressPair(allowedAddressPairJsonNode);
+        JsonNode securityGroupNode = vPortNodes.get("security_groups");
+        Collection<SecurityGroup> securityGroups = jsonNodeToSecurityGroup(securityGroupNode);
+        strMap.put("name", name);
+        strMap.put("deviceOwner", deviceOwner);
+        strMap.put("bindingVnicType", bindingVnicType);
+        strMap.put("bindingVifType", bindingVifType);
+        strMap.put("bindingVifDetails", bindingVifDetails);
+        VirtualPort vPort = new DefaultVirtualPort(id, networkId, adminStateUp,
+                                                   strMap, isState(state),
+                                                   macAddress, tenantId,
+                                                   deviceId, fixedIps,
+                                                   bindingHostId,
+                                                   Sets.newHashSet(allowedAddressPairs),
+                                                   Sets.newHashSet(securityGroups));
+        vportMap.put(id, vPort);
+
+        return Collections.unmodifiableCollection(vportMap.values());
+    }
+
+    /**
+     * Returns a Object of the currently known infrastructure virtualPort.
+     *
+     * @param allowedAddressPairs the allowedAddressPairs json node
+     * @return a collection of allowedAddressPair
+     */
+    public Collection<AllowedAddressPair> jsonNodeToAllowedAddressPair(JsonNode allowedAddressPairs) {
+        checkNotNull(allowedAddressPairs, JSON_NOT_NULL);
+        ConcurrentMap<Integer, AllowedAddressPair> allowMaps = Maps
+                .newConcurrentMap();
+        int i = 0;
+        for (JsonNode node : allowedAddressPairs) {
+            IpAddress ip = IpAddress.valueOf(node.get("ip_address").asText());
+            MacAddress mac = MacAddress.valueOf(node.get("mac_address")
+                    .asText());
+            AllowedAddressPair allows = AllowedAddressPair
+                    .allowedAddressPair(ip, mac);
+            allowMaps.put(i, allows);
+            i++;
+        }
+        log.debug("The jsonNode of allowedAddressPairallow is {}"
+                + allowedAddressPairs.toString());
+        return Collections.unmodifiableCollection(allowMaps.values());
+    }
+
+    /**
+     * Returns a collection of virtualPorts.
+     *
+     * @param securityGroups the virtualPort jsonnode
+     * @return a collection of securityGroups
+     */
+    public Collection<SecurityGroup> jsonNodeToSecurityGroup(JsonNode securityGroups) {
+        checkNotNull(securityGroups, JSON_NOT_NULL);
+        ConcurrentMap<Integer, SecurityGroup> securMaps = Maps
+                .newConcurrentMap();
+        int i = 0;
+        for (JsonNode node : securityGroups) {
+            SecurityGroup securityGroup = SecurityGroup
+                    .securityGroup(node.asText());
+            securMaps.put(i, securityGroup);
+            i++;
+        }
+        return Collections.unmodifiableCollection(securMaps.values());
+    }
+
+    /**
+     * Returns a collection of fixedIps.
+     *
+     * @param fixedIpNode the fixedIp jsonnode
+     * @return a collection of SecurityGroup
+     */
+    public FixedIp jsonNodeToFixedIps(JsonNode fixedIpNode) {
+        SubnetId subnetId = SubnetId.subnetId(fixedIpNode.get("subnet_id")
+                .asText());
+        IpAddress ipAddress = IpAddress.valueOf(fixedIpNode.get("ip_address")
+                .asText());
+        FixedIp fixedIps = FixedIp.fixedIp(subnetId, ipAddress);
+        return fixedIps;
+    }
+
+    /**
+     * Returns VirtualPort State.
+     *
+     * @param state the virtualport state
+     * @return the virtualPort state
+     */
+    private State isState(String state) {
+        if (state.equals("ACTIVE")) {
+            return VirtualPort.State.ACTIVE;
+        } else {
+            return VirtualPort.State.DOWN;
+        }
+
+    }
+
+    /**
+     * Returns the specified item if that items is null; otherwise throws not
+     * found exception.
+     *
+     * @param item item to check
+     * @param <T> item type
+     * @param message not found message
+     * @return item if not null
+     * @throws org.onlab.util.ItemNotFoundException if item is null
+     */
+    protected <T> T nullIsNotFound(T item, String message) {
+        if (item == null) {
+            throw new ItemNotFoundException(message);
+        }
+        return item;
+    }
+}
diff --git a/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java b/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
index fcaffe2..e833b2d 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/host/impl/ECHostStore.java
@@ -1,282 +1,282 @@
-/*
- * 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.store.host.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onosproject.net.DefaultAnnotations.merge;
-import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
-import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED;
-import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
-import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Objects;
-import java.util.Set;
-import java.util.function.Predicate;
-import java.util.stream.Collectors;
-
-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.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.VlanId;
-import org.onlab.util.KryoNamespace;
-import org.onosproject.net.Annotations;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.DefaultHost;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.host.HostDescription;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostStore;
-import org.onosproject.net.host.HostStoreDelegate;
-import org.onosproject.net.host.PortAddresses;
-import org.onosproject.net.host.HostEvent.Type;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.store.AbstractStore;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.EventuallyConsistentMapEvent;
-import org.onosproject.store.service.EventuallyConsistentMapListener;
-import org.onosproject.store.service.LogicalClockService;
-import org.onosproject.store.service.StorageService;
-import org.slf4j.Logger;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableMultimap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-import com.google.common.collect.Sets;
-
-/**
- * Manages the inventory of hosts using a {@code EventuallyConsistentMap}.
- */
-@Component(immediate = true)
-@Service
-public class ECHostStore
-    extends AbstractStore<HostEvent, HostStoreDelegate>
-    implements HostStore {
-
-    private final Logger log = getLogger(getClass());
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected StorageService storageService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected LogicalClockService clockService;
-
-    // Hosts tracked by their location
-    private final SetMultimap<ConnectPoint, Host> locations =
-            Multimaps.synchronizedSetMultimap(
-                    HashMultimap.<ConnectPoint, Host>create());
-
-    private final SetMultimap<ConnectPoint, PortAddresses> portAddresses =
-            Multimaps.synchronizedSetMultimap(
-                    HashMultimap.<ConnectPoint, PortAddresses>create());
-
-    private EventuallyConsistentMap<HostId, DefaultHost> hosts;
-
-    private EventuallyConsistentMapListener<HostId, DefaultHost> hostLocationTracker =
-            new HostLocationTracker();
-
-    @Activate
-    public void activate() {
-        KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder()
-                .register(KryoNamespaces.API);
-
-        hosts = storageService.<HostId, DefaultHost>eventuallyConsistentMapBuilder()
-                .withName("onos-hosts")
-                .withSerializer(hostSerializer)
-                .withTimestampProvider((k, v) -> clockService.getTimestamp())
-                .build();
-
-        hosts.addListener(hostLocationTracker);
-
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        hosts.removeListener(hostLocationTracker);
-        hosts.destroy();
-        locations.clear();
-        portAddresses.clear();
-
-        log.info("Stopped");
-    }
-
-    @Override
-    public HostEvent createOrUpdateHost(ProviderId providerId,
-            HostId hostId,
-            HostDescription hostDescription) {
-        DefaultHost currentHost = hosts.get(hostId);
-        if (currentHost == null) {
-            DefaultHost newhost = new DefaultHost(
-                        providerId,
-                        hostId,
-                        hostDescription.hwAddress(),
-                        hostDescription.vlan(),
-                        hostDescription.location(),
-                        ImmutableSet.copyOf(hostDescription.ipAddress()),
-                        hostDescription.annotations());
-            hosts.put(hostId, newhost);
-            return new HostEvent(HOST_ADDED, newhost);
-        }
-        return updateHost(providerId, hostId, hostDescription, currentHost);
-    }
-
-    @Override
-    public HostEvent removeHost(HostId hostId) {
-        Host host = hosts.remove(hostId);
-        return host != null ? new HostEvent(HOST_REMOVED, host) : null;
-    }
-
-    @Override
-    public int getHostCount() {
-        return hosts.size();
-    }
-
-    @Override
-    public Iterable<Host> getHosts() {
-        return ImmutableSet.copyOf(hosts.values());
-    }
-
-    @Override
-    public Host getHost(HostId hostId) {
-        return hosts.get(hostId);
-    }
-
-    @Override
-    public Set<Host> getHosts(VlanId vlanId) {
-        return filter(hosts.values(), host -> Objects.equals(host.vlan(), vlanId));
-    }
-
-    @Override
-    public Set<Host> getHosts(MacAddress mac) {
-        return filter(hosts.values(), host -> Objects.equals(host.mac(), mac));
-    }
-
-    @Override
-    public Set<Host> getHosts(IpAddress ip) {
-        return filter(hosts.values(), host -> host.ipAddresses().contains(ip));
-    }
-
-    @Override
-    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
-        return ImmutableSet.copyOf(locations.get(connectPoint));
-    }
-
-    @Override
-    public Set<Host> getConnectedHosts(DeviceId deviceId) {
-        return ImmutableMultimap.copyOf(locations)
-                .entries()
-                .stream()
-                .filter(entry -> entry.getKey().deviceId().equals(deviceId))
-                .map(entry -> entry.getValue())
-                .collect(Collectors.toSet());
-    }
-
-    @Override
-    public void updateAddressBindings(PortAddresses addresses) {
-        portAddresses.put(addresses.connectPoint(), addresses);
-    }
-
-    @Override
-    public void removeAddressBindings(PortAddresses addresses) {
-        portAddresses.remove(addresses.connectPoint(), addresses);
-    }
-
-    @Override
-    public void clearAddressBindings(ConnectPoint connectPoint) {
-        portAddresses.removeAll(connectPoint);
-    }
-
-    @Override
-    public Set<PortAddresses> getAddressBindings() {
-        return ImmutableSet.copyOf(portAddresses.values());
-    }
-
-    @Override
-    public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
-        synchronized (portAddresses) {
-            Set<PortAddresses> addresses = portAddresses.get(connectPoint);
-            return addresses == null ? Collections.emptySet() : ImmutableSet.copyOf(addresses);
-        }
-    }
-
-    private Set<Host> filter(Collection<DefaultHost> collection, Predicate<DefaultHost> predicate) {
-        return collection.stream().filter(predicate).collect(Collectors.toSet());
-    }
-
-    // checks for type of update to host, sends appropriate event
-    private HostEvent updateHost(ProviderId providerId,
-                                 HostId hostId,
-                                 HostDescription descr,
-                                 DefaultHost currentHost) {
-
-        final boolean hostMoved = !currentHost.location().equals(descr.location());
-        if (hostMoved ||
-                !currentHost.ipAddresses().containsAll(descr.ipAddress()) ||
-                !descr.annotations().keys().isEmpty()) {
-
-            Set<IpAddress> addresses = Sets.newHashSet(currentHost.ipAddresses());
-            addresses.addAll(descr.ipAddress());
-            Annotations annotations = merge((DefaultAnnotations) currentHost.annotations(),
-                                            descr.annotations());
-
-            DefaultHost updatedHost = new DefaultHost(providerId, currentHost.id(),
-                                                currentHost.mac(), currentHost.vlan(),
-                                                descr.location(),
-                                                addresses,
-                                                annotations);
-
-            // TODO: We need a way to detect conflicting changes and abort update.
-            hosts.put(hostId, updatedHost);
-            locations.remove(currentHost.location(), currentHost);
-            locations.put(updatedHost.location(), updatedHost);
-
-            HostEvent.Type eventType = hostMoved ? Type.HOST_MOVED : Type.HOST_UPDATED;
-            return new HostEvent(eventType, updatedHost);
-        }
-        return null;
-    }
-
-    private class HostLocationTracker implements EventuallyConsistentMapListener<HostId, DefaultHost> {
-        @Override
-        public void event(EventuallyConsistentMapEvent<HostId, DefaultHost> event) {
-            DefaultHost host = checkNotNull(event.value());
-            if (event.type() == PUT) {
-                boolean isNew = locations.put(host.location(), host);
-                notifyDelegate(new HostEvent(isNew ? HOST_ADDED : HOST_UPDATED, host));
-            } else if (event.type() == REMOVE) {
-                if (locations.remove(host.location(), host)) {
-                    notifyDelegate(new HostEvent(HOST_REMOVED, host));
-                }
-
-            }
-        }
-    }
-}
+/*
+ * 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.store.host.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.DefaultAnnotations.merge;
+import static org.onosproject.net.host.HostEvent.Type.HOST_ADDED;
+import static org.onosproject.net.host.HostEvent.Type.HOST_REMOVED;
+import static org.onosproject.net.host.HostEvent.Type.HOST_UPDATED;
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.PUT;
+import static org.onosproject.store.service.EventuallyConsistentMapEvent.Type.REMOVE;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.net.Annotations;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultHost;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostStore;
+import org.onosproject.net.host.HostStoreDelegate;
+import org.onosproject.net.host.PortAddresses;
+import org.onosproject.net.host.HostEvent.Type;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.EventuallyConsistentMapEvent;
+import org.onosproject.store.service.EventuallyConsistentMapListener;
+import org.onosproject.store.service.LogicalClockService;
+import org.onosproject.store.service.StorageService;
+import org.slf4j.Logger;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMultimap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Multimaps;
+import com.google.common.collect.SetMultimap;
+import com.google.common.collect.Sets;
+
+/**
+ * Manages the inventory of hosts using a {@code EventuallyConsistentMap}.
+ */
+@Component(immediate = true)
+@Service
+public class ECHostStore
+    extends AbstractStore<HostEvent, HostStoreDelegate>
+    implements HostStore {
+
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected LogicalClockService clockService;
+
+    // Hosts tracked by their location
+    private final SetMultimap<ConnectPoint, Host> locations =
+            Multimaps.synchronizedSetMultimap(
+                    HashMultimap.<ConnectPoint, Host>create());
+
+    private final SetMultimap<ConnectPoint, PortAddresses> portAddresses =
+            Multimaps.synchronizedSetMultimap(
+                    HashMultimap.<ConnectPoint, PortAddresses>create());
+
+    private EventuallyConsistentMap<HostId, DefaultHost> hosts;
+
+    private EventuallyConsistentMapListener<HostId, DefaultHost> hostLocationTracker =
+            new HostLocationTracker();
+
+    @Activate
+    public void activate() {
+        KryoNamespace.Builder hostSerializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API);
+
+        hosts = storageService.<HostId, DefaultHost>eventuallyConsistentMapBuilder()
+                .withName("onos-hosts")
+                .withSerializer(hostSerializer)
+                .withTimestampProvider((k, v) -> clockService.getTimestamp())
+                .build();
+
+        hosts.addListener(hostLocationTracker);
+
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        hosts.removeListener(hostLocationTracker);
+        hosts.destroy();
+        locations.clear();
+        portAddresses.clear();
+
+        log.info("Stopped");
+    }
+
+    @Override
+    public HostEvent createOrUpdateHost(ProviderId providerId,
+            HostId hostId,
+            HostDescription hostDescription) {
+        DefaultHost currentHost = hosts.get(hostId);
+        if (currentHost == null) {
+            DefaultHost newhost = new DefaultHost(
+                        providerId,
+                        hostId,
+                        hostDescription.hwAddress(),
+                        hostDescription.vlan(),
+                        hostDescription.location(),
+                        ImmutableSet.copyOf(hostDescription.ipAddress()),
+                        hostDescription.annotations());
+            hosts.put(hostId, newhost);
+            return new HostEvent(HOST_ADDED, newhost);
+        }
+        return updateHost(providerId, hostId, hostDescription, currentHost);
+    }
+
+    @Override
+    public HostEvent removeHost(HostId hostId) {
+        Host host = hosts.remove(hostId);
+        return host != null ? new HostEvent(HOST_REMOVED, host) : null;
+    }
+
+    @Override
+    public int getHostCount() {
+        return hosts.size();
+    }
+
+    @Override
+    public Iterable<Host> getHosts() {
+        return ImmutableSet.copyOf(hosts.values());
+    }
+
+    @Override
+    public Host getHost(HostId hostId) {
+        return hosts.get(hostId);
+    }
+
+    @Override
+    public Set<Host> getHosts(VlanId vlanId) {
+        return filter(hosts.values(), host -> Objects.equals(host.vlan(), vlanId));
+    }
+
+    @Override
+    public Set<Host> getHosts(MacAddress mac) {
+        return filter(hosts.values(), host -> Objects.equals(host.mac(), mac));
+    }
+
+    @Override
+    public Set<Host> getHosts(IpAddress ip) {
+        return filter(hosts.values(), host -> host.ipAddresses().contains(ip));
+    }
+
+    @Override
+    public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
+        return ImmutableSet.copyOf(locations.get(connectPoint));
+    }
+
+    @Override
+    public Set<Host> getConnectedHosts(DeviceId deviceId) {
+        return ImmutableMultimap.copyOf(locations)
+                .entries()
+                .stream()
+                .filter(entry -> entry.getKey().deviceId().equals(deviceId))
+                .map(entry -> entry.getValue())
+                .collect(Collectors.toSet());
+    }
+
+    @Override
+    public void updateAddressBindings(PortAddresses addresses) {
+        portAddresses.put(addresses.connectPoint(), addresses);
+    }
+
+    @Override
+    public void removeAddressBindings(PortAddresses addresses) {
+        portAddresses.remove(addresses.connectPoint(), addresses);
+    }
+
+    @Override
+    public void clearAddressBindings(ConnectPoint connectPoint) {
+        portAddresses.removeAll(connectPoint);
+    }
+
+    @Override
+    public Set<PortAddresses> getAddressBindings() {
+        return ImmutableSet.copyOf(portAddresses.values());
+    }
+
+    @Override
+    public Set<PortAddresses> getAddressBindingsForPort(ConnectPoint connectPoint) {
+        synchronized (portAddresses) {
+            Set<PortAddresses> addresses = portAddresses.get(connectPoint);
+            return addresses == null ? Collections.emptySet() : ImmutableSet.copyOf(addresses);
+        }
+    }
+
+    private Set<Host> filter(Collection<DefaultHost> collection, Predicate<DefaultHost> predicate) {
+        return collection.stream().filter(predicate).collect(Collectors.toSet());
+    }
+
+    // checks for type of update to host, sends appropriate event
+    private HostEvent updateHost(ProviderId providerId,
+                                 HostId hostId,
+                                 HostDescription descr,
+                                 DefaultHost currentHost) {
+
+        final boolean hostMoved = !currentHost.location().equals(descr.location());
+        if (hostMoved ||
+                !currentHost.ipAddresses().containsAll(descr.ipAddress()) ||
+                !descr.annotations().keys().isEmpty()) {
+
+            Set<IpAddress> addresses = Sets.newHashSet(currentHost.ipAddresses());
+            addresses.addAll(descr.ipAddress());
+            Annotations annotations = merge((DefaultAnnotations) currentHost.annotations(),
+                                            descr.annotations());
+
+            DefaultHost updatedHost = new DefaultHost(providerId, currentHost.id(),
+                                                currentHost.mac(), currentHost.vlan(),
+                                                descr.location(),
+                                                addresses,
+                                                annotations);
+
+            // TODO: We need a way to detect conflicting changes and abort update.
+            hosts.put(hostId, updatedHost);
+            locations.remove(currentHost.location(), currentHost);
+            locations.put(updatedHost.location(), updatedHost);
+
+            HostEvent.Type eventType = hostMoved ? Type.HOST_MOVED : Type.HOST_UPDATED;
+            return new HostEvent(eventType, updatedHost);
+        }
+        return null;
+    }
+
+    private class HostLocationTracker implements EventuallyConsistentMapListener<HostId, DefaultHost> {
+        @Override
+        public void event(EventuallyConsistentMapEvent<HostId, DefaultHost> event) {
+            DefaultHost host = checkNotNull(event.value());
+            if (event.type() == PUT) {
+                boolean isNew = locations.put(host.location(), host);
+                notifyDelegate(new HostEvent(isNew ? HOST_ADDED : HOST_UPDATED, host));
+            } else if (event.type() == REMOVE) {
+                if (locations.remove(host.location(), host)) {
+                    notifyDelegate(new HostEvent(HOST_REMOVED, host));
+                }
+
+            }
+        }
+    }
+}
diff --git a/providers/ovsdb/host/src/main/java/org/onosproject/ovsdb/provider/host/OvsdbHostProvider.java b/providers/ovsdb/host/src/main/java/org/onosproject/ovsdb/provider/host/OvsdbHostProvider.java
index 8d2fd14..0e3e156 100644
--- a/providers/ovsdb/host/src/main/java/org/onosproject/ovsdb/provider/host/OvsdbHostProvider.java
+++ b/providers/ovsdb/host/src/main/java/org/onosproject/ovsdb/provider/host/OvsdbHostProvider.java
@@ -1,148 +1,148 @@
-/*
- * 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.provider.host;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.util.Tools.toHex;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
-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.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.HostLocation;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.SparseAnnotations;
-import org.onosproject.net.host.DefaultHostDescription;
-import org.onosproject.net.host.HostDescription;
-import org.onosproject.net.host.HostProvider;
-import org.onosproject.net.host.HostProviderRegistry;
-import org.onosproject.net.host.HostProviderService;
-import org.onosproject.net.host.HostService;
-import org.onosproject.net.provider.AbstractProvider;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.ovsdb.controller.EventSubject;
-import org.onosproject.ovsdb.controller.OvsdbController;
-import org.onosproject.ovsdb.controller.OvsdbEvent;
-import org.onosproject.ovsdb.controller.OvsdbEventListener;
-import org.onosproject.ovsdb.controller.OvsdbEventSubject;
-import org.slf4j.Logger;
-
-/**
- * Provider which uses an ovsdb controller to detect host.
- */
-@Component(immediate = true)
-@Service
-public class OvsdbHostProvider extends AbstractProvider implements HostProvider {
-    private final Logger log = getLogger(getClass());
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected HostProviderRegistry providerRegistry;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected HostService hostService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected OvsdbController controller;
-
-    private HostProviderService providerService;
-    private OvsdbEventListener innerEventListener = new InnerOvsdbEventListener();
-
-    @Activate
-    public void activate() {
-        providerService = providerRegistry.register(this);
-        controller.addOvsdbEventListener(innerEventListener);
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        providerRegistry.unregister(this);
-        providerService = null;
-        log.info("Stopped");
-    }
-
-    public OvsdbHostProvider() {
-        super(new ProviderId("ovsdb", "org.onosproject.ovsdb.provider.host"));
-    }
-
-    @Override
-    public void triggerProbe(Host host) {
-        log.info("Triggering probe on host {}", host);
-    }
-
-    private class InnerOvsdbEventListener implements OvsdbEventListener {
-
-        @Override
-        public void handle(OvsdbEvent<EventSubject> event) {
-            OvsdbEventSubject subject = null;
-            if (event.subject() instanceof OvsdbEventSubject) {
-                subject = (OvsdbEventSubject) event.subject();
-            }
-            checkNotNull(subject, "EventSubject is not null");
-            // If ifaceid is null,it indicates this is not a vm port.
-            if (subject.ifaceid() == null) {
-                return;
-            }
-            switch (event.type()) {
-            case PORT_ADDED:
-                HostId hostId = HostId.hostId(subject.hwAddress(), null);
-                DeviceId deviceId = DeviceId.deviceId(uri(subject.dpid().value()));
-                PortNumber portNumber = PortNumber.portNumber(subject
-                        .portNumber().value(), subject.portName().value());
-                HostLocation loaction = new HostLocation(deviceId, portNumber,
-                                                         0L);
-                SparseAnnotations annotations = DefaultAnnotations.builder()
-                        .set("ifaceid", subject.ifaceid().value()).build();
-                HostDescription hostDescription = new DefaultHostDescription(
-                                                                             subject.hwAddress(),
-                                                                             VlanId.vlanId(),
-                                                                             loaction,
-                                                                             annotations);
-                providerService.hostDetected(hostId, hostDescription);
-                break;
-            case PORT_REMOVED:
-                HostId host = HostId.hostId(subject.hwAddress(), null);
-                providerService.hostVanished(host);
-                break;
-            default:
-                break;
-            }
-
-        }
-
-    }
-
-    public URI uri(String value) {
-        try {
-            return new URI("of", toHex(Long.valueOf(value)), null);
-        } catch (URISyntaxException e) {
-            return null;
-        }
-    }
-}
+/*
+ * 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.provider.host;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.toHex;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.SparseAnnotations;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.onosproject.ovsdb.controller.EventSubject;
+import org.onosproject.ovsdb.controller.OvsdbController;
+import org.onosproject.ovsdb.controller.OvsdbEvent;
+import org.onosproject.ovsdb.controller.OvsdbEventListener;
+import org.onosproject.ovsdb.controller.OvsdbEventSubject;
+import org.slf4j.Logger;
+
+/**
+ * Provider which uses an ovsdb controller to detect host.
+ */
+@Component(immediate = true)
+@Service
+public class OvsdbHostProvider extends AbstractProvider implements HostProvider {
+    private final Logger log = getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostProviderRegistry providerRegistry;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected OvsdbController controller;
+
+    private HostProviderService providerService;
+    private OvsdbEventListener innerEventListener = new InnerOvsdbEventListener();
+
+    @Activate
+    public void activate() {
+        providerService = providerRegistry.register(this);
+        controller.addOvsdbEventListener(innerEventListener);
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        providerRegistry.unregister(this);
+        providerService = null;
+        log.info("Stopped");
+    }
+
+    public OvsdbHostProvider() {
+        super(new ProviderId("ovsdb", "org.onosproject.ovsdb.provider.host"));
+    }
+
+    @Override
+    public void triggerProbe(Host host) {
+        log.info("Triggering probe on host {}", host);
+    }
+
+    private class InnerOvsdbEventListener implements OvsdbEventListener {
+
+        @Override
+        public void handle(OvsdbEvent<EventSubject> event) {
+            OvsdbEventSubject subject = null;
+            if (event.subject() instanceof OvsdbEventSubject) {
+                subject = (OvsdbEventSubject) event.subject();
+            }
+            checkNotNull(subject, "EventSubject is not null");
+            // If ifaceid is null,it indicates this is not a vm port.
+            if (subject.ifaceid() == null) {
+                return;
+            }
+            switch (event.type()) {
+            case PORT_ADDED:
+                HostId hostId = HostId.hostId(subject.hwAddress(), null);
+                DeviceId deviceId = DeviceId.deviceId(uri(subject.dpid().value()));
+                PortNumber portNumber = PortNumber.portNumber(subject
+                        .portNumber().value(), subject.portName().value());
+                HostLocation loaction = new HostLocation(deviceId, portNumber,
+                                                         0L);
+                SparseAnnotations annotations = DefaultAnnotations.builder()
+                        .set("ifaceid", subject.ifaceid().value()).build();
+                HostDescription hostDescription = new DefaultHostDescription(
+                                                                             subject.hwAddress(),
+                                                                             VlanId.vlanId(),
+                                                                             loaction,
+                                                                             annotations);
+                providerService.hostDetected(hostId, hostDescription);
+                break;
+            case PORT_REMOVED:
+                HostId host = HostId.hostId(subject.hwAddress(), null);
+                providerService.hostVanished(host);
+                break;
+            default:
+                break;
+            }
+
+        }
+
+    }
+
+    public URI uri(String value) {
+        try {
+            return new URI("of", toHex(Long.valueOf(value)), null);
+        } catch (URISyntaxException e) {
+            return null;
+        }
+    }
+}
