diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java
deleted file mode 100644
index 6021e3d..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-
-import net.floodlightcontroller.util.MACAddress;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.data.Status;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Put;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class HostResource extends org.restlet.resource.ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(HostResource.class);
-    
-    public class HostDefinition {
-        String port = null; // Logical port name
-        String guid = null; // Network ID
-        String mac = null; // MAC Address
-        String attachment = null; // Attachment name
-    }
-    
-    protected void jsonToHostDefinition(String json, HostDefinition host) throws IOException {
-        MappingJsonFactory f = new MappingJsonFactory();
-        JsonParser jp;
-        
-        try {
-            jp = f.createJsonParser(json);
-        } catch (JsonParseException e) {
-            throw new IOException(e);
-        }
-        
-        jp.nextToken();
-        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw new IOException("Expected START_OBJECT");
-        }
-        
-        while (jp.nextToken() != JsonToken.END_OBJECT) {
-            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
-                throw new IOException("Expected FIELD_NAME");
-            }
-            
-            String n = jp.getCurrentName();
-            jp.nextToken();
-            if (jp.getText().equals("")) 
-                continue;
-            else if (n.equals("attachment")) {
-                while (jp.nextToken() != JsonToken.END_OBJECT) {
-                    String field = jp.getCurrentName();
-                    if (field.equals("id")) {
-                        host.attachment = jp.getText();
-                    } else if (field.equals("mac")) {
-                        host.mac = jp.getText();
-                    }
-                }
-            }
-        }
-        
-        jp.close();
-    }
-    
-    @Put
-    public String addHost(String postData) {
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        HostDefinition host = new HostDefinition();
-        host.port = (String) getRequestAttributes().get("port");
-        host.guid = (String) getRequestAttributes().get("network");
-        try {
-            jsonToHostDefinition(postData, host);
-        } catch (IOException e) {
-            log.error("Could not parse JSON {}", e.getMessage());
-        }
-        vns.addHost(MACAddress.valueOf(host.mac), host.guid, host.port);
-        setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-    }
-    
-    
-    @Delete
-    public String deleteHost() {
-        String port = (String) getRequestAttributes().get("port");
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        vns.deleteHost(null, port);
-        setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java b/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java
deleted file mode 100644
index 4304a33..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.util.Collection;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.util.MACAddress;
-
-public interface IVirtualNetworkService extends IFloodlightService {
-    /**
-     * Creates a new virtual network. This can also be called
-     * to modify a virtual network. To update a network you specify the GUID
-     * and the fields you want to update.
-     * @param network The network name. Must be unique.
-     * @param guid The ID of the network. Must be unique.
-     * @param gateway The IP address of the network gateway, null if none.
-     */
-    public void createNetwork(String guid, String network, Integer gateway);
-    
-    /**
-     * Deletes a virtual network.
-     * @param guid The ID (not name) of virtual network to delete.
-     */
-    public void deleteNetwork(String guid);
-    
-    /**
-     * Adds a host to a virtual network. If a mapping already exists the
-     * new one will override the old mapping.
-     * @param mac The MAC address of the host to add.
-     * @param network The network to add the host to.
-     * @param port The logical port name to attach the host to. Must be unique.
-     */
-    public void addHost(MACAddress mac, String network, String port); 
-    
-    /**
-     * Deletes a host from a virtual network. Either the MAC or Port must
-     * be specified.
-     * @param mac The MAC address to delete.
-     * @param port The logical port the host is attached to.
-     */
-    public void deleteHost(MACAddress mac, String port);
-    
-    /**
-     * Return list of all virtual networks.
-     * @return Collection <VirtualNetwork>
-     */
-    public Collection <VirtualNetwork> listNetworks();
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
deleted file mode 100644
index 2efe52a..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.Collection;
-
-import net.floodlightcontroller.packet.IPv4;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.data.Status;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Get;
-import org.restlet.resource.Post;
-import org.restlet.resource.Put;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetworkResource extends ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(NetworkResource.class);
-    
-    public class NetworkDefinition {
-        public String name = null;
-        public String guid = null;
-        public String gateway = null;
-    }
-    
-    protected void jsonToNetworkDefinition(String json, NetworkDefinition network) throws IOException {
-        MappingJsonFactory f = new MappingJsonFactory();
-        JsonParser jp;
-        
-        try {
-            jp = f.createJsonParser(json);
-        } catch (JsonParseException e) {
-            throw new IOException(e);
-        }
-        
-        jp.nextToken();
-        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw new IOException("Expected START_OBJECT");
-        }
-        
-        while (jp.nextToken() != JsonToken.END_OBJECT) {
-            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
-                throw new IOException("Expected FIELD_NAME");
-            }
-            
-            String n = jp.getCurrentName();
-            jp.nextToken();
-            if (jp.getText().equals("")) 
-                continue;
-            else if (n.equals("network")) {
-                while (jp.nextToken() != JsonToken.END_OBJECT) {
-                    String field = jp.getCurrentName();
-                    if (field.equals("name")) {
-                        network.name = jp.getText();
-                    } else if (field.equals("gateway")) {
-                    	String gw = jp.getText();
-                    	if ((gw != null) && (!gw.equals("null")))
-                    		network.gateway = gw;
-                    } else if (field.equals("id")) {
-                    	network.guid = jp.getText();
-                    } else {
-                        log.warn("Unrecognized field {} in " +
-                        		"parsing network definition", 
-                        		jp.getText());
-                    }
-                }
-            }
-        }
-        
-        jp.close();
-    }
-    
-    @Get("json")
-    public Collection <VirtualNetwork> retrieve() {
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        
-        return vns.listNetworks();               
-    }
-    
-    @Put
-    @Post
-    public String createNetwork(String postData) {        
-        NetworkDefinition network = new NetworkDefinition();
-        try {
-            jsonToNetworkDefinition(postData, network);
-        } catch (IOException e) {
-            log.error("Could not parse JSON {}", e.getMessage());
-        }
-        
-        // We try to get the ID from the URI only if it's not
-        // in the POST data 
-        if (network.guid == null) {
-	        String guid = (String) getRequestAttributes().get("network");
-	        if ((guid != null) && (!guid.equals("null")))
-	        	network.guid = guid;
-        }
-        
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        
-        Integer gw = null;
-        if (network.gateway != null) {
-            try {
-                gw = IPv4.toIPv4Address(network.gateway);
-            } catch (IllegalArgumentException e) {
-                log.warn("Could not parse gateway {} as IP for network {}, setting as null",
-                         network.gateway, network.name);
-                network.gateway = null;
-            }
-        }
-        vns.createNetwork(network.guid, network.name, gw);
-        setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-    }
-    
-    @Delete
-    public String deleteNetwork() {
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        String guid = (String) getRequestAttributes().get("network");
-        vns.deleteNetwork(guid);
-        setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
deleted file mode 100644
index a184a95..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.Post;
-import org.restlet.resource.Put;
-import org.restlet.resource.ServerResource;
-
-public class NoOp extends ServerResource {
-	/**
-	 * Does nothing and returns 200 OK with a status message
-	 * @return status: ok
-	 */
-	@Get
-	@Put
-	@Post
-	public String noOp(String postdata) {
-		setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-	}
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java
deleted file mode 100644
index f5dfb21..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-
-import net.floodlightcontroller.util.MACAddress;
-
-/**
- * Data structure for storing and outputing information of a virtual network created
- * by VirtualNetworkFilter
- * 
- * @author KC Wang
- */
-
-@JsonSerialize(using=VirtualNetworkSerializer.class)
-public class VirtualNetwork{
-    protected String name; // network name
-    protected String guid; // network id
-    protected String gateway; // network gateway
-    protected Collection<MACAddress> hosts; // array of hosts explicitly added to this network
-
-    /**
-     * Constructor requires network name and id
-     * @param name: network name
-     * @param guid: network id 
-     */
-    public VirtualNetwork(String name, String guid) {
-        this.name = name;
-        this.guid = guid;
-        this.gateway = null;
-        this.hosts = new ArrayList<MACAddress>();
-        return;        
-    }
-
-    /**
-     * Sets network name
-     * @param gateway: IP address as String
-     */
-    public void setName(String name){
-        this.name = name;
-        return;                
-    }
-    
-    /**
-     * Sets network gateway IP address
-     * @param gateway: IP address as String
-     */
-    public void setGateway(String gateway){
-        this.gateway = gateway;
-        return;                
-    }
-    
-    /**
-     * Adds a host to this network record
-     * @param host: MAC address as MACAddress
-     */
-    public void addHost(MACAddress host){
-        this.hosts.add(host);
-        return;        
-    }
-    
-    /**
-     * Removes a host from this network record
-     * @param host: MAC address as MACAddress
-     * @return boolean: true: removed, false: host not found
-     */
-    public boolean removeHost(MACAddress host){
-        Iterator<MACAddress> iter = this.hosts.iterator();
-        while(iter.hasNext()){
-            MACAddress element = iter.next();
-            if(element.equals(host) ){
-                //assuming MAC address for host is unique
-                iter.remove();
-                return true;
-            }                
-        }
-        return false;
-    }
-    
-    /**
-     * Removes all hosts from this network record
-     */
-    public void clearHosts(){
-        this.hosts.clear();
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
deleted file mode 100644
index 012dfb6..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
+++ /dev/null
@@ -1,521 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceListener;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.packet.DHCP;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.ForwardingBase;
-import net.floodlightcontroller.util.MACAddress;
-
-/**
- * A simple Layer 2 (MAC based) network virtualization module. This module allows
- * you to create simple L2 networks (host + gateway) and will drop traffic if
- * they are not on the same virtual network.
- * 
- * LIMITATIONS
- * - This module does not allow overlapping of IPs or MACs
- * - You can only have 1 gateway per virtual network (can be shared)
- * - There is filtering of multicast/broadcast traffic
- * - All DHCP traffic will be allowed, regardless of unicast/broadcast
- * 
- * @author alexreimers
- */
-public class VirtualNetworkFilter 
-    implements IFloodlightModule, IVirtualNetworkService, IOFMessageListener, IDeviceListener {
-    protected static Logger log = LoggerFactory.getLogger(VirtualNetworkFilter.class);
-    
-    private final short APP_ID = 20;
-    
-    // Our dependencies
-    IFloodlightProviderService floodlightProvider;
-    IRestApiService restApi;
-    IDeviceService deviceService;
-    
-    // Our internal state
-    protected Map<String, VirtualNetwork> vNetsByGuid; // List of all created virtual networks 
-    protected Map<String, String> nameToGuid; // Logical name -> Network ID
-    protected Map<String, Integer> guidToGateway; // Network ID -> Gateway IP
-    protected Map<Integer, Set<String>> gatewayToGuid; // Gateway IP -> Network ID
-    protected Map<MACAddress, Integer> macToGateway; // Gateway MAC -> Gateway IP
-    protected Map<MACAddress, String> macToGuid; // Host MAC -> Network ID
-    protected Map<String, MACAddress> portToMac; // Host MAC -> logical port name
-    
-    /**
-     * Adds a gateway to a virtual network.
-     * @param guid The ID (not name) of the network.
-     * @param ip The IP addresses of the gateway.
-     */
-    protected void addGateway(String guid, Integer ip) {
-        if (ip.intValue() != 0) {
-        	if (log.isDebugEnabled())
-        		log.debug("Adding {} as gateway for GUID {}",
-        				IPv4.fromIPv4Address(ip), guid);
-        	
-            guidToGateway.put(guid, ip);
-            if (vNetsByGuid.get(guid) != null)
-                vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(ip));
-            if (gatewayToGuid.containsKey(ip)) {
-                Set<String> gSet = gatewayToGuid.get(ip);
-                gSet.add(guid);
-            } else {
-                Set<String> gSet = Collections.synchronizedSet(new HashSet<String>());
-                gSet.add(guid);
-                gatewayToGuid.put(ip, gSet);
-            }
-        }
-    }
-    
-    /**
-     * Deletes a gateway for a virtual network.
-     * @param guid The ID (not name) of the network to delete
-     * the gateway for.
-     */
-    protected void deleteGateway(String guid) {
-        Integer gwIp = guidToGateway.remove(guid);
-        if (gwIp == null) return;
-        Set<String> gSet = gatewayToGuid.get(gwIp);
-        gSet.remove(guid);
-        if(vNetsByGuid.get(guid)!=null)
-            vNetsByGuid.get(guid).setGateway(null);
-    }
-    
-    // IVirtualNetworkService
-    
-    @Override
-    public void createNetwork(String guid, String network, Integer gateway) {
-        if (log.isDebugEnabled()) {
-            String gw = null;
-            try {
-                gw = IPv4.fromIPv4Address(gateway);
-            } catch (Exception e) {
-                // fail silently
-            }
-            log.debug("Creating network {} with ID {} and gateway {}", 
-                      new Object[] {network, guid, gw});
-        }
-        
-        if (!nameToGuid.isEmpty()) {
-            // We have to iterate all the networks to handle name/gateway changes
-            for (Entry<String, String> entry : nameToGuid.entrySet()) {
-                if (entry.getValue().equals(guid)) {
-                    nameToGuid.remove(entry.getKey());
-                    break;
-                }
-            }
-        }
-        nameToGuid.put(network, guid);
-        if (vNetsByGuid.containsKey(guid))
-            vNetsByGuid.get(guid).setName(network); //network already exists, just updating name
-        else
-            vNetsByGuid.put(guid, new VirtualNetwork(network, guid)); //new network
-        
-        // If they don't specify a new gateway the old one will be preserved
-        if ((gateway != null) && (gateway != 0)) {
-            addGateway(guid, gateway);
-            if(vNetsByGuid.get(guid)!=null)
-                vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(gateway));
-        }
-    }
-
-    @Override
-    public void deleteNetwork(String guid) {
-        String name = null;
-        if (nameToGuid.isEmpty()) {
-            log.warn("Could not delete network with ID {}, network doesn't exist",
-                     guid);
-            return;
-        }
-        for (Entry<String, String> entry : nameToGuid.entrySet()) {
-            if (entry.getValue().equals(guid)) {
-                name = entry.getKey();
-                break;
-            }
-            log.warn("Could not delete network with ID {}, network doesn't exist",
-                     guid);
-        }
-        
-        if (log.isDebugEnabled()) 
-            log.debug("Deleting network with name {} ID {}", name, guid);
-        
-        nameToGuid.remove(name);
-        deleteGateway(guid);
-        if(vNetsByGuid.get(guid)!=null){
-            vNetsByGuid.get(guid).clearHosts();
-            vNetsByGuid.remove(guid);
-        }
-        Collection<MACAddress> deleteList = new ArrayList<MACAddress>();
-        for (MACAddress host : macToGuid.keySet()) {
-            if (macToGuid.get(host).equals(guid)) {
-                deleteList.add(host);
-            }
-        }
-        for (MACAddress mac : deleteList) {
-            if (log.isDebugEnabled()) {
-                log.debug("Removing host {} from network {}", 
-                          HexString.toHexString(mac.toBytes()), guid);
-            }
-            macToGuid.remove(mac);
-            for (Entry<String, MACAddress> entry : portToMac.entrySet()) {
-                if (entry.getValue().equals(mac)) {
-                    portToMac.remove(entry.getKey());
-                    break;
-                }
-            }
-        }
-    }
-
-    @Override
-    public void addHost(MACAddress mac, String guid, String port) {
-        if (guid != null) {
-            if (log.isDebugEnabled()) {
-                log.debug("Adding {} to network ID {} on port {}",
-                          new Object[] {mac, guid, port});
-            }
-            // We ignore old mappings
-            macToGuid.put(mac, guid);
-            portToMac.put(port, mac);
-            if(vNetsByGuid.get(guid)!=null)
-                vNetsByGuid.get(guid).addHost(new MACAddress(mac.toBytes()));
-        } else {
-            log.warn("Could not add MAC {} to network ID {} on port {}, the network does not exist",
-                     new Object[] {mac, guid, port});
-        }
-    }
-
-    @Override
-    public void deleteHost(MACAddress mac, String port) {
-        if (log.isDebugEnabled()) {
-            log.debug("Removing host {} from port {}", mac, port);
-        }
-        if (mac == null && port == null) return;
-        if (port != null) {
-            MACAddress host = portToMac.remove(port);
-            if(vNetsByGuid.get(macToGuid.get(host)) != null)
-                vNetsByGuid.get(macToGuid.get(host)).removeHost(host);
-            macToGuid.remove(host);
-        } else if (mac != null) {
-            if (!portToMac.isEmpty()) {
-                for (Entry<String, MACAddress> entry : portToMac.entrySet()) {
-                    if (entry.getValue().equals(mac)) {
-                        if(vNetsByGuid.get(macToGuid.get(entry.getValue())) != null)
-                            vNetsByGuid.get(macToGuid.get(entry.getValue())).removeHost(entry.getValue());
-                        portToMac.remove(entry.getKey());
-                        macToGuid.remove(entry.getValue());
-                        return;
-                    }
-                }
-            }
-        }
-    }
-    
-    // IFloodlightModule
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IVirtualNetworkService.class);
-        return l;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService>
-            getServiceImpls() {
-        Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m = 
-                new HashMap<Class<? extends IFloodlightService>,
-                    IFloodlightService>();
-        m.put(IVirtualNetworkService.class, this);
-        return m;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        l.add(IRestApiService.class);
-        l.add(IDeviceService.class);
-        return l;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context)  
-                                 throws FloodlightModuleException {
-        floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
-        restApi = context.getServiceImpl(IRestApiService.class);
-        deviceService = context.getServiceImpl(IDeviceService.class);
-        
-        vNetsByGuid = new ConcurrentHashMap<String, VirtualNetwork>();
-        nameToGuid = new ConcurrentHashMap<String, String>();
-        guidToGateway = new ConcurrentHashMap<String, Integer>();
-        gatewayToGuid = new ConcurrentHashMap<Integer, Set<String>>();
-        macToGuid = new ConcurrentHashMap<MACAddress, String>();
-        portToMac = new ConcurrentHashMap<String, MACAddress>();
-        macToGateway = new ConcurrentHashMap<MACAddress, Integer>();
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-        restApi.addRestletRoutable(new VirtualNetworkWebRoutable());
-        deviceService.addListener(this);
-    }
-
-    // IOFMessageListener
-    
-    @Override
-    public String getName() {
-        return "virtualizer";
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        // Link discovery should go before us so we don't block LLDPs
-        return (type.equals(OFType.PACKET_IN) && 
-        		(name.equals("linkdiscovery") || (name.equals("devicemanager"))));
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        // We need to go before forwarding
-        return (type.equals(OFType.PACKET_IN) && name.equals("forwarding"));
-    }
-
-    @Override
-    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-        switch (msg.getType()) {
-            case PACKET_IN:
-                return processPacketIn(sw, (OFPacketIn)msg, cntx);
-            default:
-            	break;
-        }
-        log.warn("Received unexpected message {}", msg);
-        return Command.CONTINUE;
-    }
-    
-    /**
-     * Checks whether the frame is destined to or from a gateway.
-     * @param frame The ethernet frame to check.
-     * @return True if it is to/from a gateway, false otherwise.
-     */
-    protected boolean isDefaultGateway(Ethernet frame) {
-    	if (macToGateway.containsKey(frame.getSourceMAC()))
-    		return true;
-    	
-    	Integer gwIp = macToGateway.get(frame.getDestinationMAC());
-    	if (gwIp != null) {
-    		MACAddress host = frame.getSourceMAC();
-    		String srcNet = macToGuid.get(host);
-    		if (srcNet != null) {
-	    		Integer gwIpSrcNet = guidToGateway.get(srcNet);
-	    		if ((gwIpSrcNet != null) && (gwIp.equals(gwIpSrcNet)))
-	    			return true;
-    		}
-    	}
-
-    	return false;
-    }
-    
-    /**
-     * Checks to see if two MAC Addresses are on the same network.
-     * @param m1 The first MAC.
-     * @param m2 The second MAC.
-     * @return True if they are on the same virtual network,
-     * 		   false otherwise.
-     */
-    protected boolean oneSameNetwork(MACAddress m1, MACAddress m2) {
-        String net1 = macToGuid.get(m1);
-        String net2 = macToGuid.get(m2);
-        if (net1 == null) return false;
-        if (net2 == null) return false;
-        return net1.equals(net2);
-    }
-    
-    /**
-     * Checks to see if an Ethernet frame is a DHCP packet.
-     * @param frame The Ethernet frame.
-     * @return True if it is a DHCP frame, false otherwise.
-     */
-    protected boolean isDhcpPacket(Ethernet frame) {
-        IPacket payload = frame.getPayload(); // IP
-        if (payload == null) return false;
-        IPacket p2 = payload.getPayload(); // TCP or UDP
-        if (p2 == null) return false;
-        IPacket p3 = p2.getPayload(); // Application
-        if ((p3 != null) && (p3 instanceof DHCP)) return true;
-        return false;
-    }
-    
-    /**
-     * Processes an OFPacketIn message and decides if the OFPacketIn should be dropped
-     * or the processing should continue.
-     * @param sw The switch the PacketIn came from.
-     * @param msg The OFPacketIn message from the switch.
-     * @param cntx The FloodlightContext for this message.
-     * @return Command.CONTINUE if processing should be continued, Command.STOP otherwise.
-     */
-    protected Command processPacketIn(IOFSwitch sw, OFPacketIn msg, FloodlightContext cntx) {
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, 
-                                              IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-        Command ret = Command.STOP;
-        String srcNetwork = macToGuid.get(eth.getSourceMAC());
-        // If the host is on an unknown network we deny it.
-        // We make exceptions for ARP and DHCP.
-        if (eth.isBroadcast() || eth.isMulticast() || isDefaultGateway(eth) || isDhcpPacket(eth)) {
-        	ret = Command.CONTINUE;
-        } else if (srcNetwork == null) {
-            log.trace("Blocking traffic from host {} because it is not attached to any network.",
-                      HexString.toHexString(eth.getSourceMACAddress()));
-            ret = Command.STOP;
-        } else if (oneSameNetwork(eth.getSourceMAC(), eth.getDestinationMAC())) {
-            // if they are on the same network continue
-            ret = Command.CONTINUE;
-        }
-        
-        if (log.isTraceEnabled())
-        	log.trace("Results for flow between {} and {} is {}",
-        			new Object[] {eth.getSourceMAC(), eth.getDestinationMAC(), ret});
-        /*
-         * TODO - figure out how to still detect gateways while using
-         * drop mods 
-        if (ret == Command.STOP) {
-            if (!(eth.getPayload() instanceof ARP))
-            	doDropFlow(sw, msg, cntx);
-        }
-        */
-        return ret;
-    }
-    
-    /**
-     * Writes a FlowMod to a switch that inserts a drop flow.
-     * @param sw The switch to write the FlowMod to.
-     * @param pi The corresponding OFPacketIn. Used to create the OFMatch structure.
-     * @param cntx The FloodlightContext that gets passed to the switch.
-     */
-    protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
-        if (log.isTraceEnabled()) {
-            log.trace("doDropFlow pi={} srcSwitch={}",
-                    new Object[] { pi, sw });
-        }
-
-        if (sw == null) {
-            log.warn("Switch is null, not installing drop flowmod for PacketIn {}", pi);
-            return;
-        }
-
-        // Create flow-mod based on packet-in and src-switch
-        OFFlowMod fm = 
-            (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
-        OFMatch match = new OFMatch();
-        match.loadFromPacket(pi.getPacketData(), pi.getInPort());
-        List<OFAction> actions = new ArrayList<OFAction>(); // no actions = drop
-        long cookie = AppCookie.makeCookie(APP_ID, 0);
-        fm.setCookie(cookie)
-        .setIdleTimeout(ForwardingBase.FLOWMOD_DEFAULT_IDLE_TIMEOUT)
-        .setHardTimeout(ForwardingBase.FLOWMOD_DEFAULT_HARD_TIMEOUT)
-        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-        .setMatch(match)
-        .setActions(actions)
-        .setLengthU(OFFlowMod.MINIMUM_LENGTH);
-        fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
-        try {
-            if (log.isTraceEnabled()) {
-                log.trace("write drop flow-mod srcSwitch={} match={} " + 
-                          "pi={} flow-mod={}",
-                          new Object[] {sw, match, pi, fm});
-            }
-            sw.write(fm, cntx);
-        } catch (IOException e) {
-            log.error("Failure writing drop flow mod", e);
-        }
-        return;
-    }
-
-    // IDeviceListener
-    
-	@Override
-	public void deviceAdded(IDevice device) {
-		if (device.getIPv4Addresses() == null) return;
-		for (Integer i : device.getIPv4Addresses()) {
-			if (gatewayToGuid.containsKey(i)) {
-				MACAddress mac = MACAddress.valueOf(device.getMACAddress());
-				if (log.isDebugEnabled())
-					log.debug("Adding MAC {} with IP {} a a gateway",
-							HexString.toHexString(mac.toBytes()),
-							IPv4.fromIPv4Address(i));
-				macToGateway.put(mac, i);
-			}
-		}
-	}
-
-	@Override
-	public void deviceRemoved(IDevice device) {
-		// if device is a gateway remove
-		MACAddress mac = MACAddress.valueOf(device.getMACAddress());
-		if (macToGateway.containsKey(mac)) {
-			if (log.isDebugEnabled())
-				log.debug("Removing MAC {} as a gateway",
-						HexString.toHexString(mac.toBytes()));
-			macToGateway.remove(mac);
-		}
-	}
-
-	@Override
-	public void deviceIPV4AddrChanged(IDevice device) {
-		// add or remove entry as gateway
-		deviceAdded(device);
-	}
-
-	@Override
-	public void deviceMoved(IDevice device) {
-		// ignore
-	}
-	
-	@Override
-	public void deviceVlanChanged(IDevice device) {
-		// ignore
-	}
-
-    @Override
-    public Collection <VirtualNetwork> listNetworks() {
-        return vNetsByGuid.values();
-        
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java
deleted file mode 100644
index 6902f6c..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.Iterator;
-
-import net.floodlightcontroller.util.MACAddress;
-
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.map.JsonSerializer;
-import org.codehaus.jackson.map.SerializerProvider;
-
-/**
- * Serialize a VirtualNetwork object
- * @author KC Wang
- */
-public class VirtualNetworkSerializer extends JsonSerializer<VirtualNetwork> {
-
-    @Override
-    public void serialize(VirtualNetwork vNet, JsonGenerator jGen,
-            SerializerProvider serializer) throws IOException,
-            JsonProcessingException {
-        jGen.writeStartObject();
-        
-        jGen.writeStringField("name", vNet.name);
-        jGen.writeStringField("guid", vNet.guid);
-        jGen.writeStringField("gateway", vNet.gateway);
-
-        jGen.writeArrayFieldStart("mac");
-        Iterator<MACAddress> hit = vNet.hosts.iterator();
-        while (hit.hasNext())
-            jGen.writeString(hit.next().toString());
-        jGen.writeEndArray();
-        
-        jGen.writeEndObject();
-    }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
deleted file mode 100644
index 61769ec..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-public class VirtualNetworkWebRoutable implements RestletRoutable {
-
-    @Override
-    public Restlet getRestlet(Context context) {
-        Router router = new Router(context);
-        router.attach("/tenants/{tenant}/networks", NetworkResource.class); // GET
-        router.attach("/tenants/{tenant}/networks/{network}", NetworkResource.class); // PUT, DELETE
-        router.attach("/tenants/{tenant}/networks", NetworkResource.class); // POST
-        router.attach("/tenants/{tenant}/networks/{network}/ports/{port}/attachment", HostResource.class);
-        router.attachDefault(NoOp.class);
-        return router;
-    }
-
-    @Override
-    public String basePath() {
-        return "/quantum/v1.0";
-    }
-}
\ No newline at end of file
