diff --git a/apps/vtn/src/main/java/org/onosproject/vtn/impl/VTNManager.java b/apps/vtn/src/main/java/org/onosproject/vtn/impl/VTNManager.java
index 1b2e9be..32bcc29 100644
--- a/apps/vtn/src/main/java/org/onosproject/vtn/impl/VTNManager.java
+++ b/apps/vtn/src/main/java/org/onosproject/vtn/impl/VTNManager.java
@@ -1,511 +1,511 @@
-/*
- * 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.vtn.impl;
-
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ScheduledExecutorService;
-
-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.util.KryoNamespace;
-import org.onosproject.app.vtnrsc.SegmentationId;
-import org.onosproject.app.vtnrsc.TenantNetwork;
-import org.onosproject.app.vtnrsc.VirtualPort;
-import org.onosproject.app.vtnrsc.VirtualPortId;
-import org.onosproject.app.vtnrsc.tenantnetwork.TenantNetworkService;
-import org.onosproject.app.vtnrsc.virtualport.VirtualPortService;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Host;
-import org.onosproject.net.HostId;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.behaviour.BridgeConfig;
-import org.onosproject.net.behaviour.BridgeName;
-import org.onosproject.net.behaviour.DefaultTunnelDescription;
-import org.onosproject.net.behaviour.IpTunnelEndPoint;
-import org.onosproject.net.behaviour.TunnelConfig;
-import org.onosproject.net.behaviour.TunnelDescription;
-import org.onosproject.net.behaviour.TunnelEndPoint;
-import org.onosproject.net.device.DeviceEvent;
-import org.onosproject.net.device.DeviceListener;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.DriverHandler;
-import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.flowobjective.DefaultForwardingObjective;
-import org.onosproject.net.flowobjective.FlowObjectiveService;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
-import org.onosproject.net.flowobjective.Objective;
-import org.onosproject.net.host.HostEvent;
-import org.onosproject.net.host.HostListener;
-import org.onosproject.net.host.HostService;
-import org.onosproject.store.serializers.KryoNamespaces;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.StorageService;
-import org.onosproject.store.service.WallClockTimestamp;
-import org.onosproject.vtn.VTNService;
-import org.slf4j.Logger;
-
-import com.google.common.collect.Sets;
-
-/**
- * Provides implementation of VTNService.
- */
-@Component(immediate = true)
-@Service
-public class VTNManager implements VTNService {
-    private final Logger log = getLogger(getClass());
-
-    private static final String APP_ID = "org.onosproject.app.vtn";
-    private ScheduledExecutorService backgroundService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected HostService hostService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected FlowRuleService flowRuleService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected StorageService storageService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected TenantNetworkService tenantNetworkService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected VirtualPortService virtualPortService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DriverService driverService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected FlowObjectiveService flowObjectiveService;
-    private EventuallyConsistentMap<HostId, SegmentationId> binding;
-    private ApplicationId appId;
-    private HostListener hostListener = new InnerHostListener();
-    private DeviceListener deviceListener = new InnerDeviceListener();
-    private static final String IFACEID = "ifaceid";
-    private static final String PORT_HEAD = "vxlan";
-    private static final String DEFAULT_BRIDGE_NAME = "br-int";
-    private static final String CONTROLLER_IP_KEY = "ipaddress";
-
-    @Activate
-    public void activate() {
-        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
-                .register(KryoNamespaces.API);
-        appId = coreService.registerApplication(APP_ID);
-        deviceService.addListener(deviceListener);
-        hostService.addListener(hostListener);
-        backgroundService = newSingleThreadScheduledExecutor(groupedThreads("onos-apps/vtn",
-                                                                            "manager-background"));
-        binding = storageService
-                .<HostId, SegmentationId>eventuallyConsistentMapBuilder()
-                .withName("all_tunnel").withSerializer(serializer)
-                .withTimestampProvider((k, v) -> new WallClockTimestamp())
-                .build();
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        backgroundService.shutdown();
-        binding.destroy();
-        log.info("Stopped");
-    }
-
-    @Override
-    public void onServerDetected(Device device) {
-        Iterable<Device> devices = deviceService.getAvailableDevices();
-        DriverHandler handler = driverService.createHandler(device.id());
-        BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
-        bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME));
-        String ipAddress = device.annotations().value(CONTROLLER_IP_KEY);
-        IpAddress ip = IpAddress.valueOf(ipAddress);
-        Sets.newHashSet(devices)
-                .stream()
-                .filter(d -> d.type() == Device.Type.CONTROLLER)
-                .filter(d -> !device.id().equals(d.id()))
-                .forEach(d -> {
-                             String ipAddress1 = d.annotations()
-                                     .value(CONTROLLER_IP_KEY);
-                             IpAddress ip1 = IpAddress.valueOf(ipAddress1);
-                             applyTunnelConfig(ip, ip1, handler);
-                             DriverHandler handler1 = driverService
-                                     .createHandler(d.id());
-                             applyTunnelConfig(ip1, ip, handler1);
-                         });
-    }
-
-    @Override
-    public void onServerVanished(Device device) {
-        Iterable<Device> devices = deviceService.getAvailableDevices();
-        String ipAddress = device.annotations().value(CONTROLLER_IP_KEY);
-        IpAddress dst = IpAddress.valueOf(ipAddress);
-        Sets.newHashSet(devices)
-                .stream()
-                .filter(d -> d.type() == Device.Type.CONTROLLER)
-                .filter(d -> !device.id().equals(d.id()))
-                .forEach(d -> {
-                             String ipAddress1 = d.annotations()
-                                     .value(CONTROLLER_IP_KEY);
-                             DriverHandler handler = driverService
-                                     .createHandler(d.id());
-                             IpAddress src = IpAddress.valueOf(ipAddress1);
-                             removeTunnelConfig(src, dst, handler);
-                         });
-    }
-
-    private void applyTunnelConfig(IpAddress src, IpAddress dst,
-                                   DriverHandler handler) {
-        TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(src);
-        TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dst);
-        TunnelDescription tunnel = new DefaultTunnelDescription(
-                                                                tunnelAsSrc,
-                                                                tunnelAsDst,
-                                                                TunnelDescription.Type.VXLAN,
-                                                                null);
-        TunnelConfig config = handler.behaviour(TunnelConfig.class);
-        config.createTunnel(tunnel);
-    }
-
-    private void removeTunnelConfig(IpAddress src, IpAddress dst,
-                                    DriverHandler handler) {
-        TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(src);
-        TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dst);
-        TunnelDescription tunnel = new DefaultTunnelDescription(
-                                                                tunnelAsSrc,
-                                                                tunnelAsDst,
-                                                                TunnelDescription.Type.VXLAN,
-                                                                null);
-        TunnelConfig config = handler.behaviour(TunnelConfig.class);
-        config.removeTunnel(tunnel);
-    }
-
-    @Override
-    public void onOvsDetected(Device device) {
-        programMacDefaultRules(device.id(), appId, Objective.Operation.ADD);
-        programPortDefaultRules(device.id(), appId, Objective.Operation.ADD);
-    }
-
-    @Override
-    public void onOvsVanished(Device device) {
-        programMacDefaultRules(device.id(), appId, Objective.Operation.REMOVE);
-        programPortDefaultRules(device.id(), appId, Objective.Operation.REMOVE);
-    }
-
-    @Override
-    public void onHostDetected(Host host) {
-        String ifaceId = host.annotations().value(IFACEID);
-        VirtualPortId portId = VirtualPortId.portId(ifaceId);
-        VirtualPort port = virtualPortService.getPort(portId);
-        TenantNetwork network = tenantNetworkService.getNetwork(port
-                .networkId());
-        binding.put(host.id(), network.segmentationId());
-        DeviceId deviceId = host.location().deviceId();
-        List<Port> allPorts = deviceService.getPorts(deviceId);
-        PortNumber inPort = host.location().port();
-        Set<Port> localPorts = new HashSet<>();
-        allPorts.forEach(p -> {
-            if (!p.number().name().startsWith(PORT_HEAD)) {
-                localPorts.add(p);
-            }
-        });
-        programLocalBcastRules(deviceId, network.segmentationId(), inPort,
-                               allPorts, appId, Objective.Operation.ADD);
-        programLocalOut(deviceId, network.segmentationId(), inPort, host.mac(),
-                        appId, Objective.Operation.ADD);
-        programTunnelFloodOut(deviceId, network.segmentationId(), inPort,
-                              localPorts, appId, Objective.Operation.ADD);
-        programTunnelOut(deviceId, network.segmentationId(), inPort,
-                         host.mac(), appId, Objective.Operation.ADD);
-        programLocalIn(deviceId, network.segmentationId(), inPort, host.mac(),
-                       appId, Objective.Operation.ADD);
-        programTunnelIn(deviceId, network.segmentationId(), inPort, host.mac(),
-                        appId, Objective.Operation.ADD);
-    }
-
-    @Override
-    public void onHostVanished(Host host) {
-        SegmentationId segId = binding.remove(host.id());
-        DeviceId deviceId = host.location().deviceId();
-        List<Port> allPorts = deviceService.getPorts(deviceId);
-        PortNumber inPort = host.location().port();
-        Set<Port> localPorts = new HashSet<>();
-        allPorts.forEach(p -> {
-            if (!p.number().name().startsWith(PORT_HEAD)) {
-                localPorts.add(p);
-            }
-        });
-        programLocalBcastRules(deviceId, segId, inPort, allPorts, appId,
-                               Objective.Operation.REMOVE);
-        programLocalOut(deviceId, segId, inPort, host.mac(), appId,
-                        Objective.Operation.REMOVE);
-        programTunnelFloodOut(deviceId, segId, inPort, localPorts, appId,
-                              Objective.Operation.REMOVE);
-        programTunnelOut(deviceId, segId, inPort, host.mac(), appId,
-                         Objective.Operation.REMOVE);
-        programLocalIn(deviceId, segId, inPort, host.mac(), appId,
-                       Objective.Operation.REMOVE);
-        programTunnelIn(deviceId, segId, inPort, host.mac(), appId,
-                        Objective.Operation.REMOVE);
-    }
-
-    private class InnerDeviceListener implements DeviceListener {
-
-        @Override
-        public void event(DeviceEvent event) {
-            Device device = event.subject();
-            if (Device.Type.CONTROLLER == device.type()
-                    && DeviceEvent.Type.DEVICE_ADDED == event.type()) {
-                backgroundService.execute(() -> {
-                    onServerDetected(device);
-                });
-            } else if (Device.Type.CONTROLLER == device.type()
-                    && DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event
-                            .type()) {
-                backgroundService.execute(() -> {
-                    onServerVanished(device);
-                });
-            } else if (Device.Type.SWITCH == device.type()
-                    && DeviceEvent.Type.DEVICE_ADDED == event.type()) {
-                backgroundService.execute(() -> {
-                    onOvsDetected(device);
-                });
-            } else if (Device.Type.SWITCH == device.type()
-                    && DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event
-                            .type()) {
-                backgroundService.execute(() -> {
-                    onOvsVanished(device);
-                });
-            } else {
-                log.info("do nothing for this device type");
-            }
-        }
-
-    }
-
-    private class InnerHostListener implements HostListener {
-
-        @Override
-        public void event(HostEvent event) {
-            Host host = event.subject();
-            if (HostEvent.Type.HOST_ADDED == event.type()) {
-                backgroundService.execute(() -> {
-                    onHostDetected(host);
-                });
-            } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
-                backgroundService.execute(() -> {
-                    onHostVanished(host);
-                });
-            } else {
-                log.info("unknow host");
-            }
-        }
-
-    }
-
-    // Used to forward the flows to the local VM.
-    private void programLocalOut(DeviceId dpid, SegmentationId segmentationId,
-                                 PortNumber outPort, MacAddress sourceMac,
-                                 ApplicationId appid, Objective.Operation type) {
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthDst(sourceMac).build();
-        TrafficTreatment treatment = DefaultTrafficTreatment
-                .builder()
-                .add(Instructions.modTunnelId(Long.parseLong(segmentationId
-                             .toString()))).setOutput(outPort).build();
-        ForwardingObjective.Builder objective = DefaultForwardingObjective
-                .builder().withTreatment(treatment).withSelector(selector)
-                .fromApp(appId).withFlag(Flag.SPECIFIC);
-        if (type.equals(Objective.Operation.ADD)) {
-            flowObjectiveService.forward(dpid, objective.add());
-        } else {
-            flowObjectiveService.forward(dpid, objective.remove());
-        }
-
-    }
-
-    // Used to forward the flows to the remote VM via VXLAN tunnel.
-    private void programTunnelOut(DeviceId dpid, SegmentationId segmentationId,
-                                  PortNumber outPort, MacAddress sourceMac,
-                                  ApplicationId appid, Objective.Operation type) {
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchEthDst(sourceMac).build();
-        TrafficTreatment treatment = DefaultTrafficTreatment
-                .builder()
-                .add(Instructions.modTunnelId(Long.parseLong(segmentationId
-                             .toString()))).setOutput(outPort).build();
-        ForwardingObjective.Builder objective = DefaultForwardingObjective
-                .builder().withTreatment(treatment).withSelector(selector)
-                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
-        if (type.equals(Objective.Operation.ADD)) {
-            flowObjectiveService.forward(dpid, objective.add());
-        } else {
-            flowObjectiveService.forward(dpid, objective.remove());
-        }
-    }
-
-    // Used to forward multicast flows to remote VMs of the same tenant via
-    // VXLAN tunnel.
-    private void programTunnelFloodOut(DeviceId dpid,
-                                       SegmentationId segmentationId,
-                                       PortNumber ofPortOut,
-                                       Iterable<Port> localports,
-                                       ApplicationId appid,
-                                       Objective.Operation type) {
-        TrafficSelector selector = DefaultTrafficSelector
-                .builder()
-                .matchInPort(ofPortOut)
-
-                .add(Criteria.matchTunnelId(Long.parseLong(segmentationId
-                             .toString()))).matchEthDst(MacAddress.BROADCAST)
-                .build();
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-        for (Port outport : localports) {
-            treatment.setOutput(outport.number());
-        }
-
-        ForwardingObjective.Builder objective = DefaultForwardingObjective
-                .builder().withTreatment(treatment.build())
-                .withSelector(selector).fromApp(appId).makePermanent()
-                .withFlag(Flag.SPECIFIC);
-        if (type.equals(Objective.Operation.ADD)) {
-            flowObjectiveService.forward(dpid, objective.add());
-        } else {
-            flowObjectiveService.forward(dpid, objective.remove());
-        }
-    }
-
-    // Applies default flows to mac table.
-    private void programMacDefaultRules(DeviceId dpid, ApplicationId appid,
-                                        Objective.Operation type) {
-        TrafficSelector selector = DefaultTrafficSelector.builder().build();
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder().drop()
-                .build();
-        ForwardingObjective.Builder objective = DefaultForwardingObjective
-                .builder().withTreatment(treatment).withSelector(selector)
-                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
-        if (type.equals(Objective.Operation.ADD)) {
-            flowObjectiveService.forward(dpid, objective.add());
-        } else {
-            flowObjectiveService.forward(dpid, objective.remove());
-        }
-    }
-
-    // Used to forward the flows to the local VMs with the same tenant.
-    private void programLocalBcastRules(DeviceId dpid,
-                                        SegmentationId segmentationId,
-                                        PortNumber inPort, List<Port> allports,
-                                        ApplicationId appid,
-                                        Objective.Operation type) {
-        TrafficSelector selector = DefaultTrafficSelector
-                .builder()
-                .matchInPort(inPort)
-                .matchEthDst(MacAddress.BROADCAST)
-                .add(Criteria.matchTunnelId(Long.parseLong(segmentationId
-                             .toString()))).build();
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-
-        for (Port outport : allports) {
-            if (inPort != outport.number()) {
-                treatment.setOutput(outport.number());
-            }
-        }
-        ForwardingObjective.Builder objective = DefaultForwardingObjective
-                .builder().withTreatment(treatment.build())
-                .withSelector(selector).fromApp(appId).makePermanent()
-                .withFlag(Flag.SPECIFIC);
-        if (type.equals(Objective.Operation.ADD)) {
-            flowObjectiveService.forward(dpid, objective.add());
-        } else {
-            flowObjectiveService.forward(dpid, objective.remove());
-        }
-    }
-
-    // Used to apply local entry flow.
-    private void programLocalIn(DeviceId dpid, SegmentationId segmentationId,
-                                PortNumber inPort, MacAddress srcMac,
-                                ApplicationId appid, Objective.Operation type) {
-        TrafficSelector selector = DefaultTrafficSelector.builder()
-                .matchInPort(inPort).matchEthSrc(srcMac).build();
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-        treatment.add(Instructions.modTunnelId(Long.parseLong(segmentationId
-                .toString())));
-        ForwardingObjective.Builder objective = DefaultForwardingObjective
-                .builder().withTreatment(treatment.build())
-                .withSelector(selector).fromApp(appId).makePermanent()
-                .withFlag(Flag.SPECIFIC);
-        if (type.equals(Objective.Operation.ADD)) {
-            flowObjectiveService.forward(dpid, objective.add());
-        } else {
-            flowObjectiveService.forward(dpid, objective.remove());
-        }
-    }
-
-    // Used to forward the flows from the egress tunnel to the VM.
-    private void programTunnelIn(DeviceId dpid, SegmentationId segmentationId,
-                                 PortNumber inPort, MacAddress sourceMac,
-                                 ApplicationId appid, Objective.Operation type) {
-        TrafficSelector selector = DefaultTrafficSelector
-                .builder()
-                .matchInPort(inPort)
-                .add(Criteria.matchTunnelId(Long.parseLong(segmentationId
-                             .toString()))).build();
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
-
-        ForwardingObjective.Builder objective = DefaultForwardingObjective
-                .builder().withTreatment(treatment).withSelector(selector)
-                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
-        if (type.equals(Objective.Operation.ADD)) {
-            flowObjectiveService.forward(dpid, objective.add());
-        } else {
-            flowObjectiveService.forward(dpid, objective.remove());
-        }
-    }
-
-    // Applies the default flows to port table.
-    private void programPortDefaultRules(DeviceId dpid, ApplicationId appid,
-                                         Objective.Operation type) {
-        TrafficSelector selector = DefaultTrafficSelector.builder().build();
-        TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
-        ForwardingObjective.Builder objective = DefaultForwardingObjective
-                .builder().withTreatment(treatment).withSelector(selector)
-                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
-        if (type.equals(Objective.Operation.ADD)) {
-            flowObjectiveService.forward(dpid, objective.add());
-        } else {
-            flowObjectiveService.forward(dpid, objective.remove());
-        }
-    }
-}
+/*
+ * 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.vtn.impl;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+
+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.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.BridgeConfig;
+import org.onosproject.net.behaviour.BridgeName;
+import org.onosproject.net.behaviour.DefaultTunnelDescription;
+import org.onosproject.net.behaviour.IpTunnelEndPoint;
+import org.onosproject.net.behaviour.TunnelConfig;
+import org.onosproject.net.behaviour.TunnelDescription;
+import org.onosproject.net.behaviour.TunnelEndPoint;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.EventuallyConsistentMap;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.store.service.WallClockTimestamp;
+import org.onosproject.vtn.VTNService;
+import org.onosproject.vtnrsc.SegmentationId;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.slf4j.Logger;
+
+import com.google.common.collect.Sets;
+
+/**
+ * Provides implementation of VTNService.
+ */
+@Component(immediate = true)
+@Service
+public class VTNManager implements VTNService {
+    private final Logger log = getLogger(getClass());
+
+    private static final String APP_ID = "org.onosproject.app.vtn";
+    private ScheduledExecutorService backgroundService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TenantNetworkService tenantNetworkService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VirtualPortService virtualPortService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+    private EventuallyConsistentMap<HostId, SegmentationId> binding;
+    private ApplicationId appId;
+    private HostListener hostListener = new InnerHostListener();
+    private DeviceListener deviceListener = new InnerDeviceListener();
+    private static final String IFACEID = "ifaceid";
+    private static final String PORT_HEAD = "vxlan";
+    private static final String DEFAULT_BRIDGE_NAME = "br-int";
+    private static final String CONTROLLER_IP_KEY = "ipaddress";
+
+    @Activate
+    public void activate() {
+        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API);
+        appId = coreService.registerApplication(APP_ID);
+        deviceService.addListener(deviceListener);
+        hostService.addListener(hostListener);
+        backgroundService = newSingleThreadScheduledExecutor(groupedThreads("onos-apps/vtn",
+                                                                            "manager-background"));
+        binding = storageService
+                .<HostId, SegmentationId>eventuallyConsistentMapBuilder()
+                .withName("all_tunnel").withSerializer(serializer)
+                .withTimestampProvider((k, v) -> new WallClockTimestamp())
+                .build();
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        backgroundService.shutdown();
+        binding.destroy();
+        log.info("Stopped");
+    }
+
+    @Override
+    public void onServerDetected(Device device) {
+        Iterable<Device> devices = deviceService.getAvailableDevices();
+        DriverHandler handler = driverService.createHandler(device.id());
+        BridgeConfig bridgeConfig = handler.behaviour(BridgeConfig.class);
+        bridgeConfig.addBridge(BridgeName.bridgeName(DEFAULT_BRIDGE_NAME));
+        String ipAddress = device.annotations().value(CONTROLLER_IP_KEY);
+        IpAddress ip = IpAddress.valueOf(ipAddress);
+        Sets.newHashSet(devices)
+                .stream()
+                .filter(d -> d.type() == Device.Type.CONTROLLER)
+                .filter(d -> !device.id().equals(d.id()))
+                .forEach(d -> {
+                             String ipAddress1 = d.annotations()
+                                     .value(CONTROLLER_IP_KEY);
+                             IpAddress ip1 = IpAddress.valueOf(ipAddress1);
+                             applyTunnelConfig(ip, ip1, handler);
+                             DriverHandler handler1 = driverService
+                                     .createHandler(d.id());
+                             applyTunnelConfig(ip1, ip, handler1);
+                         });
+    }
+
+    @Override
+    public void onServerVanished(Device device) {
+        Iterable<Device> devices = deviceService.getAvailableDevices();
+        String ipAddress = device.annotations().value(CONTROLLER_IP_KEY);
+        IpAddress dst = IpAddress.valueOf(ipAddress);
+        Sets.newHashSet(devices)
+                .stream()
+                .filter(d -> d.type() == Device.Type.CONTROLLER)
+                .filter(d -> !device.id().equals(d.id()))
+                .forEach(d -> {
+                             String ipAddress1 = d.annotations()
+                                     .value(CONTROLLER_IP_KEY);
+                             DriverHandler handler = driverService
+                                     .createHandler(d.id());
+                             IpAddress src = IpAddress.valueOf(ipAddress1);
+                             removeTunnelConfig(src, dst, handler);
+                         });
+    }
+
+    private void applyTunnelConfig(IpAddress src, IpAddress dst,
+                                   DriverHandler handler) {
+        TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(src);
+        TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dst);
+        TunnelDescription tunnel = new DefaultTunnelDescription(
+                                                                tunnelAsSrc,
+                                                                tunnelAsDst,
+                                                                TunnelDescription.Type.VXLAN,
+                                                                null);
+        TunnelConfig config = handler.behaviour(TunnelConfig.class);
+        config.createTunnel(tunnel);
+    }
+
+    private void removeTunnelConfig(IpAddress src, IpAddress dst,
+                                    DriverHandler handler) {
+        TunnelEndPoint tunnelAsSrc = IpTunnelEndPoint.ipTunnelPoint(src);
+        TunnelEndPoint tunnelAsDst = IpTunnelEndPoint.ipTunnelPoint(dst);
+        TunnelDescription tunnel = new DefaultTunnelDescription(
+                                                                tunnelAsSrc,
+                                                                tunnelAsDst,
+                                                                TunnelDescription.Type.VXLAN,
+                                                                null);
+        TunnelConfig config = handler.behaviour(TunnelConfig.class);
+        config.removeTunnel(tunnel);
+    }
+
+    @Override
+    public void onOvsDetected(Device device) {
+        programMacDefaultRules(device.id(), appId, Objective.Operation.ADD);
+        programPortDefaultRules(device.id(), appId, Objective.Operation.ADD);
+    }
+
+    @Override
+    public void onOvsVanished(Device device) {
+        programMacDefaultRules(device.id(), appId, Objective.Operation.REMOVE);
+        programPortDefaultRules(device.id(), appId, Objective.Operation.REMOVE);
+    }
+
+    @Override
+    public void onHostDetected(Host host) {
+        String ifaceId = host.annotations().value(IFACEID);
+        VirtualPortId portId = VirtualPortId.portId(ifaceId);
+        VirtualPort port = virtualPortService.getPort(portId);
+        TenantNetwork network = tenantNetworkService.getNetwork(port
+                .networkId());
+        binding.put(host.id(), network.segmentationId());
+        DeviceId deviceId = host.location().deviceId();
+        List<Port> allPorts = deviceService.getPorts(deviceId);
+        PortNumber inPort = host.location().port();
+        Set<Port> localPorts = new HashSet<>();
+        allPorts.forEach(p -> {
+            if (!p.number().name().startsWith(PORT_HEAD)) {
+                localPorts.add(p);
+            }
+        });
+        programLocalBcastRules(deviceId, network.segmentationId(), inPort,
+                               allPorts, appId, Objective.Operation.ADD);
+        programLocalOut(deviceId, network.segmentationId(), inPort, host.mac(),
+                        appId, Objective.Operation.ADD);
+        programTunnelFloodOut(deviceId, network.segmentationId(), inPort,
+                              localPorts, appId, Objective.Operation.ADD);
+        programTunnelOut(deviceId, network.segmentationId(), inPort,
+                         host.mac(), appId, Objective.Operation.ADD);
+        programLocalIn(deviceId, network.segmentationId(), inPort, host.mac(),
+                       appId, Objective.Operation.ADD);
+        programTunnelIn(deviceId, network.segmentationId(), inPort, host.mac(),
+                        appId, Objective.Operation.ADD);
+    }
+
+    @Override
+    public void onHostVanished(Host host) {
+        SegmentationId segId = binding.remove(host.id());
+        DeviceId deviceId = host.location().deviceId();
+        List<Port> allPorts = deviceService.getPorts(deviceId);
+        PortNumber inPort = host.location().port();
+        Set<Port> localPorts = new HashSet<>();
+        allPorts.forEach(p -> {
+            if (!p.number().name().startsWith(PORT_HEAD)) {
+                localPorts.add(p);
+            }
+        });
+        programLocalBcastRules(deviceId, segId, inPort, allPorts, appId,
+                               Objective.Operation.REMOVE);
+        programLocalOut(deviceId, segId, inPort, host.mac(), appId,
+                        Objective.Operation.REMOVE);
+        programTunnelFloodOut(deviceId, segId, inPort, localPorts, appId,
+                              Objective.Operation.REMOVE);
+        programTunnelOut(deviceId, segId, inPort, host.mac(), appId,
+                         Objective.Operation.REMOVE);
+        programLocalIn(deviceId, segId, inPort, host.mac(), appId,
+                       Objective.Operation.REMOVE);
+        programTunnelIn(deviceId, segId, inPort, host.mac(), appId,
+                        Objective.Operation.REMOVE);
+    }
+
+    private class InnerDeviceListener implements DeviceListener {
+
+        @Override
+        public void event(DeviceEvent event) {
+            Device device = event.subject();
+            if (Device.Type.CONTROLLER == device.type()
+                    && DeviceEvent.Type.DEVICE_ADDED == event.type()) {
+                backgroundService.execute(() -> {
+                    onServerDetected(device);
+                });
+            } else if (Device.Type.CONTROLLER == device.type()
+                    && DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event
+                            .type()) {
+                backgroundService.execute(() -> {
+                    onServerVanished(device);
+                });
+            } else if (Device.Type.SWITCH == device.type()
+                    && DeviceEvent.Type.DEVICE_ADDED == event.type()) {
+                backgroundService.execute(() -> {
+                    onOvsDetected(device);
+                });
+            } else if (Device.Type.SWITCH == device.type()
+                    && DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED == event
+                            .type()) {
+                backgroundService.execute(() -> {
+                    onOvsVanished(device);
+                });
+            } else {
+                log.info("do nothing for this device type");
+            }
+        }
+
+    }
+
+    private class InnerHostListener implements HostListener {
+
+        @Override
+        public void event(HostEvent event) {
+            Host host = event.subject();
+            if (HostEvent.Type.HOST_ADDED == event.type()) {
+                backgroundService.execute(() -> {
+                    onHostDetected(host);
+                });
+            } else if (HostEvent.Type.HOST_REMOVED == event.type()) {
+                backgroundService.execute(() -> {
+                    onHostVanished(host);
+                });
+            } else {
+                log.info("unknow host");
+            }
+        }
+
+    }
+
+    // Used to forward the flows to the local VM.
+    private void programLocalOut(DeviceId dpid, SegmentationId segmentationId,
+                                 PortNumber outPort, MacAddress sourceMac,
+                                 ApplicationId appid, Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(sourceMac).build();
+        TrafficTreatment treatment = DefaultTrafficTreatment
+                .builder()
+                .add(Instructions.modTunnelId(Long.parseLong(segmentationId
+                             .toString()))).setOutput(outPort).build();
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).withFlag(Flag.SPECIFIC);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(dpid, objective.add());
+        } else {
+            flowObjectiveService.forward(dpid, objective.remove());
+        }
+
+    }
+
+    // Used to forward the flows to the remote VM via VXLAN tunnel.
+    private void programTunnelOut(DeviceId dpid, SegmentationId segmentationId,
+                                  PortNumber outPort, MacAddress sourceMac,
+                                  ApplicationId appid, Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchEthDst(sourceMac).build();
+        TrafficTreatment treatment = DefaultTrafficTreatment
+                .builder()
+                .add(Instructions.modTunnelId(Long.parseLong(segmentationId
+                             .toString()))).setOutput(outPort).build();
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(dpid, objective.add());
+        } else {
+            flowObjectiveService.forward(dpid, objective.remove());
+        }
+    }
+
+    // Used to forward multicast flows to remote VMs of the same tenant via
+    // VXLAN tunnel.
+    private void programTunnelFloodOut(DeviceId dpid,
+                                       SegmentationId segmentationId,
+                                       PortNumber ofPortOut,
+                                       Iterable<Port> localports,
+                                       ApplicationId appid,
+                                       Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector
+                .builder()
+                .matchInPort(ofPortOut)
+
+                .add(Criteria.matchTunnelId(Long.parseLong(segmentationId
+                             .toString()))).matchEthDst(MacAddress.BROADCAST)
+                .build();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        for (Port outport : localports) {
+            treatment.setOutput(outport.number());
+        }
+
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment.build())
+                .withSelector(selector).fromApp(appId).makePermanent()
+                .withFlag(Flag.SPECIFIC);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(dpid, objective.add());
+        } else {
+            flowObjectiveService.forward(dpid, objective.remove());
+        }
+    }
+
+    // Applies default flows to mac table.
+    private void programMacDefaultRules(DeviceId dpid, ApplicationId appid,
+                                        Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector.builder().build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().drop()
+                .build();
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(dpid, objective.add());
+        } else {
+            flowObjectiveService.forward(dpid, objective.remove());
+        }
+    }
+
+    // Used to forward the flows to the local VMs with the same tenant.
+    private void programLocalBcastRules(DeviceId dpid,
+                                        SegmentationId segmentationId,
+                                        PortNumber inPort, List<Port> allports,
+                                        ApplicationId appid,
+                                        Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector
+                .builder()
+                .matchInPort(inPort)
+                .matchEthDst(MacAddress.BROADCAST)
+                .add(Criteria.matchTunnelId(Long.parseLong(segmentationId
+                             .toString()))).build();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+
+        for (Port outport : allports) {
+            if (inPort != outport.number()) {
+                treatment.setOutput(outport.number());
+            }
+        }
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment.build())
+                .withSelector(selector).fromApp(appId).makePermanent()
+                .withFlag(Flag.SPECIFIC);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(dpid, objective.add());
+        } else {
+            flowObjectiveService.forward(dpid, objective.remove());
+        }
+    }
+
+    // Used to apply local entry flow.
+    private void programLocalIn(DeviceId dpid, SegmentationId segmentationId,
+                                PortNumber inPort, MacAddress srcMac,
+                                ApplicationId appid, Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(inPort).matchEthSrc(srcMac).build();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        treatment.add(Instructions.modTunnelId(Long.parseLong(segmentationId
+                .toString())));
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment.build())
+                .withSelector(selector).fromApp(appId).makePermanent()
+                .withFlag(Flag.SPECIFIC);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(dpid, objective.add());
+        } else {
+            flowObjectiveService.forward(dpid, objective.remove());
+        }
+    }
+
+    // Used to forward the flows from the egress tunnel to the VM.
+    private void programTunnelIn(DeviceId dpid, SegmentationId segmentationId,
+                                 PortNumber inPort, MacAddress sourceMac,
+                                 ApplicationId appid, Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector
+                .builder()
+                .matchInPort(inPort)
+                .add(Criteria.matchTunnelId(Long.parseLong(segmentationId
+                             .toString()))).build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(dpid, objective.add());
+        } else {
+            flowObjectiveService.forward(dpid, objective.remove());
+        }
+    }
+
+    // Applies the default flows to port table.
+    private void programPortDefaultRules(DeviceId dpid, ApplicationId appid,
+                                         Objective.Operation type) {
+        TrafficSelector selector = DefaultTrafficSelector.builder().build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+        ForwardingObjective.Builder objective = DefaultForwardingObjective
+                .builder().withTreatment(treatment).withSelector(selector)
+                .fromApp(appId).makePermanent().withFlag(Flag.SPECIFIC);
+        if (type.equals(Objective.Operation.ADD)) {
+            flowObjectiveService.forward(dpid, objective.add());
+        } else {
+            flowObjectiveService.forward(dpid, objective.remove());
+        }
+    }
+}
diff --git a/apps/vtnrsc/features.xml b/apps/vtnrsc/features.xml
deleted file mode 100644
index 40be95b..0000000
--- a/apps/vtnrsc/features.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!--
-  ~ 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.
-  -->
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
-    <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository>
-    <feature name="onos-app-vtnrsc" version="@FEATURE-VERSION"
-		description="ONOS app vtnrsc components">
-		<feature>onos-api</feature>
-		<bundle>mvn:org.onosproject/onos-app-vtnrsc/@ONOS-VERSION
-		</bundle>
-	</feature>
-</features>
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/AllocationPool.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/AllocationPool.java
similarity index 96%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/AllocationPool.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/AllocationPool.java
index feab8e3..85d1fa9 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/AllocationPool.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/AllocationPool.java
@@ -1,38 +1,38 @@
-/*
- * 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.app.vtnrsc;
-
-import org.onlab.packet.IpAddress;
-
-/**
- * The continuous IP address range between the start address and the end address for the allocation pools.
- */
-public interface AllocationPool {
-
-    /**
-     * The start address for the allocation pool.
-     *
-     * @return startIp
-     */
-    IpAddress startIp();
-
-    /**
-     * The end address for the allocation pool.
-     *
-     * @return endIp
-     */
-    IpAddress endIp();
-}
+/*
+ * 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.vtnrsc;
+
+import org.onlab.packet.IpAddress;
+
+/**
+ * The continuous IP address range between the start address and the end address for the allocation pools.
+ */
+public interface AllocationPool {
+
+    /**
+     * The start address for the allocation pool.
+     *
+     * @return startIp
+     */
+    IpAddress startIp();
+
+    /**
+     * The end address for the allocation pool.
+     *
+     * @return endIp
+     */
+    IpAddress endIp();
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/AllowedAddressPair.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/AllowedAddressPair.java
similarity index 98%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/AllowedAddressPair.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/AllowedAddressPair.java
index 313a507..b60cb67 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/AllowedAddressPair.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/AllowedAddressPair.java
@@ -1,94 +1,94 @@
-/*
- * 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.app.vtnrsc;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-
-/**
- * Immutable representation of a allowed address pair.
- */
-public final class AllowedAddressPair {
-    private final IpAddress ip;
-    private final MacAddress mac;
-    // Public construction is prohibited
-    private AllowedAddressPair(IpAddress ip, MacAddress mac) {
-        checkNotNull(ip, "IpAddress cannot be null");
-        checkNotNull(mac, "MacAddress cannot be null");
-        this.ip = ip;
-        this.mac = mac;
-    }
-    /**
-     * Returns the AllowedAddressPair ip address.
-     *
-     * @return ip address
-     */
-    public IpAddress ip() {
-        return ip;
-    }
-
-    /**
-     * Returns the AllowedAddressPair MAC address.
-     *
-     * @return MAC address
-     */
-    public MacAddress mac() {
-        return mac;
-    }
-
-
-    /**
-     * Creates a allowedAddressPair using the supplied ipAddress &amp;
-     * macAddress.
-     *
-     * @param ip IP address
-     * @param mac MAC address
-     * @return AllowedAddressPair
-     */
-    public static AllowedAddressPair allowedAddressPair(IpAddress ip,
-                                                        MacAddress mac) {
-        return new AllowedAddressPair(ip, mac);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(ip, mac);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof AllowedAddressPair) {
-            final AllowedAddressPair that = (AllowedAddressPair) obj;
-            return Objects.equals(this.ip, that.ip)
-                    && Objects.equals(this.mac, that.mac);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("ip", ip).add("mac", mac).toString();
-    }
-
-}
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+
+/**
+ * Immutable representation of a allowed address pair.
+ */
+public final class AllowedAddressPair {
+    private final IpAddress ip;
+    private final MacAddress mac;
+    // Public construction is prohibited
+    private AllowedAddressPair(IpAddress ip, MacAddress mac) {
+        checkNotNull(ip, "IpAddress cannot be null");
+        checkNotNull(mac, "MacAddress cannot be null");
+        this.ip = ip;
+        this.mac = mac;
+    }
+    /**
+     * Returns the AllowedAddressPair ip address.
+     *
+     * @return ip address
+     */
+    public IpAddress ip() {
+        return ip;
+    }
+
+    /**
+     * Returns the AllowedAddressPair MAC address.
+     *
+     * @return MAC address
+     */
+    public MacAddress mac() {
+        return mac;
+    }
+
+
+    /**
+     * Creates a allowedAddressPair using the supplied ipAddress &amp;
+     * macAddress.
+     *
+     * @param ip IP address
+     * @param mac MAC address
+     * @return AllowedAddressPair
+     */
+    public static AllowedAddressPair allowedAddressPair(IpAddress ip,
+                                                        MacAddress mac) {
+        return new AllowedAddressPair(ip, mac);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(ip, mac);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof AllowedAddressPair) {
+            final AllowedAddressPair that = (AllowedAddressPair) obj;
+            return Objects.equals(this.ip, that.ip)
+                    && Objects.equals(this.mac, that.mac);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("ip", ip).add("mac", mac).toString();
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/BindingHostId.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/BindingHostId.java
new file mode 100644
index 0000000..da40387
--- /dev/null
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/BindingHostId.java
@@ -0,0 +1,57 @@
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+public final class BindingHostId {
+    private final String bindingHostId;
+
+    // Public construction is prohibited
+    private BindingHostId(String bindingHostId) {
+        checkNotNull(bindingHostId, "BindingHosttId cannot be null");
+        this.bindingHostId = bindingHostId;
+    }
+
+    /**
+     * Creates a BindingHostId identifier.
+     *
+     * @param bindingHostId the bindingHostId identifier
+     * @return the bindingHostId identifier
+     */
+    public static BindingHostId bindingHostId(String bindingHostId) {
+        return new BindingHostId(bindingHostId);
+    }
+
+    /**
+     * Returns the bindingHostId identifier.
+     *
+     * @return the bindingHostId identifier
+     */
+    public String bindingHostId() {
+        return bindingHostId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(bindingHostId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof BindingHostId) {
+            final BindingHostId that = (BindingHostId) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.bindingHostId, that.bindingHostId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return bindingHostId;
+    }
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultAllocationPool.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultAllocationPool.java
similarity index 98%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultAllocationPool.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultAllocationPool.java
index 2844de5..6a6a475 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultAllocationPool.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultAllocationPool.java
@@ -1,81 +1,81 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.Objects;
-
-import org.onlab.packet.IpAddress;
-
-/**
- * The continuous IP address range between the start address and the end address
- * for the allocation pools.
- */
-public final class DefaultAllocationPool implements AllocationPool {
-
-    private final IpAddress startIp;
-    private final IpAddress endIp;
-
-    /**
-     * Creates an AllocationPool by using the start IP address and the end IP
-     * address.
-     *
-     * @param startIp the start IP address of the allocation pool
-     * @param endIp the end IP address of the allocation pool
-     */
-    public DefaultAllocationPool(IpAddress startIp, IpAddress endIp) {
-        checkNotNull(startIp, "StartIp cannot be null");
-        checkNotNull(endIp, "EndIp cannot be null");
-        this.startIp = startIp;
-        this.endIp = endIp;
-    }
-
-    @Override
-    public IpAddress startIp() {
-        return startIp;
-    }
-
-    @Override
-    public IpAddress endIp() {
-        return endIp;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(startIp, endIp);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof DefaultAllocationPool) {
-            final DefaultAllocationPool other = (DefaultAllocationPool) obj;
-            return Objects.equals(this.startIp, other.startIp)
-                    && Objects.equals(this.endIp, other.endIp);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("startIp", startIp).add("endIp", endIp)
-                .toString();
-    }
-}
-
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+
+/**
+ * The continuous IP address range between the start address and the end address
+ * for the allocation pools.
+ */
+public final class DefaultAllocationPool implements AllocationPool {
+
+    private final IpAddress startIp;
+    private final IpAddress endIp;
+
+    /**
+     * Creates an AllocationPool by using the start IP address and the end IP
+     * address.
+     *
+     * @param startIp the start IP address of the allocation pool
+     * @param endIp the end IP address of the allocation pool
+     */
+    public DefaultAllocationPool(IpAddress startIp, IpAddress endIp) {
+        checkNotNull(startIp, "StartIp cannot be null");
+        checkNotNull(endIp, "EndIp cannot be null");
+        this.startIp = startIp;
+        this.endIp = endIp;
+    }
+
+    @Override
+    public IpAddress startIp() {
+        return startIp;
+    }
+
+    @Override
+    public IpAddress endIp() {
+        return endIp;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(startIp, endIp);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultAllocationPool) {
+            final DefaultAllocationPool other = (DefaultAllocationPool) obj;
+            return Objects.equals(this.startIp, other.startIp)
+                    && Objects.equals(this.endIp, other.endIp);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("startIp", startIp).add("endIp", endIp)
+                .toString();
+    }
+}
+
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultHostRoute.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultHostRoute.java
similarity index 98%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultHostRoute.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultHostRoute.java
index 2270a4b..c84ae18 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultHostRoute.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultHostRoute.java
@@ -1,79 +1,79 @@
-/*
- * 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.app.vtnrsc;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-import java.util.Objects;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-
-/**
- * Host route dictionaries for the subnet.
- */
-public final class DefaultHostRoute implements HostRoute {
-
-    private final IpAddress nexthop;
-    private final IpPrefix destination;
-
-    /**
-     *
-     * Creates a DefaultHostRoute by using the next hop and the destination.
-     *
-     * @param nexthop of the DefaultHostRoute
-     * @param destination of the DefaultHostRoute
-     */
-    public DefaultHostRoute(IpAddress nexthop, IpPrefix destination) {
-        this.nexthop = nexthop;
-        this.destination = destination;
-    }
-
-    @Override
-    public IpAddress nexthop() {
-        return nexthop;
-    }
-
-    @Override
-    public IpPrefix destination() {
-        return destination;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("nexthop", nexthop)
-                .add("destination", destination).toString();
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(nexthop, destination);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof DefaultHostRoute) {
-            final DefaultHostRoute other = (DefaultHostRoute) obj;
-            return Objects.equals(this.nexthop, other.nexthop)
-                    && Objects.equals(this.destination, other.destination);
-        }
-        return false;
-    }
-
-}
+/*
+ * 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.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+/**
+ * Host route dictionaries for the subnet.
+ */
+public final class DefaultHostRoute implements HostRoute {
+
+    private final IpAddress nexthop;
+    private final IpPrefix destination;
+
+    /**
+     *
+     * Creates a DefaultHostRoute by using the next hop and the destination.
+     *
+     * @param nexthop of the DefaultHostRoute
+     * @param destination of the DefaultHostRoute
+     */
+    public DefaultHostRoute(IpAddress nexthop, IpPrefix destination) {
+        this.nexthop = nexthop;
+        this.destination = destination;
+    }
+
+    @Override
+    public IpAddress nexthop() {
+        return nexthop;
+    }
+
+    @Override
+    public IpPrefix destination() {
+        return destination;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("nexthop", nexthop)
+                .add("destination", destination).toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(nexthop, destination);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultHostRoute) {
+            final DefaultHostRoute other = (DefaultHostRoute) obj;
+            return Objects.equals(this.nexthop, other.nexthop)
+                    && Objects.equals(this.destination, other.destination);
+        }
+        return false;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultSubnet.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultSubnet.java
similarity index 98%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultSubnet.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultSubnet.java
index c7c6e6f..6311a80 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultSubnet.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultSubnet.java
@@ -1,181 +1,182 @@
-/*
- * 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.app.vtnrsc;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-import java.util.Objects;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpAddress.Version;
-import org.onlab.packet.IpPrefix;
-
-/**
- * Default implementation of Subnet interface .
- */
-public final class DefaultSubnet implements Subnet {
-    private final SubnetId id;
-    private final String subnetName;
-    private final TenantNetworkId networkId;
-    private final TenantId tenantId;
-    private final Version ipVersion;
-    private final IpPrefix cidr;
-    private final IpAddress gatewayIp;
-    private final boolean dhcpEnabled;
-    private final boolean shared;
-    private final Mode ipV6AddressMode;
-    private final Mode ipV6RaMode;
-    private final Iterable<HostRoute> hostRoutes;
-    private final Iterable<AllocationPool> allocationPools;
-
-    /**
-     * Creates a subnet object.
-     *
-     * @param id subnet identifier
-     * @param subnetName the name of subnet
-     * @param networkId network identifier
-     * @param tenantId tenant identifier
-     * @param cidr the cidr
-     * @param gatewayIp gateway ip
-     * @param dhcpEnabled dhcp enabled or not
-     * @param shared indicates whether this network is shared across all
-     *            tenants, By default, only administrative user can change this
-     *            value
-     * @param hostRoutes a collection of host routes
-     * @param ipV6AddressMode ipV6AddressMode
-     * @param ipV6RaMode ipV6RaMode
-     * @param allocationPoolsIt a collection of allocationPools
-     */
-    public DefaultSubnet(SubnetId id, String subnetName,
-                         TenantNetworkId networkId, TenantId tenantId,
-                         Version ipVersion, IpPrefix cidr, IpAddress gatewayIp,
-                         boolean dhcpEnabled, boolean shared,
-                         Iterable<HostRoute> hostRoutes, Mode ipV6AddressMode,
-                         Mode ipV6RaMode,
-                         Iterable<AllocationPool> allocationPoolsIt) {
-        this.id = id;
-        this.subnetName = subnetName;
-        this.networkId = networkId;
-        this.tenantId = tenantId;
-        this.ipVersion = ipVersion;
-        this.cidr = cidr;
-        this.gatewayIp = gatewayIp;
-        this.dhcpEnabled = dhcpEnabled;
-        this.shared = shared;
-        this.ipV6AddressMode = ipV6AddressMode;
-        this.ipV6RaMode = ipV6RaMode;
-        this.hostRoutes = hostRoutes;
-        this.allocationPools = allocationPoolsIt;
-    }
-
-    @Override
-    public SubnetId id() {
-        return id;
-    }
-
-    @Override
-    public String subnetName() {
-        return subnetName;
-    }
-
-    @Override
-    public TenantNetworkId networkId() {
-        return networkId;
-    }
-
-    @Override
-    public TenantId tenantId() {
-        return tenantId;
-    }
-
-    @Override
-    public Version ipVersion() {
-        return ipVersion;
-    }
-
-    @Override
-    public IpPrefix cidr() {
-        return cidr;
-    }
-
-    @Override
-    public IpAddress gatewayIp() {
-        return gatewayIp;
-    }
-
-    @Override
-    public boolean dhcpEnabled() {
-        return dhcpEnabled;
-    }
-
-    @Override
-    public boolean shared() {
-        return shared;
-    }
-
-    @Override
-    public Iterable<HostRoute> hostRoutes() {
-        return hostRoutes;
-    }
-
-    @Override
-    public Mode ipV6AddressMode() {
-        return ipV6AddressMode;
-    }
-
-    @Override
-    public Mode ipV6RaMode() {
-        return ipV6RaMode;
-    }
-
-    @Override
-    public Iterable<AllocationPool> allocationPools() {
-        return allocationPools;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id, subnetName, ipVersion, cidr, gatewayIp,
-                            dhcpEnabled, shared, tenantId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof DefaultSubnet) {
-            final DefaultSubnet that = (DefaultSubnet) obj;
-            return Objects.equals(this.id, that.id)
-                    && Objects.equals(this.subnetName, that.subnetName)
-                    && Objects.equals(this.ipVersion, that.ipVersion)
-                    && Objects.equals(this.cidr, that.cidr)
-                    && Objects.equals(this.shared, that.shared)
-                    && Objects.equals(this.gatewayIp, that.gatewayIp)
-                    && Objects.equals(this.dhcpEnabled, that.dhcpEnabled);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("id", id).add("subnetName", subnetName)
-                .add("ipVersion", ipVersion).add("cidr", cidr)
-                .add("shared", shared).add("gatewayIp", gatewayIp)
-                .add("dhcpEnabled", dhcpEnabled).toString();
-    }
-
-}
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpAddress.Version;
+import org.onlab.packet.IpPrefix;
+
+/**
+ * Default implementation of Subnet interface .
+ */
+public final class DefaultSubnet implements Subnet {
+    private final SubnetId id;
+    private final String subnetName;
+    private final TenantNetworkId networkId;
+    private final TenantId tenantId;
+    private final Version ipVersion;
+    private final IpPrefix cidr;
+    private final IpAddress gatewayIp;
+    private final boolean dhcpEnabled;
+    private final boolean shared;
+    private final Mode ipV6AddressMode;
+    private final Mode ipV6RaMode;
+    private final Iterable<HostRoute> hostRoutes;
+    private final Iterable<AllocationPool> allocationPools;
+
+    /**
+     * Creates a subnet object.
+     *
+     * @param id subnet identifier
+     * @param subnetName the name of subnet
+     * @param networkId network identifier
+     * @param tenantId tenant identifier
+     * @param ipVersion Version of ipv4 or ipv6
+     * @param cidr the cidr
+     * @param gatewayIp gateway ip
+     * @param dhcpEnabled dhcp enabled or not
+     * @param shared indicates whether this network is shared across all
+     *            tenants, By default, only administrative user can change this
+     *            value
+     * @param hostRoutes a collection of host routes
+     * @param ipV6AddressMode ipV6AddressMode
+     * @param ipV6RaMode ipV6RaMode
+     * @param allocationPoolsIt a collection of allocationPools
+     */
+    public DefaultSubnet(SubnetId id, String subnetName,
+                         TenantNetworkId networkId, TenantId tenantId,
+                         Version ipVersion, IpPrefix cidr, IpAddress gatewayIp,
+                         boolean dhcpEnabled, boolean shared,
+                         Iterable<HostRoute> hostRoutes, Mode ipV6AddressMode,
+                         Mode ipV6RaMode,
+                         Iterable<AllocationPool> allocationPoolsIt) {
+        this.id = id;
+        this.subnetName = subnetName;
+        this.networkId = networkId;
+        this.tenantId = tenantId;
+        this.ipVersion = ipVersion;
+        this.cidr = cidr;
+        this.gatewayIp = gatewayIp;
+        this.dhcpEnabled = dhcpEnabled;
+        this.shared = shared;
+        this.ipV6AddressMode = ipV6AddressMode;
+        this.ipV6RaMode = ipV6RaMode;
+        this.hostRoutes = hostRoutes;
+        this.allocationPools = allocationPoolsIt;
+    }
+
+    @Override
+    public SubnetId id() {
+        return id;
+    }
+
+    @Override
+    public String subnetName() {
+        return subnetName;
+    }
+
+    @Override
+    public TenantNetworkId networkId() {
+        return networkId;
+    }
+
+    @Override
+    public TenantId tenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public Version ipVersion() {
+        return ipVersion;
+    }
+
+    @Override
+    public IpPrefix cidr() {
+        return cidr;
+    }
+
+    @Override
+    public IpAddress gatewayIp() {
+        return gatewayIp;
+    }
+
+    @Override
+    public boolean dhcpEnabled() {
+        return dhcpEnabled;
+    }
+
+    @Override
+    public boolean shared() {
+        return shared;
+    }
+
+    @Override
+    public Iterable<HostRoute> hostRoutes() {
+        return hostRoutes;
+    }
+
+    @Override
+    public Mode ipV6AddressMode() {
+        return ipV6AddressMode;
+    }
+
+    @Override
+    public Mode ipV6RaMode() {
+        return ipV6RaMode;
+    }
+
+    @Override
+    public Iterable<AllocationPool> allocationPools() {
+        return allocationPools;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, subnetName, ipVersion, cidr, gatewayIp,
+                            dhcpEnabled, shared, tenantId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultSubnet) {
+            final DefaultSubnet that = (DefaultSubnet) obj;
+            return Objects.equals(this.id, that.id)
+                    && Objects.equals(this.subnetName, that.subnetName)
+                    && Objects.equals(this.ipVersion, that.ipVersion)
+                    && Objects.equals(this.cidr, that.cidr)
+                    && Objects.equals(this.shared, that.shared)
+                    && Objects.equals(this.gatewayIp, that.gatewayIp)
+                    && Objects.equals(this.dhcpEnabled, that.dhcpEnabled);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("id", id).add("subnetName", subnetName)
+                .add("ipVersion", ipVersion).add("cidr", cidr)
+                .add("shared", shared).add("gatewayIp", gatewayIp)
+                .add("dhcpEnabled", dhcpEnabled).toString();
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultTenantNetwork.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultTenantNetwork.java
similarity index 99%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultTenantNetwork.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultTenantNetwork.java
index f287def..2165078 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultTenantNetwork.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultTenantNetwork.java
@@ -1,160 +1,160 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-import java.util.Objects;
-
-/**
- * Default implementation of  TenantNetwork interface.
- */
-public final class DefaultTenantNetwork implements TenantNetwork {
-    private final TenantNetworkId id;
-    private final String name;
-    private final boolean adminStateUp;
-    private final State state;
-    private final boolean shared;
-    private final Type type;
-    private final TenantId tenantId;
-    private final boolean routerExternal;
-    private final PhysicalNetwork physicalNetwork;
-    private final SegmentationId segmentationId;
-
-    /**
-     * Creates a neutronNetwork element attributed to the specified provider.
-     *
-     * @param id  network identifier
-     * @param name the network name
-     * @param adminStateUp administrative state of the network
-     * @param state the network state
-     * @param shared indicates whether this network is shared across all
-     *            tenants, By default, only administrative user can change this
-     *            value
-     * @param tenantId tenant identifier
-     * @param routerExternal network routerExternal
-     * @param type the network type
-     * @param physicalNetwork physicalNetwork identifier
-     * @param segmentationId segmentation identifier
-     */
-    public DefaultTenantNetwork(TenantNetworkId id, String name,
-                                boolean adminStateUp, State state,
-                                boolean shared, TenantId tenantId,
-                                boolean routerExternal, Type type,
-                                PhysicalNetwork physicalNetwork,
-                                SegmentationId segmentationId) {
-        this.id = id;
-        this.name = name;
-        this.adminStateUp = adminStateUp;
-        this.state = state;
-        this.shared = shared;
-        this.type = type;
-        this.tenantId = tenantId;
-        this.routerExternal = routerExternal;
-        this.physicalNetwork = physicalNetwork;
-        this.segmentationId = segmentationId;
-    }
-
-    @Override
-    public TenantNetworkId id() {
-        return id;
-    }
-
-    @Override
-    public String name() {
-        return name;
-    }
-
-    @Override
-    public boolean adminStateUp() {
-        return adminStateUp;
-    }
-
-    @Override
-    public State state() {
-        return state;
-    }
-
-    @Override
-    public boolean shared() {
-        return shared;
-    }
-
-    @Override
-    public TenantId tenantId() {
-        return tenantId;
-    }
-
-    @Override
-    public boolean routerExternal() {
-        return routerExternal;
-    }
-
-    @Override
-    public Type type() {
-        return type;
-    }
-
-    @Override
-    public PhysicalNetwork physicalNetwork() {
-        return physicalNetwork;
-    }
-
-    @Override
-    public SegmentationId segmentationId() {
-        return segmentationId;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id, name, adminStateUp, state, shared, tenantId,
-                            routerExternal, type, physicalNetwork,
-                            segmentationId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof DefaultTenantNetwork) {
-            final DefaultTenantNetwork that = (DefaultTenantNetwork) obj;
-            return Objects.equals(this.id, that.id)
-                    && Objects.equals(this.name, that.name)
-                    && Objects.equals(this.adminStateUp, that.adminStateUp)
-                    && Objects.equals(this.state, that.state)
-                    && Objects.equals(this.shared, that.shared)
-                    && Objects.equals(this.tenantId, that.tenantId)
-                    && Objects.equals(this.routerExternal, that.routerExternal)
-                    && Objects.equals(this.type, that.type)
-                    && Objects.equals(this.physicalNetwork,
-                                      that.physicalNetwork)
-                    && Objects.equals(this.segmentationId, that.segmentationId);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("id", id).add("name", name)
-                .add("adminStateUp", adminStateUp).add("state", state)
-                .add("shared", shared).add("tenantId", tenantId)
-                .add("routeExternal", routerExternal).add("type", type)
-                .add("physicalNetwork", physicalNetwork)
-                .add("segmentationId", segmentationId).toString();
-    }
-
-}
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Objects;
+
+/**
+ * Default implementation of  TenantNetwork interface.
+ */
+public final class DefaultTenantNetwork implements TenantNetwork {
+    private final TenantNetworkId id;
+    private final String name;
+    private final boolean adminStateUp;
+    private final State state;
+    private final boolean shared;
+    private final Type type;
+    private final TenantId tenantId;
+    private final boolean routerExternal;
+    private final PhysicalNetwork physicalNetwork;
+    private final SegmentationId segmentationId;
+
+    /**
+     * Creates a neutronNetwork element attributed to the specified provider.
+     *
+     * @param id  network identifier
+     * @param name the network name
+     * @param adminStateUp administrative state of the network
+     * @param state the network state
+     * @param shared indicates whether this network is shared across all
+     *            tenants, By default, only administrative user can change this
+     *            value
+     * @param tenantId tenant identifier
+     * @param routerExternal network routerExternal
+     * @param type the network type
+     * @param physicalNetwork physicalNetwork identifier
+     * @param segmentationId segmentation identifier
+     */
+    public DefaultTenantNetwork(TenantNetworkId id, String name,
+                                boolean adminStateUp, State state,
+                                boolean shared, TenantId tenantId,
+                                boolean routerExternal, Type type,
+                                PhysicalNetwork physicalNetwork,
+                                SegmentationId segmentationId) {
+        this.id = id;
+        this.name = name;
+        this.adminStateUp = adminStateUp;
+        this.state = state;
+        this.shared = shared;
+        this.type = type;
+        this.tenantId = tenantId;
+        this.routerExternal = routerExternal;
+        this.physicalNetwork = physicalNetwork;
+        this.segmentationId = segmentationId;
+    }
+
+    @Override
+    public TenantNetworkId id() {
+        return id;
+    }
+
+    @Override
+    public String name() {
+        return name;
+    }
+
+    @Override
+    public boolean adminStateUp() {
+        return adminStateUp;
+    }
+
+    @Override
+    public State state() {
+        return state;
+    }
+
+    @Override
+    public boolean shared() {
+        return shared;
+    }
+
+    @Override
+    public TenantId tenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public boolean routerExternal() {
+        return routerExternal;
+    }
+
+    @Override
+    public Type type() {
+        return type;
+    }
+
+    @Override
+    public PhysicalNetwork physicalNetwork() {
+        return physicalNetwork;
+    }
+
+    @Override
+    public SegmentationId segmentationId() {
+        return segmentationId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, name, adminStateUp, state, shared, tenantId,
+                            routerExternal, type, physicalNetwork,
+                            segmentationId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultTenantNetwork) {
+            final DefaultTenantNetwork that = (DefaultTenantNetwork) obj;
+            return Objects.equals(this.id, that.id)
+                    && Objects.equals(this.name, that.name)
+                    && Objects.equals(this.adminStateUp, that.adminStateUp)
+                    && Objects.equals(this.state, that.state)
+                    && Objects.equals(this.shared, that.shared)
+                    && Objects.equals(this.tenantId, that.tenantId)
+                    && Objects.equals(this.routerExternal, that.routerExternal)
+                    && Objects.equals(this.type, that.type)
+                    && Objects.equals(this.physicalNetwork,
+                                      that.physicalNetwork)
+                    && Objects.equals(this.segmentationId, that.segmentationId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("id", id).add("name", name)
+                .add("adminStateUp", adminStateUp).add("state", state)
+                .add("shared", shared).add("tenantId", tenantId)
+                .add("routeExternal", routerExternal).add("type", type)
+                .add("physicalNetwork", physicalNetwork)
+                .add("segmentationId", segmentationId).toString();
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultVirtualPort.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultVirtualPort.java
similarity index 91%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultVirtualPort.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultVirtualPort.java
index 1965733..4de131a 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/DefaultVirtualPort.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/DefaultVirtualPort.java
@@ -1,229 +1,229 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-
-import java.util.Collection;
-import java.util.Map;
-import java.util.Objects;
-
-import org.onlab.packet.MacAddress;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.HostId;
-
-/**
- * Default implementation of VirtualPort interface .
- */
-public final class DefaultVirtualPort implements VirtualPort {
-    private final VirtualPortId id;
-    private final TenantNetworkId networkId;
-    private final Boolean adminStateUp;
-    private final String name;
-    private final State state;
-    private final MacAddress macAddress;
-    private final TenantId tenantId;
-    private final String deviceOwner;
-    private final DeviceId deviceId;
-    private final FixedIp fixedIp;
-    private final HostId bindingHostId;
-    private final String bindingVnicType;
-    private final String bindingVifType;
-    private final String bindingVifDetails;
-    private final Collection<AllowedAddressPair> allowedAddressPairs;
-    private final Collection<SecurityGroup> securityGroups;
-
-    /**
-     * Creates a VirtualPort object.
-     *
-     * @param id the virtual port identifier
-     * @param networkId the network identifier
-     * @param adminStateUp adminStateup true or false
-     * @param strMap the map of properties of virtual port
-     * @param state virtual port state
-     * @param macAddress the MAC address
-     * @param tenantId the tenant identifier
-     * @param deviceId the device identifier
-     * @param fixedIp the fixed IP
-     * @param bindingHostId the binding host identifier
-     * @param allowedAddressPairs the collection of allowdeAddressPairs
-     * @param securityGroups the collection of securityGroups
-     */
-    public DefaultVirtualPort(VirtualPortId id,
-                              TenantNetworkId networkId,
-                              Boolean adminStateUp,
-                              Map<String, String> strMap,
-                              State state,
-                              MacAddress macAddress,
-                              TenantId tenantId,
-                              DeviceId deviceId,
-                              FixedIp fixedIp,
-                              HostId bindingHostId,
-                              Collection<AllowedAddressPair> allowedAddressPairs,
-                              Collection<SecurityGroup> securityGroups) {
-        this.id = id;
-        this.networkId = networkId;
-        this.adminStateUp = adminStateUp;
-        this.name = strMap.get("name");
-        this.state = state;
-        this.macAddress = macAddress;
-        this.tenantId = tenantId;
-        this.deviceOwner = strMap.get("deviceOwner");
-        this.deviceId = deviceId;
-        this.fixedIp = fixedIp;
-        this.bindingHostId = bindingHostId;
-        this.bindingVnicType = strMap.get("bindingVnicType");
-        this.bindingVifType = strMap.get("bindingVifType");
-        this.bindingVifDetails = strMap.get("bindingVifDetails");
-        this.allowedAddressPairs = allowedAddressPairs;
-        this.securityGroups = securityGroups;
-    }
-
-    @Override
-    public VirtualPortId portId() {
-        return id;
-    }
-
-    @Override
-    public TenantNetworkId networkId() {
-        return networkId;
-    }
-
-    @Override
-    public String name() {
-        return name;
-    }
-
-    @Override
-    public boolean adminStateUp() {
-        return adminStateUp;
-    }
-
-    @Override
-    public State state() {
-        return state;
-    }
-
-    @Override
-    public MacAddress macAddress() {
-        return macAddress;
-    }
-
-    @Override
-    public TenantId tenantId() {
-        return tenantId;
-    }
-
-    @Override
-    public DeviceId deviceId() {
-        return deviceId;
-    }
-
-    @Override
-    public String deviceOwner() {
-        return deviceOwner;
-    }
-
-    @Override
-    public Collection<AllowedAddressPair> allowedAddressPairs() {
-        return allowedAddressPairs;
-    }
-
-    @Override
-    public FixedIp fixedIps() {
-        return fixedIp;
-    }
-
-    @Override
-    public HostId bindingHostId() {
-        return bindingHostId;
-    }
-
-    @Override
-    public String bindingVnicType() {
-        return bindingVifType;
-    }
-
-    @Override
-    public String bindingVifType() {
-        return bindingVifType;
-    }
-
-    @Override
-    public String bindingVifDetails() {
-        return bindingVifDetails;
-    }
-
-    @Override
-    public Collection<SecurityGroup> securityGroups() {
-        return securityGroups;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(id, networkId, adminStateUp, name, state,
-                            macAddress, tenantId, deviceId, deviceOwner,
-                            allowedAddressPairs, fixedIp, bindingHostId,
-                            bindingVnicType, bindingVifType, bindingVifDetails,
-                            securityGroups);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof DefaultVirtualPort) {
-            final DefaultVirtualPort that = (DefaultVirtualPort) obj;
-            return Objects.equals(this.id, that.id)
-                    && Objects.equals(this.networkId, that.networkId)
-                    && Objects.equals(this.adminStateUp, that.adminStateUp)
-                    && Objects.equals(this.state, that.state)
-                    && Objects.equals(this.name, that.name)
-                    && Objects.equals(this.tenantId, that.tenantId)
-                    && Objects.equals(this.macAddress, that.macAddress)
-                    && Objects.equals(this.deviceId, that.deviceId)
-                    && Objects.equals(this.deviceOwner, that.deviceOwner)
-                    && Objects.equals(this.allowedAddressPairs,
-                                      that.allowedAddressPairs)
-                    && Objects.equals(this.fixedIp, that.fixedIp)
-                    && Objects.equals(this.bindingHostId, that.bindingHostId)
-                    && Objects.equals(this.bindingVifDetails,
-                                      that.bindingVifDetails)
-                    && Objects.equals(this.bindingVifType, that.bindingVifType)
-                    && Objects.equals(this.bindingVnicType,
-                                      that.bindingVnicType)
-                    && Objects.equals(this.securityGroups, that.securityGroups);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("id", id).add("network_id", networkId)
-                .add("adminStateUp", adminStateUp).add("state", state)
-                .add("name", name).add("state", state)
-                .add("macAddress", macAddress).add("tenantId", tenantId)
-                .add("deviced", deviceId).add("deviceOwner", deviceOwner)
-                .add("allowedAddressPairs", allowedAddressPairs)
-                .add("fixedIp", fixedIp).add("bindingHostId", bindingHostId)
-                .add("bindingVnicType", bindingVnicType)
-                .add("bindingVifDetails", bindingVifDetails)
-                .add("bindingVifType", bindingVifType)
-                .add("securityGroups", securityGroups).toString();
-    }
-
-}
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Default implementation of VirtualPort interface .
+ */
+public final class DefaultVirtualPort implements VirtualPort {
+    private final VirtualPortId id;
+    private final TenantNetworkId networkId;
+    private final Boolean adminStateUp;
+    private final String name;
+    private final State state;
+    private final MacAddress macAddress;
+    private final TenantId tenantId;
+    private final String deviceOwner;
+    private final DeviceId deviceId;
+    private final Set<FixedIp> fixedIps;
+    private final BindingHostId bindingHostId;
+    private final String bindingVnicType;
+    private final String bindingVifType;
+    private final String bindingVifDetails;
+    private final Collection<AllowedAddressPair> allowedAddressPairs;
+    private final Collection<SecurityGroup> securityGroups;
+
+    /**
+     * Creates a VirtualPort object.
+     *
+     * @param id the virtual port identifier
+     * @param networkId the network identifier
+     * @param adminStateUp adminStateup true or false
+     * @param strMap the map of properties of virtual port
+     * @param state virtual port state
+     * @param macAddress the MAC address
+     * @param tenantId the tenant identifier
+     * @param deviceId the device identifier
+     * @param fixedIps set of fixed IP
+     * @param bindingHostId the binding host identifier
+     * @param allowedAddressPairs the collection of allowdeAddressPairs
+     * @param securityGroups the collection of securityGroups
+     */
+    public DefaultVirtualPort(VirtualPortId id,
+                              TenantNetworkId networkId,
+                              Boolean adminStateUp,
+                              Map<String, String> strMap,
+                              State state,
+                              MacAddress macAddress,
+                              TenantId tenantId,
+                              DeviceId deviceId,
+                              Set<FixedIp> fixedIps,
+                              BindingHostId bindingHostId,
+                              Collection<AllowedAddressPair> allowedAddressPairs,
+                              Collection<SecurityGroup> securityGroups) {
+        this.id = id;
+        this.networkId = networkId;
+        this.adminStateUp = adminStateUp;
+        this.name = strMap.get("name");
+        this.state = state;
+        this.macAddress = macAddress;
+        this.tenantId = tenantId;
+        this.deviceOwner = strMap.get("deviceOwner");
+        this.deviceId = deviceId;
+        this.fixedIps = fixedIps;
+        this.bindingHostId = bindingHostId;
+        this.bindingVnicType = strMap.get("bindingVnicType");
+        this.bindingVifType = strMap.get("bindingVifType");
+        this.bindingVifDetails = strMap.get("bindingVifDetails");
+        this.allowedAddressPairs = allowedAddressPairs;
+        this.securityGroups = securityGroups;
+    }
+
+    @Override
+    public VirtualPortId portId() {
+        return id;
+    }
+
+    @Override
+    public TenantNetworkId networkId() {
+        return networkId;
+    }
+
+    @Override
+    public String name() {
+        return name;
+    }
+
+    @Override
+    public boolean adminStateUp() {
+        return adminStateUp;
+    }
+
+    @Override
+    public State state() {
+        return state;
+    }
+
+    @Override
+    public MacAddress macAddress() {
+        return macAddress;
+    }
+
+    @Override
+    public TenantId tenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public DeviceId deviceId() {
+        return deviceId;
+    }
+
+    @Override
+    public String deviceOwner() {
+        return deviceOwner;
+    }
+
+    @Override
+    public Collection<AllowedAddressPair> allowedAddressPairs() {
+        return allowedAddressPairs;
+    }
+
+    @Override
+    public Set<FixedIp> fixedIps() {
+        return fixedIps;
+    }
+
+    @Override
+    public BindingHostId bindingHostId() {
+        return bindingHostId;
+    }
+
+    @Override
+    public String bindingVnicType() {
+        return bindingVifType;
+    }
+
+    @Override
+    public String bindingVifType() {
+        return bindingVifType;
+    }
+
+    @Override
+    public String bindingVifDetails() {
+        return bindingVifDetails;
+    }
+
+    @Override
+    public Collection<SecurityGroup> securityGroups() {
+        return securityGroups;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, networkId, adminStateUp, name, state,
+                            macAddress, tenantId, deviceId, deviceOwner,
+                            allowedAddressPairs, fixedIps, bindingHostId,
+                            bindingVnicType, bindingVifType, bindingVifDetails,
+                            securityGroups);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DefaultVirtualPort) {
+            final DefaultVirtualPort that = (DefaultVirtualPort) obj;
+            return Objects.equals(this.id, that.id)
+                    && Objects.equals(this.networkId, that.networkId)
+                    && Objects.equals(this.adminStateUp, that.adminStateUp)
+                    && Objects.equals(this.state, that.state)
+                    && Objects.equals(this.name, that.name)
+                    && Objects.equals(this.tenantId, that.tenantId)
+                    && Objects.equals(this.macAddress, that.macAddress)
+                    && Objects.equals(this.deviceId, that.deviceId)
+                    && Objects.equals(this.deviceOwner, that.deviceOwner)
+                    && Objects.equals(this.allowedAddressPairs,
+                                      that.allowedAddressPairs)
+                    && Objects.equals(this.fixedIps, that.fixedIps)
+                    && Objects.equals(this.bindingHostId, that.bindingHostId)
+                    && Objects.equals(this.bindingVifDetails,
+                                      that.bindingVifDetails)
+                    && Objects.equals(this.bindingVifType, that.bindingVifType)
+                    && Objects.equals(this.bindingVnicType,
+                                      that.bindingVnicType)
+                    && Objects.equals(this.securityGroups, that.securityGroups);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("id", id).add("network_id", networkId)
+                .add("adminStateUp", adminStateUp).add("state", state)
+                .add("name", name).add("state", state)
+                .add("macAddress", macAddress).add("tenantId", tenantId)
+                .add("deviced", deviceId).add("deviceOwner", deviceOwner)
+                .add("allowedAddressPairs", allowedAddressPairs)
+                .add("fixedIp", fixedIps).add("bindingHostId", bindingHostId)
+                .add("bindingVnicType", bindingVnicType)
+                .add("bindingVifDetails", bindingVifDetails)
+                .add("bindingVifType", bindingVifType)
+                .add("securityGroups", securityGroups).toString();
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/FixedIp.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/FixedIp.java
similarity index 98%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/FixedIp.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/FixedIp.java
index 82c86fd..dcfb72a 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/FixedIp.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/FixedIp.java
@@ -1,93 +1,93 @@
-/*
- * 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.app.vtnrsc;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-import org.onlab.packet.IpAddress;
-
-/**
- * Immutable representation of a IP address for the port, Include the IP address
- * and subnet identity.
- */
-public final class FixedIp {
-    private final SubnetId subnetId;
-    private final IpAddress ip;
-    // Public construction is prohibited
-    private FixedIp(SubnetId subnetId, IpAddress ip) {
-        checkNotNull(subnetId, "SubnetId cannot be null");
-        checkNotNull(ip, "IpAddress cannot be null");
-        this.subnetId = subnetId;
-        this.ip = ip;
-    }
-
-    /**
-     * Returns the FixedIp subnet identifier.
-     *
-     * @return subnet identifier
-     */
-    public SubnetId subnetId() {
-        return subnetId;
-    }
-
-    /**
-     * Returns the FixedIp IP address.
-     *
-     * @return IP address
-     */
-    public IpAddress ip() {
-        return ip;
-    }
-
-    /**
-     * Creates a fixed ip using the supplied fixedIp.
-     *
-     * @param subnetId subnet identity
-     * @param ip IP address
-     * @return FixedIp
-     */
-    public static FixedIp fixedIp(SubnetId subnetId, IpAddress ip) {
-        return new FixedIp(subnetId, ip);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(subnetId, ip);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof FixedIp) {
-            final FixedIp that = (FixedIp) obj;
-            return Objects.equals(this.subnetId, that.subnetId)
-                    && Objects.equals(this.ip, that.ip);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("subnetId", subnetId).add("ip", ip)
-                .toString();
-    }
-
-}
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+import org.onlab.packet.IpAddress;
+
+/**
+ * Immutable representation of a IP address for the port, Include the IP address
+ * and subnet identity.
+ */
+public final class FixedIp {
+    private final SubnetId subnetId;
+    private final IpAddress ip;
+    // Public construction is prohibited
+    private FixedIp(SubnetId subnetId, IpAddress ip) {
+        checkNotNull(subnetId, "SubnetId cannot be null");
+        checkNotNull(ip, "IpAddress cannot be null");
+        this.subnetId = subnetId;
+        this.ip = ip;
+    }
+
+    /**
+     * Returns the FixedIp subnet identifier.
+     *
+     * @return subnet identifier
+     */
+    public SubnetId subnetId() {
+        return subnetId;
+    }
+
+    /**
+     * Returns the FixedIp IP address.
+     *
+     * @return IP address
+     */
+    public IpAddress ip() {
+        return ip;
+    }
+
+    /**
+     * Creates a fixed ip using the supplied fixedIp.
+     *
+     * @param subnetId subnet identity
+     * @param ip IP address
+     * @return FixedIp
+     */
+    public static FixedIp fixedIp(SubnetId subnetId, IpAddress ip) {
+        return new FixedIp(subnetId, ip);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(subnetId, ip);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof FixedIp) {
+            final FixedIp that = (FixedIp) obj;
+            return Objects.equals(this.subnetId, that.subnetId)
+                    && Objects.equals(this.ip, that.ip);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("subnetId", subnetId).add("ip", ip)
+                .toString();
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/HostRoute.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/HostRoute.java
similarity index 96%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/HostRoute.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/HostRoute.java
index 77f930c..74c2816 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/HostRoute.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/HostRoute.java
@@ -1,39 +1,39 @@
-/*
- * 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.app.vtnrsc;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-
-/**
- * Host route dictionaries for the subnet.
- */
-public interface HostRoute {
-
-    /**
-     * Returns the next hop address.
-     *
-     * @return next hop address
-     */
-    IpAddress nexthop();
-
-    /**
-     * Returns the destination address.
-     *
-     * @return destination address
-     */
-    IpPrefix destination();
-}
+/*
+ * 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.vtnrsc;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+
+/**
+ * Host route dictionaries for the subnet.
+ */
+public interface HostRoute {
+
+    /**
+     * Returns the next hop address.
+     *
+     * @return next hop address
+     */
+    IpAddress nexthop();
+
+    /**
+     * Returns the destination address.
+     *
+     * @return destination address
+     */
+    IpPrefix destination();
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/PhysicalNetwork.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/PhysicalNetwork.java
similarity index 62%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/PhysicalNetwork.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/PhysicalNetwork.java
index 5b0e0f2..6a0c5cb 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/PhysicalNetwork.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/PhysicalNetwork.java
@@ -1,77 +1,78 @@
-/*
- * 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.app.vtnrsc;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Immutable representation of a physicalnetwork identity.
- */
-public final class PhysicalNetwork {
-
-    private final String physicalnetwork;
-
-    // Public construction is prohibited
-    private PhysicalNetwork(String physicalnetwork) {
-        checkNotNull(physicalnetwork, "Physicalnetwork cannot be null");
-        this.physicalnetwork = physicalnetwork;
-    }
-
-    /**
-     * Creates a network id using the physicalnetwork.
-     *
-     * @param physicalnetwork network String
-     * @return physicalnetwork
-     */
-    public static PhysicalNetwork physicalNetwork(String physicalnetwork) {
-        return new PhysicalNetwork(physicalnetwork);
-    }
-
-    /**
-     *
-     * @return physicalnetwork
-     */
-    public String physicalnetwork() {
-        return physicalnetwork;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(physicalnetwork);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof PhysicalNetwork) {
-            final PhysicalNetwork that = (PhysicalNetwork) obj;
-            return this.getClass() == that.getClass()
-                    && Objects.equals(this.physicalnetwork,
-                                      that.physicalnetwork);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return physicalnetwork;
-    }
-
-}
+/*
+ * 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.vtnrsc;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Immutable representation of a physical network identity.
+ */
+public final class PhysicalNetwork {
+
+    private final String physicalNetwork;
+
+    // Public construction is prohibited
+    private PhysicalNetwork(String physicalNetwork) {
+        checkNotNull(physicalNetwork, "PhysicalNetwork cannot be null");
+        this.physicalNetwork = physicalNetwork;
+    }
+
+    /**
+     * Creates a PhysicalNetwork object.
+     *
+     * @param physicalNetwork physical network
+     * @return physical network
+     */
+    public static PhysicalNetwork physicalNetwork(String physicalNetwork) {
+        return new PhysicalNetwork(physicalNetwork);
+    }
+
+    /**
+     * Returns a physicalNetwork.
+     *
+     * @return physical network
+     */
+    public String physicalNetwork() {
+        return physicalNetwork;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(physicalNetwork);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PhysicalNetwork) {
+            final PhysicalNetwork that = (PhysicalNetwork) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.physicalNetwork,
+                                      that.physicalNetwork);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return physicalNetwork;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SecurityGroup.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SecurityGroup.java
similarity index 98%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SecurityGroup.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SecurityGroup.java
index 4171362..7f09806 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SecurityGroup.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SecurityGroup.java
@@ -1,77 +1,77 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc;
-
-import java.util.Objects;
-
-import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Immutable representation of a security group.
- */
-public final class SecurityGroup {
-    private final String securityGroup;
-
-    /**
-     * Returns the securityGroup.
-     *
-     * @return securityGroup
-     */
-    public String securityGroup() {
-        return securityGroup;
-    }
-    // Public construction is prohibited
-    private SecurityGroup(String securityGroup) {
-        checkNotNull(securityGroup, "SecurityGroup cannot be null");
-        this.securityGroup = securityGroup;
-    }
-
-    /**
-     * Creates a securityGroup using the supplied securityGroup.
-     *
-     * @param securityGroup security group
-     * @return securityGroup
-     */
-    public static SecurityGroup securityGroup(String securityGroup) {
-        return new SecurityGroup(securityGroup);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(securityGroup);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof SecurityGroup) {
-            final SecurityGroup that = (SecurityGroup) obj;
-            return this.getClass() == that.getClass()
-                    && Objects.equals(this.securityGroup, that.securityGroup);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return toStringHelper(this).add("securityGroup", securityGroup)
-                .toString();
-    }
-
-}
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.vtnrsc;
+
+import java.util.Objects;
+
+import static com.google.common.base.MoreObjects.toStringHelper;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Immutable representation of a security group.
+ */
+public final class SecurityGroup {
+    private final String securityGroup;
+
+    /**
+     * Returns the securityGroup.
+     *
+     * @return securityGroup
+     */
+    public String securityGroup() {
+        return securityGroup;
+    }
+    // Public construction is prohibited
+    private SecurityGroup(String securityGroup) {
+        checkNotNull(securityGroup, "SecurityGroup cannot be null");
+        this.securityGroup = securityGroup;
+    }
+
+    /**
+     * Creates a securityGroup using the supplied securityGroup.
+     *
+     * @param securityGroup security group
+     * @return securityGroup
+     */
+    public static SecurityGroup securityGroup(String securityGroup) {
+        return new SecurityGroup(securityGroup);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(securityGroup);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof SecurityGroup) {
+            final SecurityGroup that = (SecurityGroup) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.securityGroup, that.securityGroup);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return toStringHelper(this).add("securityGroup", securityGroup)
+                .toString();
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SegmentationId.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SegmentationId.java
similarity index 98%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SegmentationId.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SegmentationId.java
index 96969a0..69f9dce 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SegmentationId.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SegmentationId.java
@@ -1,77 +1,77 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Immutable representation of a Segmentation identifier.
- */
-public final class SegmentationId {
-
-    private final String segmentationId;
-
-    // Public construction is prohibited
-    private SegmentationId(String segmentationId) {
-        checkNotNull(segmentationId, "SegmentationId cannot be null");
-        this.segmentationId = segmentationId;
-    }
-
-    /**
-     * Creates a  SegmentationId object.
-     *
-     * @param segmentationId segmentation identifier
-     * @return SegmentationId
-     */
-    public static SegmentationId segmentationId(String segmentationId) {
-        return new SegmentationId(segmentationId);
-    }
-
-    /**
-     * Returns the segmentation identifier.
-     *
-     * @return segmentationId
-     */
-    public String segmentationId() {
-        return segmentationId;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(segmentationId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof SegmentationId) {
-            final SegmentationId that = (SegmentationId) obj;
-            return this.getClass() == that.getClass()
-                    && Objects.equals(this.segmentationId, that.segmentationId);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return segmentationId;
-    }
-
-}
+/*
+ * 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.vtnrsc;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Immutable representation of a Segmentation identifier.
+ */
+public final class SegmentationId {
+
+    private final String segmentationId;
+
+    // Public construction is prohibited
+    private SegmentationId(String segmentationId) {
+        checkNotNull(segmentationId, "SegmentationId cannot be null");
+        this.segmentationId = segmentationId;
+    }
+
+    /**
+     * Creates a  SegmentationId object.
+     *
+     * @param segmentationId segmentation identifier
+     * @return SegmentationId
+     */
+    public static SegmentationId segmentationId(String segmentationId) {
+        return new SegmentationId(segmentationId);
+    }
+
+    /**
+     * Returns the segmentation identifier.
+     *
+     * @return segmentationId
+     */
+    public String segmentationId() {
+        return segmentationId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(segmentationId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof SegmentationId) {
+            final SegmentationId that = (SegmentationId) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.segmentationId, that.segmentationId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return segmentationId;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/Subnet.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/Subnet.java
similarity index 96%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/Subnet.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/Subnet.java
index 87ae549..1104d7e 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/Subnet.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/Subnet.java
@@ -1,129 +1,129 @@
-/*
- *Copyright 2014 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.app.vtnrsc;
-
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpAddress.Version;
-import org.onlab.packet.IpPrefix;
-
-/**
- * Representation of a subnet.
- */
-public interface Subnet {
-
-    /**
-     * Coarse classification of the type of the ipV6Mode.
-     */
-    public enum Mode {
-        DHCPV6_STATEFUL, DHCPV6_STATELESS, SLAAC
-    }
-
-    /**
-     * Returns the subnet identifier.
-     *
-     * @return identifier
-     */
-    SubnetId id();
-
-    /**
-     * Returns the name of the subnet.
-     *
-     * @return subnetName
-     */
-    String subnetName();
-
-    /**
-     * Returns the network identifier.
-     *
-     * @return the network identifier
-     */
-    TenantNetworkId networkId();
-
-    /**
-     * Returns tenant identifier.
-     *
-     * @return the tenant identifier
-     */
-    TenantId tenantId();
-
-    /**
-     * Returns the IP version, which is 4 or 6.
-     *
-     * @return ipVersion
-     */
-    Version ipVersion();
-
-    /**
-     * Returns the cidr.
-     *
-     * @return cidr
-     */
-    IpPrefix cidr();
-
-    /**
-     * Returns the gateway IP address.
-     *
-     * @return gatewayIp
-     */
-    IpAddress gatewayIp();
-
-    /**
-     * Returns true if DHCP is enabled and return false if DHCP is disabled.
-     *
-     * @return true or false
-     */
-    boolean dhcpEnabled();
-
-    /**
-     * Indicates whether this tenantNetwork is shared across all tenants. By
-     * default, only administrative user can change this value.
-     *
-     * @return true or false
-     */
-    boolean shared();
-
-    /**
-     * Returns a collection of hostRoutes.
-     *
-     * @return a collection of hostRoutes
-     */
-    Iterable<HostRoute> hostRoutes();
-
-    /**
-     * Returns the ipV6AddressMode. A valid value is dhcpv6-stateful,
-     * dhcpv6-stateless, or slaac.
-     *
-     * @return ipV6AddressMode whose value is dhcpv6-stateful, dhcpv6-stateless
-     *         or slaac
-     */
-    Mode ipV6AddressMode();
-
-    /**
-     * Returns the ipV6RaMode.A valid value is dhcpv6-stateful,
-     * dhcpv6-stateless, or slaac.
-     *
-     * @return ipV6RaMode whose value is dhcpv6-stateful, dhcpv6-stateless or
-     *         slaac
-     */
-    Mode ipV6RaMode();
-
-    /**
-     * Returns a collection of allocation_pools.
-     *
-     * @return a collection of allocationPools
-     */
-    Iterable<AllocationPool> allocationPools();
-}
+/*
+ *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.vtnrsc;
+
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpAddress.Version;
+import org.onlab.packet.IpPrefix;
+
+/**
+ * Representation of a subnet.
+ */
+public interface Subnet {
+
+    /**
+     * Coarse classification of the type of the ipV6Mode.
+     */
+    public enum Mode {
+        DHCPV6_STATEFUL, DHCPV6_STATELESS, SLAAC
+    }
+
+    /**
+     * Returns the subnet identifier.
+     *
+     * @return identifier
+     */
+    SubnetId id();
+
+    /**
+     * Returns the name of the subnet.
+     *
+     * @return subnetName
+     */
+    String subnetName();
+
+    /**
+     * Returns the network identifier.
+     *
+     * @return the network identifier
+     */
+    TenantNetworkId networkId();
+
+    /**
+     * Returns tenant identifier.
+     *
+     * @return the tenant identifier
+     */
+    TenantId tenantId();
+
+    /**
+     * Returns the IP version, which is 4 or 6.
+     *
+     * @return ipVersion
+     */
+    Version ipVersion();
+
+    /**
+     * Returns the cidr.
+     *
+     * @return cidr
+     */
+    IpPrefix cidr();
+
+    /**
+     * Returns the gateway IP address.
+     *
+     * @return gatewayIp
+     */
+    IpAddress gatewayIp();
+
+    /**
+     * Returns true if DHCP is enabled and return false if DHCP is disabled.
+     *
+     * @return true or false
+     */
+    boolean dhcpEnabled();
+
+    /**
+     * Indicates whether this tenantNetwork is shared across all tenants. By
+     * default, only administrative user can change this value.
+     *
+     * @return true or false
+     */
+    boolean shared();
+
+    /**
+     * Returns a collection of hostRoutes.
+     *
+     * @return a collection of hostRoutes
+     */
+    Iterable<HostRoute> hostRoutes();
+
+    /**
+     * Returns the ipV6AddressMode. A valid value is dhcpv6-stateful,
+     * dhcpv6-stateless, or slaac.
+     *
+     * @return ipV6AddressMode whose value is dhcpv6-stateful, dhcpv6-stateless
+     *         or slaac
+     */
+    Mode ipV6AddressMode();
+
+    /**
+     * Returns the ipV6RaMode.A valid value is dhcpv6-stateful,
+     * dhcpv6-stateless, or slaac.
+     *
+     * @return ipV6RaMode whose value is dhcpv6-stateful, dhcpv6-stateless or
+     *         slaac
+     */
+    Mode ipV6RaMode();
+
+    /**
+     * Returns a collection of allocation_pools.
+     *
+     * @return a collection of allocationPools
+     */
+    Iterable<AllocationPool> allocationPools();
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SubnetId.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SubnetId.java
similarity index 97%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SubnetId.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SubnetId.java
index 34a3a3c..e0c1aee 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/SubnetId.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/SubnetId.java
@@ -1,76 +1,76 @@
-/*
- * 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.app.vtnrsc;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-/**
- * Immutable representation of a subnet identifier.
- */
-public final class SubnetId {
-
-    private final String subnetId;
-
-    // Public construction is prohibited
-    private SubnetId(String subnetId) {
-        checkNotNull(subnetId, "SubnetId cannot be null");
-        this.subnetId = subnetId;
-    }
-
-    /**
-     * Creates a Subnet identifier.
-     *
-     * @param subnetId the subnet identifier
-     * @return the subnet identifier
-     */
-    public static SubnetId subnetId(String subnetId) {
-        return new SubnetId(subnetId);
-    }
-
-    /**
-     * Returns the subnet identifier.
-     *
-     * @return the subnet identifier
-     */
-    public String subnetId() {
-        return subnetId;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(subnetId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof SubnetId) {
-            final SubnetId that = (SubnetId) obj;
-            return this.getClass() == that.getClass()
-                    && Objects.equals(this.subnetId, that.subnetId);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return subnetId;
-    }
-}
+/*
+ * 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.vtnrsc;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * Immutable representation of a subnet identifier.
+ */
+public final class SubnetId {
+
+    private final String subnetId;
+
+    // Public construction is prohibited
+    private SubnetId(String subnetId) {
+        checkNotNull(subnetId, "SubnetId cannot be null");
+        this.subnetId = subnetId;
+    }
+
+    /**
+     * Creates a Subnet identifier.
+     *
+     * @param subnetId the subnet identifier
+     * @return the subnet identifier
+     */
+    public static SubnetId subnetId(String subnetId) {
+        return new SubnetId(subnetId);
+    }
+
+    /**
+     * Returns the subnet identifier.
+     *
+     * @return the subnet identifier
+     */
+    public String subnetId() {
+        return subnetId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(subnetId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof SubnetId) {
+            final SubnetId that = (SubnetId) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.subnetId, that.subnetId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return subnetId;
+    }
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantId.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantId.java
similarity index 76%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantId.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantId.java
index 4ae9b57..9d44c46 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantId.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantId.java
@@ -1,76 +1,77 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc;
-
-import java.util.Objects;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Immutable representation of a network identity.
- */
-public final class TenantId {
-
-    private final String tenantid;
-
-    // Public construction is prohibited
-    private TenantId(String tenantid) {
-        this.tenantid = tenantid;
-    }
-
-    /**
-     * Creates a network id using the tenantid.
-     *
-     * @param tenantid network String
-     * @return TenantId
-     */
-    public static TenantId tenantId(String tenantid) {
-        checkNotNull(tenantid, "Tenantid can not be null");
-        return new TenantId(tenantid);
-    }
-
-    /**
-     *
-     * @return tenantid
-     */
-    public String tenantid() {
-        return tenantid;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(tenantid);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof TenantId) {
-            final TenantId that = (TenantId) obj;
-            return this.getClass() == that.getClass()
-                    && Objects.equals(this.tenantid, that.tenantid);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return tenantid;
-    }
-
-}
+/*
+ * 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.vtnrsc;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Immutable representation of a tenant identifier.
+ */
+public final class TenantId {
+
+    private final String tenantId;
+
+    // Public construction is prohibited
+    private TenantId(String tenantId) {
+        this.tenantId = tenantId;
+    }
+
+    /**
+     * Creates a network id using the tenantid.
+     *
+     * @param tenantid network String
+     * @return TenantId
+     */
+    public static TenantId tenantId(String tenantid) {
+        checkNotNull(tenantid, "Tenantid can not be null");
+        return new TenantId(tenantid);
+    }
+
+    /**
+     * Returns the tenant identifier.
+     *
+     * @return the tenant identifier
+     */
+    public String tenantId() {
+        return tenantId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(tenantId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TenantId) {
+            final TenantId that = (TenantId) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.tenantId, that.tenantId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return tenantId;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetwork.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantNetwork.java
similarity index 97%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetwork.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantNetwork.java
index f196f50..d9238f9 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetwork.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantNetwork.java
@@ -1,130 +1,130 @@
-/*
- * 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.app.vtnrsc;
-
-/**
- * Representation of the tenantNetwork.
- */
-public interface TenantNetwork {
-
-    /**
-     * Coarse classification of the state of the tenantNetwork.
-     */
-    public enum State {
-        /**
-         * Signifies that a tenantNetwork is currently active.This state means
-         * that this network is available.
-         */
-        ACTIVE,
-        /**
-         * Signifies that a tenantNetwork is currently built.
-         */
-        BUILD,
-        /**
-         * Signifies that a tenantNetwork is currently unavailable.
-         */
-        DOWN,
-        /**
-         * Signifies that a tenantNetwork is currently error.
-         */
-        ERROR
-    }
-
-    /**
-     * Coarse classification of the type of the tenantNetwork.
-     */
-    public enum Type {
-        /**
-         * Signifies that a tenantNetwork is local.
-         */
-        LOCAL
-    }
-
-    /**
-     * Returns the tenantNetwork identifier.
-     *
-     * @return tenantNetwork identifier
-     */
-    TenantNetworkId id();
-
-    /**
-     * Returns the tenantNetwork name.
-     *
-     * @return tenantNetwork name
-     */
-    String name();
-
-    /**
-     * Returns the administrative state of the tenantNetwork,which is up(true)
-     * or down(false).
-     *
-     * @return true or false
-     */
-    boolean adminStateUp();
-
-    /**
-     * Returns the tenantNetwork state.
-     *
-     * @return tenant network state
-     */
-    State state();
-
-    /**
-     * Indicates whether this tenantNetwork is shared across all tenants. By
-     * default,only administrative user can change this value.
-     *
-     * @return true or false
-     */
-    boolean shared();
-
-    /**
-     * Returns the UUID of the tenant that will own the tenantNetwork. This
-     * tenant can be different from the tenant that makes the create
-     * tenantNetwork request.
-     *
-     * @return tenantNetwork tenant identifier
-     */
-    TenantId tenantId();
-
-    /**
-     * Returns the routerExternal.Indicates whether this network is externally
-     * accessible.
-     *
-     * @return true or false
-     */
-    boolean routerExternal();
-
-    /**
-     * Returns the tenantNetwork Type.
-     *
-     * @return tenantNetwork Type
-     */
-    Type type();
-
-    /**
-     * Returns the tenantNetwork physical network.
-     *
-     * @return tenantNetwork physical network
-     */
-    PhysicalNetwork physicalNetwork();
-
-    /**
-     * Returns the tenantNetwork segmentation id.
-     *
-     * @return tenantNetwork segmentation id
-     */
-    SegmentationId segmentationId();
-}
+/*
+ * 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.vtnrsc;
+
+/**
+ * Representation of the tenantNetwork.
+ */
+public interface TenantNetwork {
+
+    /**
+     * Coarse classification of the state of the tenantNetwork.
+     */
+    public enum State {
+        /**
+         * Signifies that a tenantNetwork is currently active.This state means
+         * that this network is available.
+         */
+        ACTIVE,
+        /**
+         * Signifies that a tenantNetwork is currently built.
+         */
+        BUILD,
+        /**
+         * Signifies that a tenantNetwork is currently unavailable.
+         */
+        DOWN,
+        /**
+         * Signifies that a tenantNetwork is currently error.
+         */
+        ERROR
+    }
+
+    /**
+     * Coarse classification of the type of the tenantNetwork.
+     */
+    public enum Type {
+        /**
+         * Signifies that a tenantNetwork is local.
+         */
+        LOCAL
+    }
+
+    /**
+     * Returns the tenantNetwork identifier.
+     *
+     * @return tenantNetwork identifier
+     */
+    TenantNetworkId id();
+
+    /**
+     * Returns the tenantNetwork name.
+     *
+     * @return tenantNetwork name
+     */
+    String name();
+
+    /**
+     * Returns the administrative state of the tenantNetwork,which is up(true)
+     * or down(false).
+     *
+     * @return true or false
+     */
+    boolean adminStateUp();
+
+    /**
+     * Returns the tenantNetwork state.
+     *
+     * @return tenant network state
+     */
+    State state();
+
+    /**
+     * Indicates whether this tenantNetwork is shared across all tenants. By
+     * default,only administrative user can change this value.
+     *
+     * @return true or false
+     */
+    boolean shared();
+
+    /**
+     * Returns the UUID of the tenant that will own the tenantNetwork. This
+     * tenant can be different from the tenant that makes the create
+     * tenantNetwork request.
+     *
+     * @return the tenant identifier
+     */
+    TenantId tenantId();
+
+    /**
+     * Returns the routerExternal.Indicates whether this network is externally
+     * accessible.
+     *
+     * @return true or false
+     */
+    boolean routerExternal();
+
+    /**
+     * Returns the tenantNetwork Type.
+     *
+     * @return tenantNetwork Type
+     */
+    Type type();
+
+    /**
+     * Returns the tenantNetwork physical network.
+     *
+     * @return tenantNetwork physical network
+     */
+    PhysicalNetwork physicalNetwork();
+
+    /**
+     * Returns the tenantNetwork segmentation id.
+     *
+     * @return tenantNetwork segmentation id
+     */
+    SegmentationId segmentationId();
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetworkId.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantNetworkId.java
similarity index 97%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetworkId.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantNetworkId.java
index 03ff6bf..81c9962 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/TenantNetworkId.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/TenantNetworkId.java
@@ -1,76 +1,76 @@
-/*
- * 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.app.vtnrsc;
-
-import java.util.Objects;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Immutable representation of a tenantNetwork identity.
- */
-public final class TenantNetworkId {
-
-    private final String networkId;
-
-    // Public construction is prohibited
-    private TenantNetworkId(String networkId) {
-        this.networkId = networkId;
-    }
-
-    /**
-     * Creates a TenantNetwork identifier.
-     *
-     * @param networkId tenantNetwork identify string
-     * @return the attached tenantNetwork identifier
-     */
-    public static TenantNetworkId networkId(String networkId) {
-        checkNotNull(networkId, "Networkid cannot be null");
-        return new TenantNetworkId(networkId);
-    }
-
-    /**
-     * Returns tenantNetwork identifier.
-     *
-     * @return the tenantNetwork identifier
-     */
-    public String networkId() {
-        return networkId;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(networkId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof TenantNetworkId) {
-            final TenantNetworkId that = (TenantNetworkId) obj;
-            return this.getClass() == that.getClass()
-                    && Objects.equals(this.networkId, that.networkId);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return networkId;
-    }
-
-}
+/*
+ * 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.vtnrsc;
+
+import java.util.Objects;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+/**
+ * Immutable representation of a tenantNetwork identity.
+ */
+public final class TenantNetworkId {
+
+    private final String networkId;
+
+    // Public construction is prohibited
+    private TenantNetworkId(String networkId) {
+        this.networkId = networkId;
+    }
+
+    /**
+     * Creates a TenantNetwork identifier.
+     *
+     * @param networkId tenantNetwork identify string
+     * @return the attached tenantNetwork identifier
+     */
+    public static TenantNetworkId networkId(String networkId) {
+        checkNotNull(networkId, "Networkid cannot be null");
+        return new TenantNetworkId(networkId);
+    }
+
+    /**
+     * Returns tenantNetwork identifier.
+     *
+     * @return the tenantNetwork identifier
+     */
+    public String networkId() {
+        return networkId;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(networkId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof TenantNetworkId) {
+            final TenantNetworkId that = (TenantNetworkId) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.networkId, that.networkId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return networkId;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/VirtualPort.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/VirtualPort.java
similarity index 92%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/VirtualPort.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/VirtualPort.java
index 1f83c81..a607109 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/VirtualPort.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/VirtualPort.java
@@ -1,156 +1,156 @@
-/*
- * 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.app.vtnrsc;
-
-import java.util.Collection;
-
-import org.onlab.packet.MacAddress;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.HostId;
-
-/**
- * Representation of the VirtualPort.
- */
-public interface VirtualPort {
-    /**
-     * Coarse classification of the type of the virtual port.
-     */
-    public enum State {
-        /**
-         * Signifies that a virtualPort is currently active,This state mean that
-         * this virtualPort is available.
-         */
-        ACTIVE,
-        /**
-         * Signifies that a virtualPort is currently unavailable.
-         */
-        DOWN;
-    }
-
-    /**
-     * Returns the virtualPort identifier.
-     *
-     * @return virtualPort identifier
-     */
-    VirtualPortId portId();
-
-    /**
-     * Returns the network identifier.
-     *
-     * @return tenantNetwork identifier
-     */
-    TenantNetworkId networkId();
-
-    /**
-     * Returns the symbolic name for the virtualPort.
-     *
-     * @return virtualPort name
-     */
-    String name();
-
-    /**
-     * Returns the administrative status of the port,which is up(true) or
-     * down(false).
-     *
-     * @return true if the administrative status of the port is up
-     */
-    boolean adminStateUp();
-
-    /**
-     * Returns the state.
-     *
-     * @return state
-     */
-    State state();
-
-    /**
-     * Returns the MAC address.
-     *
-     * @return MAC Address
-     */
-    MacAddress macAddress();
-
-    /**
-     * Returns the port tenantId.
-     *
-     * @return port tenantId
-     */
-    TenantId tenantId();
-
-    /**
-     * Returns the device identifier.
-     *
-     * @return deviceId
-     */
-    DeviceId deviceId();
-
-    /**
-     * Returns the identifier of the entity that uses this port.
-     *
-     * @return deviceOwner
-     */
-    String deviceOwner();
-
-    /**
-     * Returns the virtualPort allowedAddressPairs.
-     *
-     * @return virtualPort allowedAddressPairs
-     */
-    Collection<AllowedAddressPair> allowedAddressPairs();
-
-    /**
-     * Returns the IP address for the port, Include the IP address and subnet
-     * identity.
-     *
-     * @return port fixedIps
-     */
-    FixedIp fixedIps();
-
-    /**
-     * Returns the virtualPort bindinghostId.
-     *
-     * @return virtualPort bindinghostId
-     */
-    HostId bindingHostId();
-
-    /**
-     * Returns the virtualPort bindingVnicType.
-     *
-     * @return virtualPort bindingVnicType
-     */
-    String bindingVnicType();
-
-    /**
-     * Returns the virtualPort bindingVifType.
-     *
-     * @return virtualPort bindingVifType
-     */
-    String bindingVifType();
-
-    /**
-     * Returns the virtualPort bindingvifDetail.
-     *
-     * @return virtualPort bindingvifDetail
-     */
-    String bindingVifDetails();
-
-    /**
-     * Returns the security groups.
-     *
-     * @return port security groups
-     */
-    Iterable<SecurityGroup> securityGroups();
-}
+/*
+ * 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.vtnrsc;
+
+import java.util.Collection;
+import java.util.Set;
+
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.DeviceId;
+
+/**
+ * Representation of the VirtualPort.
+ */
+public interface VirtualPort {
+    /**
+     * Coarse classification of the type of the virtual port.
+     */
+    public enum State {
+        /**
+         * Signifies that a virtualPort is currently active,This state mean that
+         * this virtualPort is available.
+         */
+        ACTIVE,
+        /**
+         * Signifies that a virtualPort is currently unavailable.
+         */
+        DOWN;
+    }
+
+    /**
+     * Returns the virtualPort identifier.
+     *
+     * @return virtualPort identifier
+     */
+    VirtualPortId portId();
+
+    /**
+     * Returns the network identifier.
+     *
+     * @return tenantNetwork identifier
+     */
+    TenantNetworkId networkId();
+
+    /**
+     * Returns the symbolic name for the virtualPort.
+     *
+     * @return virtualPort name
+     */
+    String name();
+
+    /**
+     * Returns the administrative status of the port,which is up(true) or
+     * down(false).
+     *
+     * @return true if the administrative status of the port is up
+     */
+    boolean adminStateUp();
+
+    /**
+     * Returns the state.
+     *
+     * @return state
+     */
+    State state();
+
+    /**
+     * Returns the MAC address.
+     *
+     * @return MAC Address
+     */
+    MacAddress macAddress();
+
+    /**
+     * Returns the port tenantId.
+     *
+     * @return port tenantId
+     */
+    TenantId tenantId();
+
+    /**
+     * Returns the device identifier.
+     *
+     * @return deviceId
+     */
+    DeviceId deviceId();
+
+    /**
+     * Returns the identifier of the entity that uses this port.
+     *
+     * @return deviceOwner
+     */
+    String deviceOwner();
+
+    /**
+     * Returns the virtualPort allowedAddressPairs.
+     *
+     * @return virtualPort allowedAddressPairs
+     */
+    Collection<AllowedAddressPair> allowedAddressPairs();
+
+    /**
+     * Returns set of IP addresses for the port, include the IP addresses and subnet
+     * identity.
+     *
+     * @return FixedIps Set of fixedIp
+     */
+    Set<FixedIp> fixedIps();
+
+    /**
+     * Returns the virtualPort bindinghostId.
+     *
+     * @return virtualPort bindinghostId
+     */
+    BindingHostId bindingHostId();
+
+    /**
+     * Returns the virtualPort bindingVnicType.
+     *
+     * @return virtualPort bindingVnicType
+     */
+    String bindingVnicType();
+
+    /**
+     * Returns the virtualPort bindingVifType.
+     *
+     * @return virtualPort bindingVifType
+     */
+    String bindingVifType();
+
+    /**
+     * Returns the virtualPort bindingvifDetail.
+     *
+     * @return virtualPort bindingvifDetail
+     */
+    String bindingVifDetails();
+
+    /**
+     * Returns the security groups.
+     *
+     * @return port security groups
+     */
+    Iterable<SecurityGroup> securityGroups();
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/VirtualPortId.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/VirtualPortId.java
similarity index 97%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/VirtualPortId.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/VirtualPortId.java
index d21e60a..0969ce1 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/VirtualPortId.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/VirtualPortId.java
@@ -1,70 +1,70 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Objects;
-
-/**
- * Immutable representation of a virtual port identifier.
- */
-public final class VirtualPortId {
-    private final String portId;
-    // Public construction is prohibited
-    private VirtualPortId(String virtualPortId) {
-        checkNotNull(virtualPortId, "VirtualPortId cannot be null");
-        this.portId = virtualPortId;
-    }
-
-    public String portId() {
-        return portId;
-    }
-
-    /**
-     * Creates a virtualPort id using the supplied portId.
-     *
-     * @param portId virtualport identifier
-     * @return VirtualPortId
-     */
-    public static VirtualPortId portId(String portId) {
-        return new VirtualPortId(portId);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(portId);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj instanceof VirtualPortId) {
-            final VirtualPortId that = (VirtualPortId) obj;
-            return this.getClass() == that.getClass()
-                    && Objects.equals(this.portId, that.portId);
-        }
-        return false;
-    }
-
-    @Override
-    public String toString() {
-        return portId;
-    }
-
-}
+/*
+ * 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.vtnrsc;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Objects;
+
+/**
+ * Immutable representation of a virtual port identifier.
+ */
+public final class VirtualPortId {
+    private final String portId;
+    // Public construction is prohibited
+    private VirtualPortId(String virtualPortId) {
+        checkNotNull(virtualPortId, "VirtualPortId cannot be null");
+        this.portId = virtualPortId;
+    }
+
+    public String portId() {
+        return portId;
+    }
+
+    /**
+     * Creates a virtualPort id using the supplied portId.
+     *
+     * @param portId virtualport identifier
+     * @return VirtualPortId
+     */
+    public static VirtualPortId portId(String portId) {
+        return new VirtualPortId(portId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(portId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof VirtualPortId) {
+            final VirtualPortId that = (VirtualPortId) obj;
+            return this.getClass() == that.getClass()
+                    && Objects.equals(this.portId, that.portId);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return portId;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/SubnetService.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/SubnetService.java
similarity index 93%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/SubnetService.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/SubnetService.java
index 9ef0229..71ea9ba 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/SubnetService.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/SubnetService.java
@@ -1,72 +1,72 @@
-/*
- * 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.app.vtnrsc.subnet;
-
-import org.onosproject.app.vtnrsc.Subnet;
-import org.onosproject.app.vtnrsc.SubnetId;
-
-
-/**
- * Service for interacting with the inventory of subnets.
- */
-public interface SubnetService {
-    /**
-     * Returns the subnet with the specified identifier.
-     *
-     * @param subnetId subnet identifier
-     * @return true or false
-     */
-    boolean exists(SubnetId subnetId);
-    /**
-     * Returns a collection of the currently known subnets.
-     *
-     * @return iterable collection of subnets
-     */
-    Iterable<Subnet> getSubnets();
-
-    /**
-     * Returns the subnet with the specified identifier.
-     *
-     * @param subnetId subnet identifier
-     * @return subnet or null if one with the given identifier is not known
-     */
-    Subnet getSubnet(SubnetId subnetId);
-    /**
-     * Creates new subnets.
-     *
-     * @param subnets the iterable collection of subnets
-     * @return true  if the identifier subnet has been created right
-     */
-    boolean createSubnets(Iterable<Subnet> subnets);
-
-    /**
-     * Updates existing subnets.
-     *
-     * @param subnets the iterable collection of subnets
-     * @return true if all subnets were updated successfully
-     */
-    boolean updateSubnets(Iterable<Subnet> subnets);
-
-    /**
-     * Administratively removes the specified subnets from the store.
-     *
-     * @param subnetIds the iterable collection of  subnets identifier
-     * @return true if remove identifier subnets successfully
-     */
-    boolean removeSubnets(Iterable<SubnetId> subnetIds);
-
-
-}
+/*
+ * 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.vtnrsc.subnet;
+
+import org.onosproject.vtnrsc.Subnet;
+import org.onosproject.vtnrsc.SubnetId;
+
+
+/**
+ * Service for interacting with the inventory of subnets.
+ */
+public interface SubnetService {
+    /**
+     * Returns the subnet with the specified identifier.
+     *
+     * @param subnetId subnet identifier
+     * @return true or false
+     */
+    boolean exists(SubnetId subnetId);
+    /**
+     * Returns a collection of the currently known subnets.
+     *
+     * @return iterable collection of subnets
+     */
+    Iterable<Subnet> getSubnets();
+
+    /**
+     * Returns the subnet with the specified identifier.
+     *
+     * @param subnetId subnet identifier
+     * @return subnet or null if one with the given identifier is not known
+     */
+    Subnet getSubnet(SubnetId subnetId);
+    /**
+     * Creates new subnets.
+     *
+     * @param subnets the iterable collection of subnets
+     * @return true  if the identifier subnet has been created right
+     */
+    boolean createSubnets(Iterable<Subnet> subnets);
+
+    /**
+     * Updates existing subnets.
+     *
+     * @param subnets the iterable collection of subnets
+     * @return true if all subnets were updated successfully
+     */
+    boolean updateSubnets(Iterable<Subnet> subnets);
+
+    /**
+     * Administratively removes the specified subnets from the store.
+     *
+     * @param subnetIds the iterable collection of  subnets identifier
+     * @return true if remove identifier subnets successfully
+     */
+    boolean removeSubnets(Iterable<SubnetId> subnetIds);
+
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/impl/SubnetManager.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/impl/SubnetManager.java
similarity index 81%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/impl/SubnetManager.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/impl/SubnetManager.java
index 5214691..c5ccf60 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/impl/SubnetManager.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/subnet/impl/SubnetManager.java
@@ -1,154 +1,143 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc.subnet.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Collections;
-
-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.util.KryoNamespace;
-import org.onosproject.app.vtnrsc.Subnet;
-import org.onosproject.app.vtnrsc.SubnetId;
-import org.onosproject.app.vtnrsc.subnet.SubnetService;
-import org.onosproject.app.vtnrsc.tenantnetwork.TenantNetworkService;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.MultiValuedTimestamp;
-import org.onosproject.store.service.StorageService;
-import org.onosproject.store.service.WallClockTimestamp;
-import org.slf4j.Logger;
-
-/**
- * Provides implementation of the Subnet service.
- */
-@Component(immediate = true)
-@Service
-public class SubnetManager implements SubnetService {
-
-    private static final String SUBNET_ID_NULL = "Subnet ID cannot be null";
-    private static final String SUBNET_NOT_NULL = "Subnet cannot be null";
-
-    private final Logger log = getLogger(getClass());
-
-    private EventuallyConsistentMap<SubnetId, Subnet> subnetStore;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected StorageService storageService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected TenantNetworkService tenantNetworkService;
-
-    @Activate
-    public void activate() {
-        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
-                .register(MultiValuedTimestamp.class);
-        subnetStore = storageService
-                .<SubnetId, Subnet>eventuallyConsistentMapBuilder()
-                .withName("all_subnet").withSerializer(serializer)
-                .withTimestampProvider((k, v) -> new WallClockTimestamp())
-                .build();
-
-        log.info("SubnetManager  started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        subnetStore.destroy();
-        log.info("SubnetManager stopped");
-    }
-
-    @Override
-    public Iterable<Subnet> getSubnets() {
-        return Collections.unmodifiableCollection(subnetStore.values());
-    }
-
-    @Override
-    public Subnet getSubnet(SubnetId subnetId) {
-        checkNotNull(subnetId, SUBNET_ID_NULL);
-        return subnetStore.get(subnetId);
-    }
-
-    @Override
-    public boolean exists(SubnetId subnetId) {
-        checkNotNull(subnetId, SUBNET_ID_NULL);
-        return subnetStore.containsKey(subnetId);
-    }
-
-    @Override
-    public boolean createSubnets(Iterable<Subnet> subnets) {
-        checkNotNull(subnets, SUBNET_NOT_NULL);
-        for (Subnet subnet : subnets) {
-            if (!tenantNetworkService.exists(subnet.networkId())) {
-                log.debug("The network identifier that the subnet {} belong to is not exist",
-                          subnet.networkId().toString(), subnet.id().toString());
-                return false;
-            }
-            subnetStore.put(subnet.id(), subnet);
-            if (!subnetStore.containsKey(subnet.id())) {
-                log.debug("The identified subnet whose identifier is {}  create failed",
-                          subnet.id().toString());
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean updateSubnets(Iterable<Subnet> subnets) {
-        checkNotNull(subnets, SUBNET_NOT_NULL);
-        if (subnets != null) {
-            for (Subnet subnet : subnets) {
-                if (!subnetStore.containsKey(subnet.id())) {
-                    log.debug("The subnet is not exist whose identifier is {}",
-                              subnet.id().toString());
-                    return false;
-                }
-
-                subnetStore.put(subnet.id(), subnet);
-
-                if (!subnet.equals(subnetStore.get(subnet.id()))) {
-                    log.debug("The subnet is updated failed whose identifier is {}",
-                              subnet.id().toString());
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean removeSubnets(Iterable<SubnetId> subnetIds) {
-        checkNotNull(subnetIds, SUBNET_ID_NULL);
-        if (subnetIds != null) {
-            for (SubnetId subnetId : subnetIds) {
-                subnetStore.remove(subnetId);
-                if (subnetStore.containsKey(subnetId)) {
-                    log.debug("The subnet created is failed whose identifier is {}",
-                              subnetId.toString());
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-}
+/*
+ * 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.vtnrsc.subnet.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+
+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.onosproject.store.service.StorageService;
+import org.onosproject.vtnrsc.Subnet;
+import org.onosproject.vtnrsc.SubnetId;
+import org.onosproject.vtnrsc.subnet.SubnetService;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.slf4j.Logger;
+
+/**
+ * Provides implementation of the Subnet service.
+ */
+@Component(immediate = true)
+@Service
+public class SubnetManager implements SubnetService {
+
+    private static final String SUBNET_ID_NULL = "Subnet ID cannot be null";
+    private static final String SUBNET_NOT_NULL = "Subnet cannot be null";
+
+    private final Logger log = getLogger(getClass());
+
+    protected ConcurrentHashMap<SubnetId, Subnet> subnetStore =
+            new ConcurrentHashMap<>();
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TenantNetworkService tenantNetworkService;
+
+    @Activate
+    public void activate() {
+        log.info("SubnetManager started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        subnetStore.clear();
+        log.info("SubnetManager stopped");
+    }
+
+    @Override
+    public Iterable<Subnet> getSubnets() {
+        return Collections.unmodifiableCollection(subnetStore.values());
+    }
+
+    @Override
+    public Subnet getSubnet(SubnetId subnetId) {
+        checkNotNull(subnetId, SUBNET_ID_NULL);
+        return subnetStore.get(subnetId);
+    }
+
+    @Override
+    public boolean exists(SubnetId subnetId) {
+        checkNotNull(subnetId, SUBNET_ID_NULL);
+        return subnetStore.containsKey(subnetId);
+    }
+
+    @Override
+    public boolean createSubnets(Iterable<Subnet> subnets) {
+        checkNotNull(subnets, SUBNET_NOT_NULL);
+        for (Subnet subnet : subnets) {
+            if (!tenantNetworkService.exists(subnet.networkId())) {
+                log.debug("The network identifier that the subnet {} belong to is not exist",
+                          subnet.networkId().toString(), subnet.id().toString());
+                return false;
+            }
+            subnetStore.put(subnet.id(), subnet);
+            if (!subnetStore.containsKey(subnet.id())) {
+                log.debug("The identified subnet whose identifier is {}  create failed",
+                          subnet.id().toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updateSubnets(Iterable<Subnet> subnets) {
+        checkNotNull(subnets, SUBNET_NOT_NULL);
+        if (subnets != null) {
+            for (Subnet subnet : subnets) {
+                if (!subnetStore.containsKey(subnet.id())) {
+                    log.debug("The subnet is not exist whose identifier is {}",
+                              subnet.id().toString());
+                    return false;
+                }
+
+                subnetStore.put(subnet.id(), subnet);
+
+                if (!subnet.equals(subnetStore.get(subnet.id()))) {
+                    log.debug("The subnet is updated failed whose identifier is {}",
+                              subnet.id().toString());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removeSubnets(Iterable<SubnetId> subnetIds) {
+        checkNotNull(subnetIds, SUBNET_ID_NULL);
+        if (subnetIds != null) {
+            for (SubnetId subnetId : subnetIds) {
+                subnetStore.remove(subnetId);
+                if (subnetStore.containsKey(subnetId)) {
+                    log.debug("The subnet created is failed whose identifier is {}",
+                              subnetId.toString());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/TenantNetworkService.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkService.java
similarity index 85%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/TenantNetworkService.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkService.java
index cf20e70..56e8bce 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/TenantNetworkService.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tenantnetwork/TenantNetworkService.java
@@ -1,80 +1,80 @@
-/*
- * 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.app.vtnrsc.tenantnetwork;
-
-import org.onosproject.app.vtnrsc.TenantNetwork;
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-
-/**
- * Service for interacting with the inventory of tenantNetwork.
- */
-public interface TenantNetworkService {
-
-    /**
-     * Returns if the tenantNetwork is existed.
-     *
-     * @param networkId tenantNetwork identifier
-     * @return true or false if one with the given identifier exists.
-     */
-    boolean exists(TenantNetworkId networkId);
-
-    /**
-     * Returns the number of tenantNetwork known to the system.
-     *
-     * @return number of tenantNetwork.
-     */
-    int getNetworkCount();
-
-    /**
-     * Returns an iterable collection of the currently known tenantNetwork.
-     *
-     * @return collection of tenantNetwork.
-     */
-    Iterable<TenantNetwork> getNetworks();
-
-    /**
-     * Returns the tenantNetwork with the identifier.
-     *
-     * @param networkId TenantNetwork identifier
-     * @return TenantNetwork or null if one with the given identifier is not
-     *         known.
-     */
-    TenantNetwork getNetwork(TenantNetworkId networkId);
-
-    /**
-     * Creates tenantNetworks by networks.
-     *
-     * @param networks the collection of tenantNetworks
-     * @return true if all given identifiers created successfully.
-     */
-    boolean createNetworks(Iterable<TenantNetwork> networks);
-
-    /**
-     * Updates tenantNetworks by tenantNetworks.
-     *
-     * @param networks the collection of tenantNetworks
-     * @return true if all given identifiers updated successfully.
-     */
-    boolean updateNetworks(Iterable<TenantNetwork> networks);
-
-    /**
-     * Deletes tenantNetwork by tenantNetworkIds.
-     *
-     * @param networksId the collection of tenantNetworkIds
-     * @return true if the specified tenantNetwork deleted successfully.
-     */
-    boolean removeNetworks(Iterable<TenantNetworkId> networksId);
-}
+/*
+ * 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.vtnrsc.tenantnetwork;
+
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+
+/**
+ * Service for interacting with the inventory of tenantNetwork.
+ */
+public interface TenantNetworkService {
+
+    /**
+     * Returns if the tenantNetwork is existed.
+     *
+     * @param networkId tenantNetwork identifier
+     * @return true or false if one with the given identifier exists.
+     */
+    boolean exists(TenantNetworkId networkId);
+
+    /**
+     * Returns the number of tenantNetwork known to the system.
+     *
+     * @return number of tenantNetwork.
+     */
+    int getNetworkCount();
+
+    /**
+     * Returns an iterable collection of the currently known tenantNetwork.
+     *
+     * @return collection of tenantNetwork.
+     */
+    Iterable<TenantNetwork> getNetworks();
+
+    /**
+     * Returns the tenantNetwork with the identifier.
+     *
+     * @param networkId TenantNetwork identifier
+     * @return TenantNetwork or null if one with the given identifier is not
+     *         known.
+     */
+    TenantNetwork getNetwork(TenantNetworkId networkId);
+
+    /**
+     * Creates tenantNetworks by networks.
+     *
+     * @param networks the collection of tenantNetworks
+     * @return true if all given identifiers created successfully.
+     */
+    boolean createNetworks(Iterable<TenantNetwork> networks);
+
+    /**
+     * Updates tenantNetworks by tenantNetworks.
+     *
+     * @param networks the collection of tenantNetworks
+     * @return true if all given identifiers updated successfully.
+     */
+    boolean updateNetworks(Iterable<TenantNetwork> networks);
+
+    /**
+     * Deletes tenantNetwork by tenantNetworkIds.
+     *
+     * @param networksIds the collection of tenantNetworkIds
+     * @return true if the specified tenantNetworks deleted successfully.
+     */
+    boolean removeNetworks(Iterable<TenantNetworkId> networksIds);
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java
similarity index 68%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java
index 711cbcc..29c0059 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tenantnetwork/impl/TenantNetworkManager.java
@@ -1,143 +1,130 @@
-/*
- * 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.app.vtnrsc.tenantnetwork.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.util.Collections;
-
-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.util.KryoNamespace;
-import org.onosproject.app.vtnrsc.TenantNetwork;
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-import org.onosproject.app.vtnrsc.tenantnetwork.TenantNetworkService;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.MultiValuedTimestamp;
-import org.onosproject.store.service.StorageService;
-import org.onosproject.store.service.WallClockTimestamp;
-import org.slf4j.Logger;
-
-/**
- * Provides implementation of the tenantNetworkService.
- */
-@Component(immediate = true)
-@Service
-public class TenantNetworkManager implements TenantNetworkService {
-
-    private static final String NETWORK_ID_NULL = "Network ID cannot be null";
-    private static final String NETWORK_NOT_NULL = "Network ID cannot be null";
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected StorageService storageService;
-    private EventuallyConsistentMap<TenantNetworkId, TenantNetwork> networkIdAsKeyStore;
-    private final Logger log = getLogger(getClass());
-
-    @Activate
-    public void activate() {
-        KryoNamespace.Builder serializer = KryoNamespace.newBuilder()
-                .register(MultiValuedTimestamp.class);
-        networkIdAsKeyStore = storageService
-                .<TenantNetworkId, TenantNetwork>eventuallyConsistentMapBuilder()
-                .withName("all_network").withSerializer(serializer)
-                .withTimestampProvider((k, v) -> new WallClockTimestamp())
-                .build();
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        networkIdAsKeyStore.destroy();
-        log.info("Stopped");
-    }
-
-    @Override
-    public boolean exists(TenantNetworkId networkId) {
-        checkNotNull(networkId, NETWORK_ID_NULL);
-        return networkIdAsKeyStore.containsKey(networkId);
-    }
-
-    @Override
-    public int getNetworkCount() {
-        return networkIdAsKeyStore.size();
-    }
-
-    @Override
-    public Iterable<TenantNetwork> getNetworks() {
-        return Collections.unmodifiableCollection(networkIdAsKeyStore.values());
-    }
-
-    @Override
-    public TenantNetwork getNetwork(TenantNetworkId networkId) {
-        checkNotNull(networkId, NETWORK_ID_NULL);
-        return networkIdAsKeyStore.get(networkId);
-    }
-
-    @Override
-    public boolean createNetworks(Iterable<TenantNetwork> networks) {
-        checkNotNull(networks, NETWORK_NOT_NULL);
-        for (TenantNetwork network : networks) {
-            networkIdAsKeyStore.put(network.id(), network);
-            if (!networkIdAsKeyStore.containsKey(network.id())) {
-                log.debug("the network created failed which identifier was {}", network.id()
-                        .toString());
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean updateNetworks(Iterable<TenantNetwork> networks) {
-        checkNotNull(networks, NETWORK_NOT_NULL);
-        for (TenantNetwork network : networks) {
-            if (!networkIdAsKeyStore.containsKey(network.id())) {
-                log.debug("the tenantNetwork did not exist whose identifier was {} ",
-                          network.id().toString());
-                return false;
-            }
-
-            networkIdAsKeyStore.put(network.id(), network);
-
-            if (network.equals(networkIdAsKeyStore.get(network.id()))) {
-                log.debug("the network updated failed whose identifier was {} ",
-                          network.id().toString());
-                return false;
-            }
-
-        }
-        return true;
-    }
-
-    @Override
-    public boolean removeNetworks(Iterable<TenantNetworkId> networkIds) {
-        checkNotNull(networkIds, NETWORK_NOT_NULL);
-        for (TenantNetworkId networkId : networkIds) {
-            networkIdAsKeyStore.remove(networkId);
-            if (networkIdAsKeyStore.containsKey(networkId)) {
-                log.debug("the network removed failed whose identifier was {}",
-                          networkId.toString());
-                return false;
-            }
-        }
-        return true;
-    }
-}
+/*
+ * 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.vtnrsc.tenantnetwork.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.vtnrsc.TenantNetwork;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.slf4j.Logger;
+
+/**
+ * Provides implementation of the tenantNetworkService.
+ */
+@Component(immediate = true)
+@Service
+public class TenantNetworkManager implements TenantNetworkService {
+
+    private static final String NETWORK_ID_NULL = "Network ID cannot be null";
+    private static final String NETWORK_NOT_NULL = "Network ID cannot be null";
+
+    protected ConcurrentHashMap<TenantNetworkId, TenantNetwork> networkIdAsKeyStore =
+            new ConcurrentHashMap<>();
+
+    private final Logger log = getLogger(getClass());
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        networkIdAsKeyStore.clear();
+        log.info("Stopped");
+    }
+
+    @Override
+    public boolean exists(TenantNetworkId networkId) {
+        checkNotNull(networkId, NETWORK_ID_NULL);
+        return networkIdAsKeyStore.containsKey(networkId);
+    }
+
+    @Override
+    public int getNetworkCount() {
+        return networkIdAsKeyStore.size();
+    }
+
+    @Override
+    public Iterable<TenantNetwork> getNetworks() {
+        return Collections.unmodifiableCollection(networkIdAsKeyStore.values());
+    }
+
+    @Override
+    public TenantNetwork getNetwork(TenantNetworkId networkId) {
+        checkNotNull(networkId, NETWORK_ID_NULL);
+        return networkIdAsKeyStore.get(networkId);
+    }
+
+    @Override
+    public boolean createNetworks(Iterable<TenantNetwork> networks) {
+        checkNotNull(networks, NETWORK_NOT_NULL);
+        for (TenantNetwork network : networks) {
+            networkIdAsKeyStore.put(network.id(), network);
+            if (!networkIdAsKeyStore.containsKey(network.id())) {
+                log.debug("The tenantNetwork is created failed which identifier was {}", network.id()
+                        .toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updateNetworks(Iterable<TenantNetwork> networks) {
+        checkNotNull(networks, NETWORK_NOT_NULL);
+        for (TenantNetwork network : networks) {
+            if (!networkIdAsKeyStore.containsKey(network.id())) {
+                log.debug("The tenantNetwork is not exist whose identifier was {} ",
+                          network.id().toString());
+                return false;
+            }
+
+            networkIdAsKeyStore.put(network.id(), network);
+
+            if (!network.equals(networkIdAsKeyStore.get(network.id()))) {
+                log.debug("The tenantNetwork is updated failed whose identifier was {} ",
+                          network.id().toString());
+                return false;
+            }
+
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removeNetworks(Iterable<TenantNetworkId> networkIds) {
+        checkNotNull(networkIds, NETWORK_NOT_NULL);
+        for (TenantNetworkId networkId : networkIds) {
+            networkIdAsKeyStore.remove(networkId);
+            if (networkIdAsKeyStore.containsKey(networkId)) {
+                log.debug("The tenantNetwork is removed failed whose identifier was {}",
+                          networkId.toString());
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/SubnetService.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java
similarity index 92%
copy from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/SubnetService.java
copy to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java
index 9ef0229..f09caf2 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/subnet/SubnetService.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/tunnel/TunnelConfigService.java
@@ -1,72 +1,72 @@
-/*
- * 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.app.vtnrsc.subnet;
-
-import org.onosproject.app.vtnrsc.Subnet;
-import org.onosproject.app.vtnrsc.SubnetId;
-
-
-/**
- * Service for interacting with the inventory of subnets.
- */
-public interface SubnetService {
-    /**
-     * Returns the subnet with the specified identifier.
-     *
-     * @param subnetId subnet identifier
-     * @return true or false
-     */
-    boolean exists(SubnetId subnetId);
-    /**
-     * Returns a collection of the currently known subnets.
-     *
-     * @return iterable collection of subnets
-     */
-    Iterable<Subnet> getSubnets();
-
-    /**
-     * Returns the subnet with the specified identifier.
-     *
-     * @param subnetId subnet identifier
-     * @return subnet or null if one with the given identifier is not known
-     */
-    Subnet getSubnet(SubnetId subnetId);
-    /**
-     * Creates new subnets.
-     *
-     * @param subnets the iterable collection of subnets
-     * @return true  if the identifier subnet has been created right
-     */
-    boolean createSubnets(Iterable<Subnet> subnets);
-
-    /**
-     * Updates existing subnets.
-     *
-     * @param subnets the iterable collection of subnets
-     * @return true if all subnets were updated successfully
-     */
-    boolean updateSubnets(Iterable<Subnet> subnets);
-
-    /**
-     * Administratively removes the specified subnets from the store.
-     *
-     * @param subnetIds the iterable collection of  subnets identifier
-     * @return true if remove identifier subnets successfully
-     */
-    boolean removeSubnets(Iterable<SubnetId> subnetIds);
-
-
-}
+/*
+ * 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.vtnrsc.tunnel;
+
+import org.onosproject.vtnrsc.Subnet;
+import org.onosproject.vtnrsc.SubnetId;
+
+
+/**
+ * Service for interacting with the inventory of subnets.
+ */
+public interface TunnelConfigService {
+    /**
+     * Returns the subnet with the specified identifier.
+     *
+     * @param subnetId subnet identifier
+     * @return true or false
+     */
+    boolean exists(SubnetId subnetId);
+    /**
+     * Returns a collection of the currently known subnets.
+     *
+     * @return iterable collection of subnets
+     */
+    Iterable<Subnet> getSubnets();
+
+    /**
+     * Returns the subnet with the specified identifier.
+     *
+     * @param subnetId subnet identifier
+     * @return subnet or null if one with the given identifier is not known
+     */
+    Subnet getSubnet(SubnetId subnetId);
+    /**
+     * Creates new subnets.
+     *
+     * @param subnets the iterable collection of subnets
+     * @return true  if the identifier subnet has been created right
+     */
+    boolean createSubnets(Iterable<Subnet> subnets);
+
+    /**
+     * Updates existing subnets.
+     *
+     * @param subnets the iterable collection of subnets
+     * @return true if all subnets were updated successfully
+     */
+    boolean updateSubnets(Iterable<Subnet> subnets);
+
+    /**
+     * Administratively removes the specified subnets from the store.
+     *
+     * @param subnetIds the iterable collection of  subnets identifier
+     * @return true if remove identifier subnets successfully
+     */
+    boolean removeSubnets(Iterable<SubnetId> subnetIds);
+
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/virtualport/VirtualPortService.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
similarity index 91%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/virtualport/VirtualPortService.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
index 71b1560..24ddb9f 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/virtualport/VirtualPortService.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/VirtualPortService.java
@@ -1,99 +1,100 @@
-/*
- * Copyright 2015 Open Porting 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.app.vtnrsc.virtualport;
-
-import java.util.Collection;
-
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-import org.onosproject.app.vtnrsc.TenantId;
-import org.onosproject.app.vtnrsc.VirtualPort;
-import org.onosproject.app.vtnrsc.VirtualPortId;
-import org.onosproject.net.DeviceId;
-
-/**
- * Service for interacting with the inventory of virtualPort.
- */
-public interface VirtualPortService {
-    /**
-     * Returns if the virtualPort is existed.
-     *
-     * @param virtualPortId virtualPort identifier
-     * @return true or false if one with the given identifier is not existed.
-     */
-    boolean exists(VirtualPortId virtualPortId);
-
-    /**
-     * Returns the virtualPort with the identifier.
-     *
-     * @param virtualPortId virtualPort ID
-     * @return VirtualPort or null if one with the given ID is not know.
-     */
-    VirtualPort getPort(VirtualPortId virtualPortId);
-
-    /**
-     * Returns the collection of the currently known virtualPort.
-     */
-    Collection<VirtualPort> getPorts();
-
-    /**
-     * Returns the collection of the virtualPorts associated with the networkId.
-     *
-     * @param networkId  the network identifer
-     * @return collection of virtualPort.
-     */
-    Collection<VirtualPort> getPorts(TenantNetworkId networkId);
-
-    /**
-     * Returns the collection of the virtualPorts associated with the tenantId.
-     *
-     * @param tenantId   the tenant identifier
-     * @return collection of virtualPorts.
-     */
-    Collection<VirtualPort> getPorts(TenantId tenantId);
-
-    /**
-     * Returns the collection of the virtualPorts associated with the deviceId.
-     *
-     * @param deviceId   the device identifier
-     * @return collection of virtualPort.
-     */
-    Collection<VirtualPort> getPorts(DeviceId deviceId);
-
-    /**
-     * Creates virtualPorts by virtualPorts.
-     *
-     * @param virtualPorts the iterable collection of virtualPorts
-     * @return true if all given identifiers created successfully.
-     */
-    boolean createPorts(Iterable<VirtualPort> virtualPorts);
-
-    /**
-     * Updates virtualPorts by virtualPorts.
-     *
-     * @param virtualPorts the iterable  collection of virtualPorts
-     * @return true if all given identifiers updated successfully.
-     */
-    boolean updatePorts(Iterable<VirtualPort> virtualPorts);
-
-    /**
-     * Deletes virtualPortIds by virtualPortIds.
-     *
-     * @param virtualPortIds the iterable collection of virtualPort identifiers
-     * @return true or false if one with the given identifier to delete is
-     *         successfully.
-     */
-    boolean removePorts(Iterable<VirtualPortId> virtualPortIds);
-}
+/*
+ * Copyright 2015 Open Porting 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.vtnrsc.virtualport;
+
+import java.util.Collection;
+
+import org.onosproject.net.DeviceId;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+
+/**
+ * Service for interacting with the inventory of virtualPort.
+ */
+public interface VirtualPortService {
+    /**
+     * Returns if the virtualPort is existed.
+     *
+     * @param virtualPortId virtualPort identifier
+     * @return true or false if one with the given identifier is not existed.
+     */
+    boolean exists(VirtualPortId virtualPortId);
+
+    /**
+     * Returns the virtualPort with the identifier.
+     *
+     * @param virtualPortId virtualPort ID
+     * @return VirtualPort or null if one with the given ID is not know.
+     */
+    VirtualPort getPort(VirtualPortId virtualPortId);
+
+    /**
+     * Returns the collection of the currently known virtualPort.
+     * @return collection of VirtualPort.
+     */
+    Collection<VirtualPort> getPorts();
+
+    /**
+     * Returns the collection of the virtualPorts associated with the networkId.
+     *
+     * @param networkId  the network identifer
+     * @return collection of virtualPort.
+     */
+    Collection<VirtualPort> getPorts(TenantNetworkId networkId);
+
+    /**
+     * Returns the collection of the virtualPorts associated with the tenantId.
+     *
+     * @param tenantId   the tenant identifier
+     * @return collection of virtualPorts.
+     */
+    Collection<VirtualPort> getPorts(TenantId tenantId);
+
+    /**
+     * Returns the collection of the virtualPorts associated with the deviceId.
+     *
+     * @param deviceId   the device identifier
+     * @return collection of virtualPort.
+     */
+    Collection<VirtualPort> getPorts(DeviceId deviceId);
+
+    /**
+     * Creates virtualPorts by virtualPorts.
+     *
+     * @param virtualPorts the iterable collection of virtualPorts
+     * @return true if all given identifiers created successfully.
+     */
+    boolean createPorts(Iterable<VirtualPort> virtualPorts);
+
+    /**
+     * Updates virtualPorts by virtualPorts.
+     *
+     * @param virtualPorts the iterable  collection of virtualPorts
+     * @return true if all given identifiers updated successfully.
+     */
+    boolean updatePorts(Iterable<VirtualPort> virtualPorts);
+
+    /**
+     * Deletes virtualPortIds by virtualPortIds.
+     *
+     * @param virtualPortIds the iterable collection of virtualPort identifiers
+     * @return true or false if one with the given identifier to delete is
+     *         successfully.
+     */
+    boolean removePorts(Iterable<VirtualPortId> virtualPortIds);
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/virtualport/impl/VirtualPortManager.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
similarity index 79%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/virtualport/impl/VirtualPortManager.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
index b6ce13e..8477b32 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/virtualport/impl/VirtualPortManager.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/virtualport/impl/VirtualPortManager.java
@@ -1,192 +1,182 @@
-/*
- * 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.app.vtnrsc.virtualport.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collection;
-import java.util.Collections;
-
-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.util.KryoNamespace;
-import org.onosproject.net.DeviceId;
-import org.onosproject.store.service.EventuallyConsistentMap;
-import org.onosproject.store.service.MultiValuedTimestamp;
-import org.onosproject.store.service.StorageService;
-import org.onosproject.store.service.WallClockTimestamp;
-import org.onosproject.app.vtnrsc.TenantId;
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-import org.onosproject.app.vtnrsc.VirtualPort;
-import org.onosproject.app.vtnrsc.VirtualPortId;
-import org.onosproject.app.vtnrsc.tenantnetwork.TenantNetworkService;
-import org.onosproject.app.vtnrsc.virtualport.VirtualPortService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Provides implementation of the VirtualPort APIs.
- */
-@Component(immediate = true)
-@Service
-public class VirtualPortManager implements VirtualPortService {
-
-    private final Logger log = LoggerFactory.getLogger(getClass());
-
-    private static final String VIRTUALPORT_ID_NULL = "VirtualPort ID cannot be null";
-    private static final String VIRTUALPORT_NOT_NULL = "VirtualPort  cannot be null";
-    private static final String TENANTID_NOT_NULL = "TenantId  cannot be null";
-    private static final String NETWORKID_NOT_NULL = "NetworkId  cannot be null";
-    private static final String DEVICEID_NOT_NULL = "DeviceId  cannot be null";
-
-    private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected StorageService storageService;
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected TenantNetworkService networkService;
-
-    @Activate
-    public void activate() {
-        KryoNamespace.Builder seriallizer = KryoNamespace.newBuilder()
-                .register(MultiValuedTimestamp.class);
-        vPortStore = storageService
-                .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder()
-                .withName("vPortId_vPort").withSerializer(seriallizer)
-                .withTimestampProvider((k, v) -> new WallClockTimestamp())
-                .build();
-        log.info("Started");
-    }
-
-    @Deactivate
-    public void deactivate() {
-        vPortStore.destroy();
-        log.info("Stoppped");
-    }
-
-    @Override
-    public boolean exists(VirtualPortId vPortId) {
-        checkNotNull(vPortId, VIRTUALPORT_ID_NULL);
-        return vPortStore.containsKey(vPortId);
-    }
-
-    @Override
-    public VirtualPort getPort(VirtualPortId vPortId) {
-        checkNotNull(vPortId, VIRTUALPORT_ID_NULL);
-        return vPortStore.get(vPortId);
-    }
-
-    @Override
-    public Collection<VirtualPort> getPorts() {
-        return Collections.unmodifiableCollection(vPortStore.values());
-    }
-
-    @Override
-    public Collection<VirtualPort> getPorts(TenantNetworkId networkId) {
-        checkNotNull(networkId, NETWORKID_NOT_NULL);
-        Collection<VirtualPort> vPortWithNetworkIds = vPortStore.values();
-        for (VirtualPort vPort : vPortWithNetworkIds) {
-            if (!vPort.networkId().equals(networkId)) {
-                vPortWithNetworkIds.remove(vPort);
-            }
-        }
-        return vPortWithNetworkIds;
-    }
-
-    @Override
-    public Collection<VirtualPort> getPorts(TenantId tenantId) {
-        checkNotNull(tenantId, TENANTID_NOT_NULL);
-        Collection<VirtualPort> vPortWithTenantIds = vPortStore.values();
-        for (VirtualPort vPort : vPortWithTenantIds) {
-            if (!vPort.tenantId().equals(tenantId)) {
-                vPortWithTenantIds.remove(vPort);
-            }
-        }
-        return vPortWithTenantIds;
-    }
-
-    @Override
-    public Collection<VirtualPort> getPorts(DeviceId deviceId) {
-        checkNotNull(deviceId, DEVICEID_NOT_NULL);
-        Collection<VirtualPort> vPortWithDeviceIds = vPortStore.values();
-        for (VirtualPort vPort : vPortWithDeviceIds) {
-            if (!vPort.deviceId().equals(deviceId)) {
-                vPortWithDeviceIds.remove(vPort);
-            }
-        }
-        return vPortWithDeviceIds;
-    }
-
-    @Override
-    public boolean createPorts(Iterable<VirtualPort> vPorts) {
-        checkNotNull(vPorts, VIRTUALPORT_NOT_NULL);
-        for (VirtualPort vPort : vPorts) {
-            log.debug("vPortId is  {} ", vPort.portId().toString());
-            vPortStore.put(vPort.portId(), vPort);
-            if (!vPortStore.containsKey(vPort.portId())) {
-                log.debug("the virtualPort created failed whose identifier was {} ",
-                          vPort.portId().toString());
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean updatePorts(Iterable<VirtualPort> vPorts) {
-        checkNotNull(vPorts, VIRTUALPORT_NOT_NULL);
-        if (vPorts != null) {
-            for (VirtualPort vPort : vPorts) {
-                vPortStore.put(vPort.portId(), vPort);
-                if (!vPortStore.containsKey(vPort.portId())) {
-                    log.debug("the virtualPort  did not exist whose identifier was {}",
-                              vPort.portId().toString());
-                    return false;
-                }
-
-                vPortStore.put(vPort.portId(), vPort);
-
-                if (!vPort.equals(vPortStore.get(vPort.portId()))) {
-                    log.debug("the virtualPort updated failed whose  identifier was {}",
-                              vPort.portId().toString());
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public boolean removePorts(Iterable<VirtualPortId> vPortIds) {
-        checkNotNull(vPortIds, VIRTUALPORT_ID_NULL);
-        if (vPortIds != null) {
-            for (VirtualPortId vPortId : vPortIds) {
-                vPortStore.remove(vPortId);
-                if (vPortStore.containsKey(vPortId)) {
-                    log.debug("the virtualPort removed failed whose identifier was {}",
-                              vPortId.toString());
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-}
+/*
+ * 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.vtnrsc.virtualport.impl;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+
+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.onosproject.net.DeviceId;
+import org.onosproject.store.service.StorageService;
+import org.onosproject.vtnrsc.TenantId;
+import org.onosproject.vtnrsc.TenantNetworkId;
+import org.onosproject.vtnrsc.VirtualPort;
+import org.onosproject.vtnrsc.VirtualPortId;
+import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
+import org.onosproject.vtnrsc.virtualport.VirtualPortService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides implementation of the VirtualPort APIs.
+ */
+@Component(immediate = true)
+@Service
+public class VirtualPortManager implements VirtualPortService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final String VIRTUALPORT_ID_NULL = "VirtualPort ID cannot be null";
+    private static final String VIRTUALPORT_NOT_NULL = "VirtualPort  cannot be null";
+    private static final String TENANTID_NOT_NULL = "TenantId  cannot be null";
+    private static final String NETWORKID_NOT_NULL = "NetworkId  cannot be null";
+    private static final String DEVICEID_NOT_NULL = "DeviceId  cannot be null";
+
+    protected ConcurrentHashMap<VirtualPortId, VirtualPort> vPortStore =
+            new ConcurrentHashMap<>();
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected TenantNetworkService networkService;
+
+    @Activate
+    public void activate() {
+        log.info("Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        vPortStore.clear();
+        log.info("Stoppped");
+    }
+
+    @Override
+    public boolean exists(VirtualPortId vPortId) {
+        checkNotNull(vPortId, VIRTUALPORT_ID_NULL);
+        return vPortStore.containsKey(vPortId);
+    }
+
+    @Override
+    public VirtualPort getPort(VirtualPortId vPortId) {
+        checkNotNull(vPortId, VIRTUALPORT_ID_NULL);
+        return vPortStore.get(vPortId);
+    }
+
+    @Override
+    public Collection<VirtualPort> getPorts() {
+        return Collections.unmodifiableCollection(vPortStore.values());
+    }
+
+    @Override
+    public Collection<VirtualPort> getPorts(TenantNetworkId networkId) {
+        checkNotNull(networkId, NETWORKID_NOT_NULL);
+        Collection<VirtualPort> vPortWithNetworkIds = vPortStore.values();
+        for (VirtualPort vPort : vPortWithNetworkIds) {
+            if (!vPort.networkId().equals(networkId)) {
+                vPortWithNetworkIds.remove(vPort);
+            }
+        }
+        return vPortWithNetworkIds;
+    }
+
+    @Override
+    public Collection<VirtualPort> getPorts(TenantId tenantId) {
+        checkNotNull(tenantId, TENANTID_NOT_NULL);
+        Collection<VirtualPort> vPortWithTenantIds = vPortStore.values();
+        for (VirtualPort vPort : vPortWithTenantIds) {
+            if (!vPort.tenantId().equals(tenantId)) {
+                vPortWithTenantIds.remove(vPort);
+            }
+        }
+        return vPortWithTenantIds;
+    }
+
+    @Override
+    public Collection<VirtualPort> getPorts(DeviceId deviceId) {
+        checkNotNull(deviceId, DEVICEID_NOT_NULL);
+        Collection<VirtualPort> vPortWithDeviceIds = vPortStore.values();
+        for (VirtualPort vPort : vPortWithDeviceIds) {
+            if (!vPort.deviceId().equals(deviceId)) {
+                vPortWithDeviceIds.remove(vPort);
+            }
+        }
+        return vPortWithDeviceIds;
+    }
+
+    @Override
+    public boolean createPorts(Iterable<VirtualPort> vPorts) {
+        checkNotNull(vPorts, VIRTUALPORT_NOT_NULL);
+        for (VirtualPort vPort : vPorts) {
+            log.debug("vPortId is  {} ", vPort.portId().toString());
+            vPortStore.put(vPort.portId(), vPort);
+            if (!vPortStore.containsKey(vPort.portId())) {
+                log.debug("The virtualPort is created failed whose identifier is {} ",
+                          vPort.portId().toString());
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean updatePorts(Iterable<VirtualPort> vPorts) {
+        checkNotNull(vPorts, VIRTUALPORT_NOT_NULL);
+        if (vPorts != null) {
+            for (VirtualPort vPort : vPorts) {
+                vPortStore.put(vPort.portId(), vPort);
+                if (!vPortStore.containsKey(vPort.portId())) {
+                    log.debug("The virtualPort is not exist whose identifier is {}",
+                              vPort.portId().toString());
+                    return false;
+                }
+
+                vPortStore.put(vPort.portId(), vPort);
+
+                if (!vPort.equals(vPortStore.get(vPort.portId()))) {
+                    log.debug("The virtualPort is updated failed whose  identifier is {}",
+                              vPort.portId().toString());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removePorts(Iterable<VirtualPortId> vPortIds) {
+        checkNotNull(vPortIds, VIRTUALPORT_ID_NULL);
+        if (vPortIds != null) {
+            for (VirtualPortId vPortId : vPortIds) {
+                vPortStore.remove(vPortId);
+                if (vPortStore.containsKey(vPortId)) {
+                    log.debug("The virtualPort is removed failed whose identifier is {}",
+                              vPortId.toString());
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/AllocationPoolsCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllocationPoolsCodec.java
similarity index 93%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/AllocationPoolsCodec.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllocationPoolsCodec.java
index 8d99c31..4a6c321 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/AllocationPoolsCodec.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllocationPoolsCodec.java
@@ -1,40 +1,40 @@
-/*
- * 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.app.vtnrsc.web;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.app.vtnrsc.AllocationPool;
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * Subnet AllocationPool codec.
- */
-public final class AllocationPoolsCodec extends JsonCodec<AllocationPool> {
-
-    @Override
-    public ObjectNode encode(AllocationPool alocPool, CodecContext context) {
-        checkNotNull(alocPool, "AllocationPools cannot be null");
-        ObjectNode result = context.mapper().createObjectNode()
-                .put("start", alocPool.startIp().toString())
-                .put("end", alocPool.endIp().toString());
-        return result;
-    }
-
-}
+/*
+ * 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.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.AllocationPool;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Subnet AllocationPool codec.
+ */
+public final class AllocationPoolsCodec extends JsonCodec<AllocationPool> {
+
+    @Override
+    public ObjectNode encode(AllocationPool alocPool, CodecContext context) {
+        checkNotNull(alocPool, "AllocationPools cannot be null");
+        ObjectNode result = context.mapper().createObjectNode()
+                .put("start", alocPool.startIp().toString())
+                .put("end", alocPool.endIp().toString());
+        return result;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/AllowedAddressPairCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllowedAddressPairCodec.java
similarity index 93%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/AllowedAddressPairCodec.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllowedAddressPairCodec.java
index bd3c380..6c5cc2e 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/AllowedAddressPairCodec.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/AllowedAddressPairCodec.java
@@ -1,40 +1,40 @@
-/*
- * 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.app.vtnrsc.web;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.app.vtnrsc.AllowedAddressPair;
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * VirtualPort AllowedAddressPair codec.
- */
-public final class AllowedAddressPairCodec extends JsonCodec<AllowedAddressPair> {
-
-    @Override
-    public ObjectNode encode(AllowedAddressPair alocAddPair, CodecContext context) {
-        checkNotNull(alocAddPair, "AllowedAddressPair cannot be null");
-        ObjectNode result = context.mapper().createObjectNode()
-                .put("ip_address", alocAddPair.ip().toString())
-                .put("mac_address", alocAddPair.mac().toString());
-        return result;
-    }
-
-}
+/*
+ * 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.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.AllowedAddressPair;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * VirtualPort AllowedAddressPair codec.
+ */
+public final class AllowedAddressPairCodec extends JsonCodec<AllowedAddressPair> {
+
+    @Override
+    public ObjectNode encode(AllowedAddressPair alocAddPair, CodecContext context) {
+        checkNotNull(alocAddPair, "AllowedAddressPair cannot be null");
+        ObjectNode result = context.mapper().createObjectNode()
+                .put("ip_address", alocAddPair.ip().toString())
+                .put("mac_address", alocAddPair.mac().toString());
+        return result;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/FixedIpCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FixedIpCodec.java
similarity index 93%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/FixedIpCodec.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FixedIpCodec.java
index d2b427a..a69b821 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/FixedIpCodec.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/FixedIpCodec.java
@@ -1,40 +1,40 @@
-/*
- * 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.app.vtnrsc.web;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.app.vtnrsc.FixedIp;
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * VirtualPort FixedIp codec.
- */
-public final class FixedIpCodec extends JsonCodec<FixedIp> {
-
-    @Override
-    public ObjectNode encode(FixedIp fixIp, CodecContext context) {
-        checkNotNull(fixIp, "FixedIp cannot be null");
-        ObjectNode result = context.mapper().createObjectNode()
-                .put("subnet_id", fixIp.subnetId().toString())
-                .put("ip_address", fixIp.ip().toString());
-        return result;
-    }
-
-}
+/*
+ * 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.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.FixedIp;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * VirtualPort FixedIp codec.
+ */
+public final class FixedIpCodec extends JsonCodec<FixedIp> {
+
+    @Override
+    public ObjectNode encode(FixedIp fixIp, CodecContext context) {
+        checkNotNull(fixIp, "FixedIp cannot be null");
+        ObjectNode result = context.mapper().createObjectNode()
+                .put("subnet_id", fixIp.subnetId().toString())
+                .put("ip_address", fixIp.ip().toString());
+        return result;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/HostRoutesCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/HostRoutesCodec.java
similarity index 93%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/HostRoutesCodec.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/HostRoutesCodec.java
index 915726e..ba977a0 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/HostRoutesCodec.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/HostRoutesCodec.java
@@ -1,40 +1,40 @@
-/*
- * 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.app.vtnrsc.web;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-import org.onosproject.app.vtnrsc.HostRoute;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * Subnet HostRoute codec.
- */
-public final class HostRoutesCodec extends JsonCodec<HostRoute> {
-
-    @Override
-    public ObjectNode encode(HostRoute hostRoute, CodecContext context) {
-        checkNotNull(hostRoute, "HostRoute cannot be null");
-        ObjectNode result = context.mapper().createObjectNode()
-                .put("nexthop", hostRoute.nexthop().toString())
-                .put("destination", hostRoute.destination().toString());
-        return result;
-    }
-
-}
+/*
+ * 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.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.HostRoute;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Subnet HostRoute codec.
+ */
+public final class HostRoutesCodec extends JsonCodec<HostRoute> {
+
+    @Override
+    public ObjectNode encode(HostRoute hostRoute, CodecContext context) {
+        checkNotNull(hostRoute, "HostRoute cannot be null");
+        ObjectNode result = context.mapper().createObjectNode()
+                .put("nexthop", hostRoute.nexthop().toString())
+                .put("destination", hostRoute.destination().toString());
+        return result;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/SecurityGroupCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SecurityGroupCodec.java
similarity index 93%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/SecurityGroupCodec.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SecurityGroupCodec.java
index 34e0fe9..83bab6b 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/SecurityGroupCodec.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SecurityGroupCodec.java
@@ -1,39 +1,39 @@
-/*
- * 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.app.vtnrsc.web;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.app.vtnrsc.SecurityGroup;
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * Virtualport SecurityGroup codec.
- */
-public final class SecurityGroupCodec extends JsonCodec<SecurityGroup> {
-
-    @Override
-    public ObjectNode encode(SecurityGroup securGroup, CodecContext context) {
-        checkNotNull(securGroup, "SecurityGroup cannot be null");
-        ObjectNode result = context.mapper().createObjectNode()
-                .put("security_group", securGroup.securityGroup());
-        return result;
-    }
-
-}
+/*
+ * 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.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.SecurityGroup;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Virtualport SecurityGroup codec.
+ */
+public final class SecurityGroupCodec extends JsonCodec<SecurityGroup> {
+
+    @Override
+    public ObjectNode encode(SecurityGroup securGroup, CodecContext context) {
+        checkNotNull(securGroup, "SecurityGroup cannot be null");
+        ObjectNode result = context.mapper().createObjectNode()
+                .put("security_group", securGroup.securityGroup());
+        return result;
+    }
+
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/SubnetCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SubnetCodec.java
similarity index 95%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/SubnetCodec.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SubnetCodec.java
index f14ec8e..8f0fd2e 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/SubnetCodec.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/SubnetCodec.java
@@ -1,49 +1,49 @@
-/*
- * 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.app.vtnrsc.web;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.app.vtnrsc.Subnet;
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * Subnet JSON codec.
- */
-public final class SubnetCodec extends JsonCodec<Subnet> {
-    @Override
-    public ObjectNode encode(Subnet subnet, CodecContext context) {
-        checkNotNull(subnet, "Subnet cannot be null");
-        ObjectNode result = context.mapper().createObjectNode()
-                .put("id", subnet.id().toString())
-                .put("gate_ip", subnet.gatewayIp().toString())
-                .put("network_id", subnet.networkId().toString())
-                .put("name", subnet.subnetName().toString())
-                .put("ip_version", subnet.ipVersion().toString())
-                .put("cidr", subnet.cidr().toString())
-                .put("shared", subnet.shared())
-                .put("enabled_dchp", subnet.dhcpEnabled())
-                .put("tenant_id", subnet.tenantId().toString());
-        result.set("alloction_pools", new AllocationPoolsCodec().encode(subnet
-                .allocationPools(), context));
-        result.set("host_routes",
-                   new HostRoutesCodec().encode(subnet.hostRoutes(), context));
-        return result;
-    }
-}
+/*
+ * 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.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.Subnet;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * Subnet JSON codec.
+ */
+public final class SubnetCodec extends JsonCodec<Subnet> {
+    @Override
+    public ObjectNode encode(Subnet subnet, CodecContext context) {
+        checkNotNull(subnet, "Subnet cannot be null");
+        ObjectNode result = context.mapper().createObjectNode()
+                .put("id", subnet.id().toString())
+                .put("gate_ip", subnet.gatewayIp().toString())
+                .put("network_id", subnet.networkId().toString())
+                .put("name", subnet.subnetName().toString())
+                .put("ip_version", subnet.ipVersion().toString())
+                .put("cidr", subnet.cidr().toString())
+                .put("shared", subnet.shared())
+                .put("enabled_dchp", subnet.dhcpEnabled())
+                .put("tenant_id", subnet.tenantId().toString());
+        result.set("alloction_pools", new AllocationPoolsCodec().encode(subnet
+                .allocationPools(), context));
+        result.set("host_routes",
+                   new HostRoutesCodec().encode(subnet.hostRoutes(), context));
+        return result;
+    }
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/TenantNetworkCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/TenantNetworkCodec.java
similarity index 95%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/TenantNetworkCodec.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/TenantNetworkCodec.java
index bad7a82..07ae9f8 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/TenantNetworkCodec.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/TenantNetworkCodec.java
@@ -1,47 +1,47 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.app.vtnrsc.web;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-import org.onosproject.app.vtnrsc.TenantNetwork;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * TenantNetwork JSON codec.
- */
-public final class TenantNetworkCodec extends JsonCodec<TenantNetwork> {
-
-    @Override
-    public ObjectNode encode(TenantNetwork network, CodecContext context) {
-        checkNotNull(network, "Network cannot be null");
-        ObjectNode result = context.mapper().createObjectNode()
-                .put("id", network.id().toString())
-                .put("name", network.name().toString())
-                .put("admin_state_up", network.adminStateUp())
-                .put("status", "" + network.state())
-                .put("shared", network.shared())
-                .put("tenant_id", network.tenantId().toString())
-                .put("router:external", network.routerExternal())
-                .put("provider:network_type", "" + network.type())
-                .put("provider:physical_network", network.physicalNetwork().toString())
-                .put("provider:segmentation_id", network.segmentationId().toString());
-        return result;
-    }
-}
+/*
+ * 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.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.TenantNetwork;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * TenantNetwork JSON codec.
+ */
+public final class TenantNetworkCodec extends JsonCodec<TenantNetwork> {
+
+    @Override
+    public ObjectNode encode(TenantNetwork network, CodecContext context) {
+        checkNotNull(network, "Network cannot be null");
+        ObjectNode result = context.mapper().createObjectNode()
+                .put("id", network.id().toString())
+                .put("name", network.name().toString())
+                .put("admin_state_up", network.adminStateUp())
+                .put("status", "" + network.state())
+                .put("shared", network.shared())
+                .put("tenant_id", network.tenantId().toString())
+                .put("router:external", network.routerExternal())
+                .put("provider:network_type", "" + network.type())
+                .put("provider:physical_network", network.physicalNetwork().toString())
+                .put("provider:segmentation_id", network.segmentationId().toString());
+        return result;
+    }
+}
diff --git a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/VirtualPortCodec.java b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/VirtualPortCodec.java
similarity index 93%
rename from apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/VirtualPortCodec.java
rename to apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/VirtualPortCodec.java
index 69523d4..aa3c0c7 100644
--- a/apps/vtnrsc/src/main/java/org/onosproject/app/vtnrsc/web/VirtualPortCodec.java
+++ b/apps/vtnrsc/src/main/java/org/onosproject/vtnrsc/web/VirtualPortCodec.java
@@ -1,57 +1,57 @@
-/*
- * 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.app.vtnrsc.web;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-import org.onosproject.app.vtnrsc.VirtualPort;
-
-import com.fasterxml.jackson.databind.node.ObjectNode;
-
-/**
- * VirtualPort JSON codec.
- */
-public final class VirtualPortCodec extends JsonCodec<VirtualPort> {
-    @Override
-    public ObjectNode encode(VirtualPort vPort, CodecContext context) {
-        checkNotNull(vPort, "VPort cannot be null");
-        ObjectNode result = context
-                .mapper()
-                .createObjectNode()
-                .put("id", vPort.portId().toString())
-                .put("network_id", vPort.networkId().toString())
-                .put("admin_state_up", vPort.adminStateUp())
-                .put("name", vPort.name().toString())
-                .put("status", vPort.state().toString())
-                .put("mac_address", vPort.macAddress().toString())
-                .put("tenant_id", vPort.tenantId().toString())
-                .put("device_id", vPort.deviceId().toString())
-                .put("device_owner", vPort.deviceOwner().toString())
-                .put("binding:vnic_type", vPort.bindingVnicType().toString())
-                .put("binding:Vif_type", vPort.bindingVifType().toString())
-                .put("binding:host_id", vPort.bindingHostId().mac().toString())
-                .put("binding:vif_details", vPort.bindingVifDetails().toString());
-        result.set("allowed_address_pairs", new AllowedAddressPairCodec().encode(
-                                                                               vPort.allowedAddressPairs(), context));
-        result.set("fixed_ips", new FixedIpCodec().encode(
-                                                        vPort.fixedIps(), context));
-        result.set("security_groups", new SecurityGroupCodec().encode(
-                                                        vPort.securityGroups(), context));
-        return result;
-    }
-}
+/*
+ * 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.vtnrsc.web;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.onosproject.codec.CodecContext;
+import org.onosproject.codec.JsonCodec;
+import org.onosproject.vtnrsc.VirtualPort;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * VirtualPort JSON codec.
+ */
+public final class VirtualPortCodec extends JsonCodec<VirtualPort> {
+    @Override
+    public ObjectNode encode(VirtualPort vPort, CodecContext context) {
+        checkNotNull(vPort, "VPort cannot be null");
+        ObjectNode result = context
+                .mapper()
+                .createObjectNode()
+                .put("id", vPort.portId().toString())
+                .put("network_id", vPort.networkId().toString())
+                .put("admin_state_up", vPort.adminStateUp())
+                .put("name", vPort.name().toString())
+                .put("status", vPort.state().toString())
+                .put("mac_address", vPort.macAddress().toString())
+                .put("tenant_id", vPort.tenantId().toString())
+                .put("device_id", vPort.deviceId().toString())
+                .put("device_owner", vPort.deviceOwner().toString())
+                .put("binding:vnic_type", vPort.bindingVnicType().toString())
+                .put("binding:Vif_type", vPort.bindingVifType().toString())
+                .put("binding:host_id", vPort.bindingHostId().toString())
+                .put("binding:vif_details", vPort.bindingVifDetails().toString());
+        result.set("allowed_address_pairs", new AllowedAddressPairCodec().encode(
+                                                                               vPort.allowedAddressPairs(), context));
+        result.set("fixed_ips", new FixedIpCodec().encode(
+                                                        vPort.fixedIps(), context));
+        result.set("security_groups", new SecurityGroupCodec().encode(
+                                                        vPort.securityGroups(), context));
+        return result;
+    }
+}
diff --git a/apps/vtnweb/features.xml b/apps/vtnweb/features.xml
deleted file mode 100644
index e20b023..0000000
--- a/apps/vtnweb/features.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<!--
-  ~ 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.
-  -->
-<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}">
-    <repository>mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features</repository>
-    <feature name="onos-app-vtnweb" version="@FEATURE-VERSION"
-		description="ONOS app vtnweb components">
-		<feature>onos-app-vtnrsc</feature>
-		<bundle>mvn:org.onosproject/vtnweb/@ONOS-VERSION
-		</bundle>
-	</feature>
-</features>
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 aa73d26..779777f 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,319 +1,361 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.vtnweb.resources;
-
-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.app.vtnrsc.AllocationPool;
-import org.onosproject.app.vtnrsc.DefaultAllocationPool;
-import org.onosproject.app.vtnrsc.DefaultHostRoute;
-import org.onosproject.app.vtnrsc.DefaultSubnet;
-import org.onosproject.app.vtnrsc.HostRoute;
-import org.onosproject.app.vtnrsc.Subnet;
-import org.onosproject.app.vtnrsc.Subnet.Mode;
-import org.onosproject.app.vtnrsc.SubnetId;
-import org.onosproject.app.vtnrsc.TenantId;
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-import org.onosproject.app.vtnrsc.subnet.SubnetService;
-import org.onosproject.app.vtnrsc.web.SubnetCodec;
-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;
-
-@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<SubnetId>();
-            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<SubnetId, Subnet>();
-        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,
-                                              hostRoutesIt, ipV6AddressMode,
-                                              ipV6RaMode, 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);
-        Map<SubnetId, Subnet> subMap = new HashMap<SubnetId, Subnet>();
-        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());
-        Version ipVersion = Version.valueOf(subnetNodes.get("ip_version")
-                .asText());
-        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 = Mode.valueOf(subnetNodes
-                .get("ipv6_address_mode").asText());
-        Mode ipV6RaMode = Mode
-                .valueOf(subnetNodes.get("ipv6_ra_mode").asText());
-        Subnet subnet = new DefaultSubnet(id, subnetName, networkId, tenantId,
-                                          ipVersion, cidr, gatewayIp,
-                                          dhcpEnabled, shared, hostRoutesIt,
-                                          ipV6AddressMode, ipV6RaMode,
-                                          allocationPoolsIt);
-        subMap.put(id, subnet);
-        return Collections.unmodifiableCollection(subMap.values());
-    }
-
-    /**
-     * 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.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;
+
+@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<SubnetId>();
+            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<SubnetId, Subnet>();
+        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,
+                                              hostRoutesIt, ipV6AddressMode,
+                                              ipV6RaMode, 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);
+        Map<SubnetId, Subnet> subMap = new HashMap<SubnetId, Subnet>();
+        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:
+            ipVersion = null;
+        }
+
+        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, hostRoutesIt,
+                                          ipV6AddressMode, ipV6RaMode,
+                                          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 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;
+    }
+}
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 6d7d9f4..b851a0f 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,399 +1,407 @@
-/*
- * 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.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.net.HostId;
-import org.onosproject.rest.AbstractWebResource;
-import org.onosproject.app.vtnrsc.AllowedAddressPair;
-import org.onosproject.app.vtnrsc.DefaultVirtualPort;
-import org.onosproject.app.vtnrsc.FixedIp;
-import org.onosproject.app.vtnrsc.SecurityGroup;
-import org.onosproject.app.vtnrsc.SubnetId;
-import org.onosproject.app.vtnrsc.TenantId;
-import org.onosproject.app.vtnrsc.TenantNetworkId;
-import org.onosproject.app.vtnrsc.VirtualPort;
-import org.onosproject.app.vtnrsc.VirtualPortId;
-import org.onosproject.app.vtnrsc.VirtualPort.State;
-import org.onosproject.app.vtnrsc.virtualport.VirtualPortService;
-import org.onosproject.app.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;
-
-/**
- * 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("ports", 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<VirtualPortId>();
-        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<VirtualPortId, VirtualPort>();
-        Map<String, String> strMap = new HashMap<String, String>();
-        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());
-            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 fixedIpNode = vPortnode.get("fixed_ips");
-            FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
-            HostId bindingHostId = HostId.hostId(MacAddress.valueOf(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.putIfAbsent("name", name);
-            strMap.putIfAbsent("deviceOwner", deviceOwner);
-            strMap.putIfAbsent("bindingVnicType", bindingVnicType);
-            strMap.putIfAbsent("bindingVifType", bindingVifType);
-            strMap.putIfAbsent("bindingVifDetails", bindingVifDetails);
-            VirtualPort vPort = new DefaultVirtualPort(id, networkId,
-                                                       adminStateUp, strMap,
-                                                       isState(state),
-                                                       macAddress, tenantId,
-                                                       deviceId, fixedIp,
-                                                       bindingHostId,
-                                                       allowedAddressPairs,
-                                                       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<VirtualPortId, VirtualPort>();
-        Map<String, String> strMap = new HashMap<String, String>();
-        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 fixedIpNode = vPortNodes.get("fixed_ips");
-        FixedIp fixedIp = jsonNodeToFixedIps(fixedIpNode);
-        HostId bindingHostId = HostId.hostId(MacAddress.valueOf(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.putIfAbsent("name", name);
-        strMap.putIfAbsent("deviceOwner", deviceOwner);
-        strMap.putIfAbsent("bindingVnicType", bindingVnicType);
-        strMap.putIfAbsent("bindingVifType", bindingVifType);
-        strMap.putIfAbsent("bindingVifDetails", bindingVifDetails);
-        VirtualPort vPort = new DefaultVirtualPort(id, networkId, adminStateUp,
-                                                   strMap, isState(state),
-                                                   macAddress, tenantId,
-                                                   deviceId, fixedIp,
-                                                   bindingHostId,
-                                                   allowedAddressPairs,
-                                                   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
-                    .get("security_group").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.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.VirtualPortId;
+import org.onosproject.vtnrsc.VirtualPort.State;
+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;
+
+/**
+ * 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("ports", 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<VirtualPortId>();
+        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<VirtualPortId, VirtualPort>();
+        Map<String, String> strMap = new HashMap<String, String>();
+        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());
+            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<FixedIp>();
+            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,
+                                                       allowedAddressPairs,
+                                                       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<VirtualPortId, VirtualPort>();
+        Map<String, String> strMap = new HashMap<String, String>();
+        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<FixedIp>();
+        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,
+                                                   allowedAddressPairs,
+                                                   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;
+    }
+}
