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 6ab1b14..092ea89 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,368 +1,368 @@
-/*
- * 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 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.app.vtnrsc.DefaultTenantNetwork;
-import org.onosproject.app.vtnrsc.PhysicalNetwork;
-import org.onosproject.app.vtnrsc.SegmentationId;
-import org.onosproject.app.vtnrsc.TenantId;
-import org.onosproject.app.vtnrsc.TenantNetwork;
-import org.onosproject.app.vtnrsc.TenantNetwork.State;
-import org.onosproject.app.vtnrsc.TenantNetwork.Type;
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-import org.onosproject.app.vtnrsc.tenantnetwork.TenantNetworkService;
-import org.onosproject.app.vtnrsc.web.TenantNetworkCodec;
-import org.onosproject.rest.AbstractWebResource;
-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()
-                            .toString()))
-                    && (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<TenantNetworkId>();
-        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) {
-            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 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()
+                            .toString()))
+                    && (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<TenantNetworkId>();
+        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) {
+            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;
+    }
+}
