diff --git a/build.xml b/build.xml
index 3093f956856f9b2ca13bf9e67fe37d573ee1f609..cdea14c7ef4982b658d8e0ce0fe74198c3154cc5 100644
--- a/build.xml
+++ b/build.xml
@@ -27,10 +27,11 @@
     <property name="build-test" location="${target}/bin-test"/>
     <property name="test-output" location="${target}/test"/>
     <property name="source" location="src/main/java"/>
+	<property name="resources" location="src/main/resources/"/>
     <property name="source-test" location="src/test/java"/>
     <property name="python-src" location="src/main/python"/>
     <property name="docs" location="${target}/docs"/>
-    <property name="main-class" value="net.floodlightcontroller.core.internal.Controller"/>
+    <property name="main-class" value="net.floodlightcontroller.core.Main"/>
     <property name="packetstreamer-gen" location="${target}/gen-java" />
     <property name="packetstreamer-gen-build" location="${target}/gen-java-bin"/>
     <property name="packetstreamer-thrift-jar" location="${target}/lib/packetstreamer-thrift.jar"/>
@@ -102,6 +103,7 @@
 
     <target name="compile-tests" depends="compile-test"/>
     <target name="compile-test" depends="compile">
+    	<fileset dir="${resources}"/>
         <javac includeAntRuntime="false" debug="true" 
 	       srcdir="${source-test}"
 	       classpath="${build}"
@@ -159,6 +161,7 @@
                 <attribute name="Class-Path" value="."/>
             </manifest>
             <fileset dir="${build}"/>
+        	<fileset dir="${resources}"/>
             <fileset dir="${python-src}">
                 <include name="**/*.py"/>
             </fileset>
@@ -174,6 +177,7 @@
                 <attribute name="Class-Path" value="."/>
             </manifest>
             <fileset dir="${build-test}"/>
+        	<fileset dir="${resources}"/>
             <zipgroupfileset dir="lib">
                 <patternset refid="lib-test"/>
             </zipgroupfileset>
diff --git a/setup-eclipse.sh b/setup-eclipse.sh
index d7e9a06fb126b99ffe22cc670926f34d28a3bc9d..bdf87200a57a97a7d618303da714356cc86d53a6 100755
--- a/setup-eclipse.sh
+++ b/setup-eclipse.sh
@@ -31,6 +31,7 @@ cat >$d/.classpath <<EOF
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
 	<classpathentry kind="src" path="src/main/java" output="target/bin"/>
+	<classpathentry kind="src" path="src/main/resources"/>
         <classpathentry kind="src" path="src/test/java" output="target/bin-test"/>
 EOF
 (
diff --git a/src/main/java/net/floodlightcontroller/core/CoreModule.java b/src/main/java/net/floodlightcontroller/core/CoreModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..be4ebc25e644ca7794cc2930c5125e961f363f82
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/CoreModule.java
@@ -0,0 +1,77 @@
+package net.floodlightcontroller.core;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import net.floodlightcontroller.core.internal.Controller;
+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.counter.CounterStore;
+import net.floodlightcontroller.counter.ICounterStoreService;
+import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.storage.IStorageSourceService;
+
+public class CoreModule implements IFloodlightModule {
+    Controller controller;
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> services =
+                new ArrayList<Class<? extends IFloodlightService>>(2);
+        services.add(IFloodlightProviderService.class);
+        services.add(ICounterStoreService.class);
+        return services;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>,
+               IFloodlightService> getServiceImpls() {
+        controller = new Controller();
+        ICounterStoreService counterStore = new CounterStore();
+        controller.setCounterStore(counterStore);
+        
+        Map<Class<? extends IFloodlightService>,
+            IFloodlightService> m = 
+                new HashMap<Class<? extends IFloodlightService>,
+                            IFloodlightService>();
+        m.put(IFloodlightProviderService.class, controller);
+        m.put(ICounterStoreService.class, counterStore);
+        return m;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        Collection<Class<? extends IFloodlightService>> dependencies =
+            new ArrayList<Class<? extends IFloodlightService>>(4);
+        dependencies.add(IStorageSourceService.class);
+        dependencies.add(IOFMessageFilterManagerService.class);
+        dependencies.add(IPktInProcessingTimeService.class);
+        dependencies.add(IRestApiService.class);
+        return dependencies;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+       controller.setStorageSourceService(
+           context.getServiceImpl(IStorageSourceService.class));
+       controller.setPktInProcessingService(
+           context.getServiceImpl(IPktInProcessingTimeService.class));
+       controller.setCounterStore(
+           context.getServiceImpl(ICounterStoreService.class));
+       controller.setMessageFilterManagerService(
+           context.getServiceImpl(IOFMessageFilterManagerService.class));         
+       controller.setRestApiService(
+           context.getServiceImpl(IRestApiService.class));
+       controller.init();
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        controller.startupComponents();
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
similarity index 91%
rename from src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java
rename to src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
index 6cf9515b9fcfa2c350f5bae11b392dce34a81d93..c2d5cf433297e7b89af5b95370a70862e2825012 100644
--- a/src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
@@ -21,6 +21,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
 
+import net.floodlightcontroller.core.internal.CmdLineSettings;
+import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.packet.Ethernet;
 
 import org.openflow.protocol.OFMessage;
@@ -33,7 +35,7 @@ import org.openflow.protocol.factory.BasicFactory;
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public interface IFloodlightProvider {
+public interface IFloodlightProviderService extends IFloodlightService {
 
     /**
      * A value stored in the floodlight context containing a parsed packet
@@ -133,4 +135,14 @@ public interface IFloodlightProvider {
      * @return an OpenFlow message factory
      */
     public BasicFactory getOFMessageFactory();
+
+    /**
+     * Run the main I/O loop of the Controller.
+     */
+    public void run();
+    
+    /**
+     * Sets the command line settings
+     */
+    public void setCmdLineOptions(CmdLineSettings settings);
 }
diff --git a/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java b/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java
new file mode 100644
index 0000000000000000000000000000000000000000..58de92ca04d6b7ad519b2fa85b6d2e06d56ecf47
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java
@@ -0,0 +1,12 @@
+package net.floodlightcontroller.core;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+import org.openflow.protocol.OFMessage;
+
+public interface IOFMessageFilterManagerService extends IFloodlightService {
+
+    public String getDataAsString(IOFSwitch sw, OFMessage msg, 
+                                  FloodlightContext cntx);
+
+}
diff --git a/src/main/java/net/floodlightcontroller/core/Main.java b/src/main/java/net/floodlightcontroller/core/Main.java
new file mode 100644
index 0000000000000000000000000000000000000000..10ad853e1a18adf0e695c65afabe4ea3965dbb95
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/Main.java
@@ -0,0 +1,45 @@
+package net.floodlightcontroller.core;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+
+import net.floodlightcontroller.core.internal.CmdLineSettings;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.FloodlightModuleLoader;
+import net.floodlightcontroller.core.module.IFloodlightModuleContext;
+import net.floodlightcontroller.restserver.IRestApiService;
+
+/**
+ * Host for the Floodlight main method
+ * @author alexreimers
+ */
+public class Main {
+
+    /**
+     * Main method to load configuration and modules
+     * @param args
+     * @throws FloodlightModuleException 
+     */
+    public static void main(String[] args) throws FloodlightModuleException {
+        System.setProperty("org.restlet.engine.loggerFacadeClass", 
+                "org.restlet.ext.slf4j.Slf4jLoggerFacade");
+        
+        CmdLineSettings settings = new CmdLineSettings();
+        CmdLineParser parser = new CmdLineParser(settings);
+        try {
+            parser.parseArgument(args);
+        } catch (CmdLineException e) {
+            parser.printUsage(System.out);
+            System.exit(1);
+        }
+        
+        FloodlightModuleLoader fml = new FloodlightModuleLoader();
+        IFloodlightModuleContext moduleContext = fml.loadModulesFromConfig(settings.getModuleFile());
+        IRestApiService restApi = moduleContext.getServiceImpl(IRestApiService.class);
+        restApi.run();
+        IFloodlightProviderService controller =
+                moduleContext.getServiceImpl(IFloodlightProviderService.class);
+        controller.setCmdLineOptions(settings);
+        controller.run();
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
index 316c200bb59bfde85e37a99e7425b2b7c00ec4fd..d787fc702ceca3b08c6d5b22e2b94731632e841b 100644
--- a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
+++ b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
@@ -19,7 +19,9 @@ package net.floodlightcontroller.core;
 
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
+import java.util.Collection;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
@@ -49,10 +51,15 @@ import org.apache.thrift.transport.TTransportException;
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.protocol.TProtocol;
 
+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.packet.Ethernet;
 import net.floodlightcontroller.packetstreamer.thrift.*;
 
-public class OFMessageFilterManager implements IOFMessageListener {
+public class OFMessageFilterManager 
+        implements IOFMessageListener, IFloodlightModule, IOFMessageFilterManagerService {
 
     /**
      * @author Srini
@@ -65,7 +72,7 @@ public class OFMessageFilterManager implements IOFMessageListener {
     protected static TTransport transport = null;
     protected static PacketStreamer.Client packetClient = null;
 
-    protected IFloodlightProvider floodlightProvider = null;
+    protected IFloodlightProviderService floodlightProvider = null;
     // filter List is a key value pair.  Key is the session id, value is the filter rules.
     protected ConcurrentHashMap<String, ConcurrentHashMap<String,String>> filterMap = null;
     protected ConcurrentHashMap<String, Long> filterTimeoutMap = null;
@@ -91,13 +98,6 @@ public class OFMessageFilterManager implements IOFMessageListener {
         FILTER_NOT_DEFINED, FILTER_NO_MATCH, FILTER_MATCH
     }
 
-    public void init (IFloodlightProvider bp) {
-        floodlightProvider = bp;
-        filterMap = new ConcurrentHashMap<String, ConcurrentHashMap<String,String>>();
-        filterTimeoutMap = new ConcurrentHashMap<String, Long>();
-        serverPort = Integer.parseInt(System.getProperty("net.floodlightcontroller.packetstreamer.port", "9090"));
-    }
-
     protected String addFilter(ConcurrentHashMap<String,String> f, long delta) {
 
         // Create unique session ID.  
@@ -200,8 +200,8 @@ public class OFMessageFilterManager implements IOFMessageListener {
         Ethernet eth = null;
 
         if (m.getType() == OFType.PACKET_IN) {
-            eth = IFloodlightProvider.bcStore.get(cntx, 
-                    IFloodlightProvider.CONTEXT_PI_PAYLOAD);
+            eth = IFloodlightProviderService.bcStore.get(cntx, 
+                    IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
         } else if (m.getType() == OFType.PACKET_OUT) {
             eth = new Ethernet();
             OFPacketOut p = (OFPacketOut) m;
@@ -254,30 +254,7 @@ public class OFMessageFilterManager implements IOFMessageListener {
         else 
             return matchedFilters;
     }
-
-
-    protected void startListening() {
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-        floodlightProvider.addOFMessageListener(OFType.PACKET_OUT, this);
-        floodlightProvider.addOFMessageListener(OFType.FLOW_MOD, this);
-    }
-
-    protected void stopListening() {
-        floodlightProvider.removeOFMessageListener(OFType.PACKET_IN, this);
-        floodlightProvider.removeOFMessageListener(OFType.PACKET_OUT, this);
-        floodlightProvider.removeOFMessageListener(OFType.FLOW_MOD, this);
-    }
-
-    public void startUp() {
-        startListening();
-        //connectToPSServer();
-    }
-
-    public void shutDown() {
-        stopListening();
-        disconnectFromPSServer();
-    }
-
+    
     public boolean connectToPSServer() {
         int numRetries = 0;
         if (transport != null && transport.isOpen()) {
@@ -464,6 +441,7 @@ public class OFMessageFilterManager implements IOFMessageListener {
         }
     }
 
+    @Override
     public String getDataAsString(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
 
         Ethernet eth;
@@ -495,8 +473,8 @@ public class OFMessageFilterManager implements IOFMessageListener {
                 // If the conext is not set by floodlight, then ignore.
                 if (cntx != null) {
                 // packet type  icmp, arp, etc.
-                    eth = IFloodlightProvider.bcStore.get(cntx,
-                            IFloodlightProvider.CONTEXT_PI_PAYLOAD);
+                    eth = IFloodlightProviderService.bcStore.get(cntx,
+                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
                     if (eth != null)
                            sb.append(eth.toString());
                 }
@@ -528,8 +506,8 @@ public class OFMessageFilterManager implements IOFMessageListener {
 
                 // If the conext is not set by floodlight, then ignore.
                 if (cntx != null) {
-                    eth = IFloodlightProvider.bcStore.get(cntx,
-                        IFloodlightProvider.CONTEXT_PI_PAYLOAD);
+                    eth = IFloodlightProviderService.bcStore.get(cntx,
+                        IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
                     if (eth != null)
                         sb.append(eth.toString());
                 }
@@ -565,4 +543,53 @@ public class OFMessageFilterManager implements IOFMessageListener {
         return this.getDataAsString(sw, msg, cntx).getBytes();
     }
 
+    // IFloodlightModule methods
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IOFMessageFilterManagerService.class);
+        return l;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+        IFloodlightService> m = 
+            new HashMap<Class<? extends IFloodlightService>,
+                        IFloodlightService>();
+        // We are the class that implements the service
+        m.put(IOFMessageFilterManagerService.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);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context) 
+            throws FloodlightModuleException {
+        this.floodlightProvider = 
+                context.getServiceImpl(IFloodlightProviderService.class);
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // This is our 'constructor'
+        
+        filterMap = new ConcurrentHashMap<String, ConcurrentHashMap<String,String>>();
+        filterTimeoutMap = new ConcurrentHashMap<String, Long>();
+        serverPort = Integer.parseInt(System.getProperty("net.floodlightcontroller.packetstreamer.port", "9090"));
+        
+        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+        floodlightProvider.addOFMessageListener(OFType.PACKET_OUT, this);
+        floodlightProvider.addOFMessageListener(OFType.FLOW_MOD, this);
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/CmdLineSettings.java b/src/main/java/net/floodlightcontroller/core/internal/CmdLineSettings.java
index f4a654fe70e08b4f6f21356de8e6b513af1a2b22..dc81f044ba08c5dae1a5f22e6b984a2247e3457b 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/CmdLineSettings.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/CmdLineSettings.java
@@ -6,14 +6,17 @@ import org.kohsuke.args4j.Option;
  * Expresses the port settings of OpenFlow controller.
  */
 public class CmdLineSettings {
-    private final int DEFAULT_OPENFLOW_PORT = 6633;
-    private final int DEFAULT_REST_PORT = 8080;
+    public static final int DEFAULT_OPENFLOW_PORT = 6633;
+    public static final int DEFAULT_REST_PORT = 8080;
+    public static final String DEFAULT_CONFIG_FILE = "floodlightdefault.properties";
     private final int DEFAULT_WORKER_THREADS = 0;
 
     @Option(name="-ofp", aliases="--openFlowPort",metaVar="PORT", usage="Port number for OpenFlow")
     private int openFlowPort = DEFAULT_OPENFLOW_PORT;
     @Option(name="-rp", aliases="--restPort", metaVar="PORT", usage="Port number for REST API")
     private int restPort = DEFAULT_REST_PORT;
+    @Option(name="-cf", aliases="--configFile", metaVar="FILE", usage="Floodlight configuration file")
+    private String configFile = DEFAULT_CONFIG_FILE;
     @Option(name="-wt", aliases="--workerThreads", metaVar="THREADS", usage="Number of worker threads")
     private int workerThreads = DEFAULT_WORKER_THREADS;
     
@@ -25,6 +28,10 @@ public class CmdLineSettings {
         return restPort;
     }
     
+    public String getModuleFile() {
+    	return configFile;
+    }
+
     public int getWorkerThreads() {
         return workerThreads;
     }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 13afeb3592a111aed976c17e28d8ee4b590c5206..3630ce6070c4221af5136fbadaab7fda1b3dea1c 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -21,11 +21,9 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -46,43 +44,31 @@ import java.util.concurrent.TimeoutException;
 import java.nio.channels.ClosedChannelException;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFController;
+import net.floodlightcontroller.core.IOFMessageFilterManagerService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFMessageListener.Command;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchFilter;
 import net.floodlightcontroller.core.IOFSwitchListener;
-import net.floodlightcontroller.core.OFMessageFilterManager;
 import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState;
 import net.floodlightcontroller.core.util.ListenerDispatcher;
 import net.floodlightcontroller.core.web.CoreWebRoutable;
-import net.floodlightcontroller.core.web.JacksonCustomConverter;
-import net.floodlightcontroller.core.web.RestletRoutable;
 import static net.floodlightcontroller.counter.CounterValue.CounterType;
 import net.floodlightcontroller.counter.CounterStore;
 import net.floodlightcontroller.counter.ICounter;
 import net.floodlightcontroller.counter.CounterStore.NetworkLayer;
-import net.floodlightcontroller.devicemanager.IDeviceManagerAware;
-import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl;
-import net.floodlightcontroller.forwarding.Forwarding;
+import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.jython.Server;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.routing.dijkstra.RoutingImpl;
-import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
-import net.floodlightcontroller.perfmon.PktinProcessingTime;
+import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
+import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.storage.IResultSet;
-import net.floodlightcontroller.storage.IStorageExceptionHandler;
-import net.floodlightcontroller.storage.IStorageSource;
+import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.OperatorPredicate;
 import net.floodlightcontroller.storage.StorageException;
-import net.floodlightcontroller.storage.memory.MemoryStorageSource;
-import net.floodlightcontroller.storage.web.StorageWebRoutable;
-import net.floodlightcontroller.topology.ITopologyAware;
-import net.floodlightcontroller.topology.internal.TopologyImpl;
-import net.floodlightcontroller.topology.web.TopologyWebRouteable;
-
 import org.jboss.netty.bootstrap.ServerBootstrap;
 import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
@@ -100,8 +86,6 @@ import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
 import org.jboss.netty.handler.timeout.IdleStateAwareChannelUpstreamHandler;
 import org.jboss.netty.handler.timeout.IdleStateEvent;
 import org.jboss.netty.handler.timeout.ReadTimeoutException;
-import org.kohsuke.args4j.CmdLineException;
-import org.kohsuke.args4j.CmdLineParser;
 import org.openflow.protocol.OFEchoReply;
 import org.openflow.protocol.OFError;
 import org.openflow.protocol.OFError.OFBadActionCode;
@@ -130,17 +114,6 @@ import org.openflow.protocol.factory.MessageParseException;
 import org.openflow.util.HexString;
 import org.openflow.util.U16;
 import org.openflow.util.U32;
-import org.restlet.Component;
-import org.restlet.Context;
-import org.restlet.Request;
-import org.restlet.Response;
-import org.restlet.Restlet;
-import org.restlet.data.Protocol;
-import org.restlet.data.Reference;
-import org.restlet.routing.Filter;
-import org.restlet.routing.Router;
-import org.restlet.routing.Template;
-import org.restlet.Application;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -149,8 +122,7 @@ import org.slf4j.LoggerFactory;
  * The main controller class.  Handles all setup and network listeners
  */
 public class Controller
-    extends Application
-    implements IFloodlightProvider, IOFController {
+    implements IFloodlightProviderService, IOFController {
     
     protected static Logger log = LoggerFactory.getLogger(Controller.class);
     
@@ -161,27 +133,22 @@ public class Controller
     protected ConcurrentHashMap<Long, IOFSwitch> switches;
     protected Set<IOFSwitchListener> switchListeners;
     protected BlockingQueue<Update> updates;
-    protected CounterStore counterStore;
+    protected ICounterStoreService counterStore;
+    protected IRestApiService restApi;
 
     protected ScheduledExecutorService executor = 
             Executors.newScheduledThreadPool(5);
     
-    protected IStorageSource storageSource;
-    protected TopologyImpl topology;
-    protected DeviceManagerImpl deviceManager;
-    protected RoutingImpl routingEngine;
-    protected Forwarding forwarding;
-    protected OFMessageFilterManager messageFilterManager;
-    protected PktinProcessingTime pktinProcTime;
-    private StaticFlowEntryPusher staticFlowEntryPusher;
-    protected long ptWarningThresholdInNano;
+    protected IStorageSourceService storageSource;
+    protected IOFMessageFilterManagerService messageFilterManager;
+    protected IPktInProcessingTimeService pktinProcTime;
     
-    protected List<RestletRoutable> restlets;
-
-    protected int restPort;
-    protected int openFlowPort;
+    // Configuration options
+    protected int openFlowPort = 6633;
+    protected long ptWarningThresholdInNano;
     protected int workerThreads;
-
+    
+    // Storage table names
     protected static final String CONTROLLER_TABLE_NAME = "controller_controller";
     protected static final String CONTROLLER_ID = "id";
     
@@ -220,24 +187,31 @@ public class Controller
             this.added = added;
         }
     }
-
-    public Controller() {
-        this(new CmdLineSettings());
+    
+    // ***************
+    // Getters/Setters
+    // ***************
+    
+    public void setStorageSourceService(IStorageSourceService storageSource) {
+        this.storageSource = storageSource;
     }
-
-    public Controller(CmdLineSettings settings) {
-        this.messageListeners =
-            new ConcurrentHashMap<OFType, 
-                                  ListenerDispatcher<OFType, 
-                                                     IOFMessageListener>>();
-        this.switchListeners = new CopyOnWriteArraySet<IOFSwitchListener>();
-        this.updates = new LinkedBlockingQueue<Update>();
-        this.restlets = new ArrayList<RestletRoutable>();
-        this.restPort = settings.getRestPort();
-        this.openFlowPort = settings.getOpenFlowPort();
-        this.workerThreads = settings.getWorkerThreads();
+    
+    public void setCounterStore(ICounterStoreService counterStore) {
+        this.counterStore = counterStore;
+    }
+    
+    public void setMessageFilterManagerService(IOFMessageFilterManagerService mfm) {
+        this.messageFilterManager = mfm;
     }
     
+    public void setPktInProcessingService(IPktInProcessingTimeService pits) {
+        this.pktinProcTime = pits;
+    }
+    
+    public void setRestApiService(IRestApiService restApi) {
+        this.restApi = restApi;
+    }
+
     // **********************
     // ChannelUpstreamHandler
     // **********************
@@ -543,20 +517,6 @@ public class Controller
                             processSwitchDescReply();
                         }
                         break;
-                    /*
-                     * "Trivial" server to test raw low-level throughput
-                    case PACKET_IN:
-                        OFPacketIn pi = (OFPacketIn)m;
-    
-                        OFFlowMod fm = 
-                                (OFFlowMod)factory.getMessage(OFType.FLOW_MOD);
-                        OFMatch match = new OFMatch();
-                        match.loadFromPacket(pi.getPacketData(), pi.getInPort());
-                        fm.setBufferId(pi.getBufferId());
-                        fm.setMatch(match);
-                        sw.write(fm, null);
-                        break; 
-                    */
                     case PORT_STATUS:
                         boolean swadded = 
                             state.hsState.equals(HandshakeState.READY);
@@ -690,7 +650,7 @@ public class Controller
             portL3Counter.increment();
             switchL3Counter.increment();
             
-            if (etherType.compareTo(CounterStore.L3ET_IPV4) == 0) {
+            if (etherType.compareTo(ICounterStoreService.L3ET_IPV4) == 0) {
                 IPv4 ipV4 = (IPv4)eth.getPayload();
                 String l4Type = String.format("%02x", ipV4.getProtocol());
                 if (TypeAliases.l4TypeAliasMap != null && 
@@ -780,8 +740,8 @@ public class Controller
                         bc = bContext;
                     }
                     if (eth != null) {
-                        IFloodlightProvider.bcStore.put(bc, 
-                                IFloodlightProvider.CONTEXT_PI_PAYLOAD, 
+                        IFloodlightProviderService.bcStore.put(bc, 
+                                IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
                                 eth);
                     }
                     
@@ -1088,96 +1048,9 @@ public class Controller
         return "localhost";
     }
     
-    // ***********
-    // Application
-    // ***********
-
-    @Override
-    public Restlet createInboundRoot() {
-        Context context = getContext();
-        initRestContext(context);
-        
-        Router baseRouter = new Router(context);
-        baseRouter.setDefaultMatchingMode(Template.MODE_STARTS_WITH);
-        for (RestletRoutable rr : restlets) {
-            baseRouter.attach(rr.basePath(), rr.getRestlet(context));
-        }
-
-        Filter slashFilter = new Filter() {            
-            @Override
-            protected int beforeHandle(Request request, Response response) {
-                Reference ref = request.getResourceRef();
-                String originalPath = ref.getPath();
-                if (originalPath.contains("//"))
-                {
-                    String newPath = originalPath.replaceAll("/+", "/");
-                    ref.setPath(newPath);
-                }
-                return Filter.CONTINUE;
-            }
-
-        };
-        slashFilter.setNext(baseRouter);
-        
-        return slashFilter;
-    }
-    
     // **************
     // Initialization
     // **************
-    
-    /**
-     * Call after init() has run, but before this.run()
-     * @throws IOException
-     */
-    
-    protected void startUp() throws IOException {
-        // Connect to the storage source to update info about this controller
-        // node, and wait indefinitely if the storage source is unavailable;
-        // don't want switches to connect before we have a database
-        while (true) {
-            try {
-                updateControllerInfo();
-                break;
-            }
-            catch (StorageException e) {
-                log.info("Waiting for storage source");
-                try {
-                    Thread.sleep(1000);
-                } catch (InterruptedException e1) {
-                }
-            }
-        }
-        log.info("Connected to storage source");
-        
-        switches = new ConcurrentHashMap<Long, IOFSwitch>();
-        
-        this.factory = new BasicFactory();
-    }
-
-    protected void shutDown() {
-        try {
-            removeControllerInfo();
-        } catch (StorageException e) {
-        }
-        
-        log.info("Shutdown complete");
-    }
-
-    protected void setStorageSource(IStorageSource storageSource) {
-        this.storageSource = storageSource;
-        IStorageExceptionHandler handler = 
-                new TerminationStorageExceptionHandler(this);
-        storageSource.setExceptionHandler(handler);
-        storageSource.createTable(CONTROLLER_TABLE_NAME, null);
-        storageSource.createTable(SWITCH_TABLE_NAME, null);
-        storageSource.createTable(PORT_TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(CONTROLLER_TABLE_NAME,
-                                             CONTROLLER_ID);
-        storageSource.setTablePrimaryKeyName(SWITCH_TABLE_NAME,
-                                             SWITCH_DATAPATH_ID);
-        storageSource.setTablePrimaryKeyName(PORT_TABLE_NAME, PORT_ID);
-    }
 
     protected void updateAllInactiveSwitchInfo() {
         String controllerId = getControllerId();
@@ -1243,17 +1116,6 @@ public class Controller
         storageSource.updateRow(CONTROLLER_TABLE_NAME, controllerInfo);
     }
     
-    protected void removeControllerInfo() {
-        // Update the controller info in the storage source to be inactive
-//        Map<String, Object> controllerInfo = new HashMap<String, Object>();
-//        String id = getControllerId();
-//        controllerInfo.put(CONTROLLER_ID, id);
-//        controllerInfo.put(CONTROLLER_ACTIVE, Boolean.FALSE);
-//        storageSource.updateRow(CONTROLLER_TABLE_NAME, controllerInfo);
-        
-        updateAllInactiveSwitchInfo();
-    }
-    
     protected void updateActiveSwitchInfo(IOFSwitch sw) {
         // Obtain the row info for the switch
         Map<String, Object> switchInfo = new HashMap<String, Object>();
@@ -1346,34 +1208,14 @@ public class Controller
      * Tell controller that we're ready to accept switches loop
      * @throws IOException 
      */
-    protected void run() {
+    public void run() {
         try {            
-            // Start listening for REST requests
-            final Component component = new Component();
-            component.getServers().add(Protocol.HTTP, restPort);
-            component.getDefaultHost().attach(this);
-            
-            component.start();
-
-            // Start listening for switch connections
-            //int threads = 
-            //       Runtime.getRuntime().availableProcessors() * 2 + 1;
-            //int threads = 1;
-            //long maxMem = Runtime.getRuntime().maxMemory() * 1 / 3;
-            //long memPerChannel = 2 * 1024 * 1024;
-
-            final ServerBootstrap bootstrap = createServerBootStrap(workerThreads);
+           final ServerBootstrap bootstrap = createServerBootStrap(workerThreads);
 
             bootstrap.setOption("reuseAddr", true);
             bootstrap.setOption("child.keepAlive", true);
             bootstrap.setOption("child.tcpNoDelay", true);
 
-            //OrderedMemoryAwareThreadPoolExecutor pipelineExecutor =
-            //        new OrderedMemoryAwareThreadPoolExecutor(
-            //                threads, memPerChannel, maxMem,
-            //                1000, TimeUnit.SECONDS,
-            //                Executors.defaultThreadFactory());
-
             ChannelPipelineFactory pfact = 
                     new OpenflowPipelineFactory(this, null);
             bootstrap.setPipelineFactory(pfact);
@@ -1428,170 +1270,87 @@ public class Controller
     }
 
     /**
-     * Initialize all of the controller's components; override me for
-     * new components
-     */
-    protected void init() {
-        topology = new TopologyImpl();
-        deviceManager = new DeviceManagerImpl();
-        counterStore = new CounterStore();
-        pktinProcTime = new PktinProcessingTime();
-        routingEngine = new RoutingImpl();
-        initStorageSource();
-        
-        topology.setFloodlightProvider(this);
-        topology.setStorageSource(storageSource);
-         
-        deviceManager.setFloodlightProvider(this);
-        deviceManager.setStorageSource(storageSource);
-        deviceManager.setTopology(topology);
-        
-        initMessageFilterManager();
-        initStaticFlowPusher();
-        initForwarding();
-        
-        // call this explicitly because it does setup
-        this.setStorageSource(storageSource);        
-        
-        
-        ArrayList<ITopologyAware> topologyAware = new ArrayList<ITopologyAware>();
-        topologyAware.add(deviceManager);
-        topologyAware.add(routingEngine);
-        topology.setTopologyAware(topologyAware);
-        topology.setRoutingEngine(routingEngine);
-
-        HashSet<IDeviceManagerAware> dmAware = 
-            new HashSet<IDeviceManagerAware>();
-        dmAware.add(forwarding);
-        //deviceManager.setDeviceManagerAware(dmAware);
-        
-        restlets.add(new CoreWebRoutable());
-        restlets.add(new StorageWebRoutable());
-        restlets.add(new TopologyWebRouteable());
-        JacksonCustomConverter.replaceConverter();
-        
-        // Processing Time Warning Threshold
-        ptWarningThresholdInNano = Long.parseLong(System.getProperty("net.floodlightcontroller.core.PTWarningThresholdInMilli", "0")) * 1000000;
-        if (ptWarningThresholdInNano > 0) {
-            log.info("Packet processing time threshold for warning set to {} ms.",
-                 ptWarningThresholdInNano/1000000);
-        }
-    }
-    
-    protected void initStorageSource() {
-        MemoryStorageSource memoryStorageSource = new MemoryStorageSource();
-        memoryStorageSource.setCounterStore(counterStore);
-        storageSource = memoryStorageSource;
-    }
-    
-    protected void initMessageFilterManager() {
-        messageFilterManager = new OFMessageFilterManager();
-        messageFilterManager.init(this);
-    }
-    
-    protected void initStaticFlowPusher() {
-        staticFlowEntryPusher = new StaticFlowEntryPusher();
-        staticFlowEntryPusher.setFloodlightProvider(this);
-    }
-    
-    protected void initForwarding() {
-        forwarding = new Forwarding();
-        forwarding.setFloodlightProvider(this);
-        forwarding.setCounterStore(counterStore);
-        forwarding.setDeviceManager(deviceManager);
-        forwarding.setRoutingEngine(routingEngine);
-        forwarding.setTopology(topology);
-    }
-    
-    /**
-     * Initialize the rest context
+     * Initialize internal datastructures
      */
-    protected void initRestContext(Context context) {
-        context.getAttributes().put("floodlightProvider", this);
-        context.getAttributes().put("counterStore", counterStore);
-        context.getAttributes().put("storageSource", storageSource);
-        context.getAttributes().put("deviceManager", deviceManager);
-        context.getAttributes().put("messageFilterManager",
-                                    messageFilterManager);
-        context.getAttributes().put("pktinProcessingTime", pktinProcTime);
-        if (staticFlowEntryPusher != null) {
-            context.getAttributes().put("staticFlowEntryPusher", 
-                                        staticFlowEntryPusher);
-        }
-        context.getAttributes().put("topology", topology);
+    public void init() {
+        // These data structures are initialized here because other
+        // module's startUp() might be called before ours
+        this.messageListeners =
+                new ConcurrentHashMap<OFType, 
+                                      ListenerDispatcher<OFType, 
+                                                         IOFMessageListener>>();
+        this.switchListeners = new CopyOnWriteArraySet<IOFSwitchListener>();
+        this.switches = new ConcurrentHashMap<Long, IOFSwitch>();
+        this.updates = new LinkedBlockingQueue<Update>();
+        this.factory = new BasicFactory();
     }
     
     /**
      * Startup all of the controller's components
      */
-    protected void startupComponents() {
-        // now, do our own init
-        try {
-            log.debug("Doing controller internal setup");
-            this.startUp();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
+    public void startupComponents() {
+        log.debug("Doing controller internal setup");
+        // Create the table names we use
+        storageSource.createTable(CONTROLLER_TABLE_NAME, null);
+        storageSource.createTable(SWITCH_TABLE_NAME, null);
+        storageSource.createTable(PORT_TABLE_NAME, null);
+        storageSource.setTablePrimaryKeyName(CONTROLLER_TABLE_NAME,
+                                             CONTROLLER_ID);
+        storageSource.setTablePrimaryKeyName(SWITCH_TABLE_NAME,
+                                             SWITCH_DATAPATH_ID);
+        storageSource.setTablePrimaryKeyName(PORT_TABLE_NAME, PORT_ID);
         
-        log.debug("Starting topology service");
-        topology.startUp();
-        log.debug("Starting deviceManager service");
-        deviceManager.startUp();
-        // no need to do storageSource.startUp()
-        log.debug("Starting counterStore service");
-        counterStore.startUp();
-        log.debug("Starting routingEngine service");
-        routingEngine.startUp();
-        log.debug("Starting forwarding service");
-        forwarding.startUp(); 
-        log.debug("Starting messageFilter service");
-        messageFilterManager.startUp();
-        log.debug("Starting staticFlowEntryPusher service");
-        staticFlowEntryPusher.startUp();
-        log.debug("Starting DebugServer");
-        this.debugserver_start();
+        while (true) {
+            try {
+                updateControllerInfo();
+                break;
+            }
+            catch (StorageException e) {
+                log.info("Waiting for storage source");
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException e1) {
+                }
+            }
+        }
+        log.info("Connected to storage source");
+                
+        // Processing Time Warning Threshold
+        ptWarningThresholdInNano = Long.parseLong(System.getProperty(
+             "net.floodlightcontroller.core.PTWarningThresholdInMilli", "0")) * 1000000;
+        if (ptWarningThresholdInNano > 0) {
+            log.info("Packet processing time threshold for warning set to {} ms.",
+                 ptWarningThresholdInNano/1000000);
+        }
+       
+        // Add our REST API
+        restApi.addRestletRoutable(new CoreWebRoutable());
     }
     
     /**
      * Start debug server, put global state as local variables for the jython shell
      */
+    // TODO - make this a module
     protected void debugserver_start() {
+        log.debug("Starting DebugServer");
         Map<String, Object> locals = new HashMap<String, Object>();
         locals.put("controller", this);
-        locals.put("deviceManager", this.deviceManager);
-        locals.put("topology", this.topology);
-        locals.put("routingEngine", this.routingEngine);
-        locals.put("forwarding", this.forwarding);
-        locals.put("staticFlowEntryPusher", this.staticFlowEntryPusher);
+        //locals.put("deviceManager", this.deviceManager);
+        //locals.put("topology", this.topology);
+        //locals.put("routingEngine", this.routingEngine);
+        //locals.put("forwarding", this.forwarding);
+        //locals.put("staticFlowEntryPusher", this.staticFlowEntryPusher);
         locals.put("counterStore", this.counterStore);
         locals.put("storageSource", this.storageSource);
         locals.put("switches", this.switches);
-        locals.put("messageFilterManager", this.messageFilterManager);
+        //locals.put("messageFilterManager", this.messageFilterManager);
 
         Server debug_server = new Server(6655, locals);
         debug_server.start();
 	}
-
-    /**
-     * Main function entry point; override init() for adding modules
-     * @param args Command line arguments
-     */
-    public static void main(String args[]) throws Exception {
-        System.setProperty("org.restlet.engine.loggerFacadeClass", 
-                           "org.restlet.ext.slf4j.Slf4jLoggerFacade");
-
-        CmdLineSettings settings = new CmdLineSettings();
-        CmdLineParser parser = new CmdLineParser(settings);
-        try {
-            parser.parseArgument(args);
-        } catch (CmdLineException e) {
-            parser.printUsage(System.out);
-            System.exit(1);
-        }
-
-        Controller controller = new Controller(settings);
-        controller.init();
-        controller.startupComponents();
-        controller.run();
+    
+    @Override
+    public void setCmdLineOptions(CmdLineSettings settings) {
+        this.openFlowPort = settings.getOpenFlowPort();
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java b/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java
index 4435682802c6901b2509ad3ee60ec44ab2c5f0b5..9f8b30e141ae0b915f006fad251a1bb8bc1fa724 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java
@@ -26,7 +26,7 @@ import java.util.concurrent.TimeoutException;
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFType;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchFilter;
 import net.floodlightcontroller.core.IOFSwitchListener;
@@ -42,7 +42,7 @@ import net.floodlightcontroller.core.IOFSwitchListener;
 public abstract class OFMessageFuture<T,V> implements Future<V>,
         IOFSwitchFilter, IOFSwitchListener {
 
-    protected IFloodlightProvider floodlightProvider;
+    protected IFloodlightProviderService floodlightProvider;
     protected volatile boolean canceled;
     protected CountDownLatch latch;
     protected OFType responseType;
@@ -51,12 +51,12 @@ public abstract class OFMessageFuture<T,V> implements Future<V>,
     protected Runnable timeoutTimer;
     protected int transactionId;
 
-    public OFMessageFuture(IFloodlightProvider floodlightProvider, IOFSwitch sw,
+    public OFMessageFuture(IFloodlightProviderService floodlightProvider, IOFSwitch sw,
             OFType responseType, int transactionId) {
         this(floodlightProvider, sw, responseType, transactionId, 60, TimeUnit.SECONDS);
     }
 
-    public OFMessageFuture(IFloodlightProvider floodlightProvider, IOFSwitch sw,
+    public OFMessageFuture(IFloodlightProviderService floodlightProvider, IOFSwitch sw,
             OFType responseType, int transactionId, long timeout, TimeUnit unit) {
         this.floodlightProvider = floodlightProvider;
         this.canceled = false;
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java b/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java
index 6c9870c518a11305f0d0086401132d05793d8393..306d38eeabb4e7f91219cb829fb909826a17a489 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java
@@ -21,7 +21,7 @@ import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.TimeUnit;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 
 import org.openflow.protocol.OFMessage;
@@ -40,13 +40,13 @@ public class OFStatisticsFuture extends
 
     protected volatile boolean finished;
 
-    public OFStatisticsFuture(IFloodlightProvider floodlightProvider, IOFSwitch sw,
+    public OFStatisticsFuture(IFloodlightProviderService floodlightProvider, IOFSwitch sw,
             int transactionId) {
         super(floodlightProvider, sw, OFType.STATS_REPLY, transactionId);
         init();
     }
 
-    public OFStatisticsFuture(IFloodlightProvider floodlightProvider, IOFSwitch sw,
+    public OFStatisticsFuture(IFloodlightProviderService floodlightProvider, IOFSwitch sw,
             int transactionId, long timeout, TimeUnit unit) {
         super(floodlightProvider, sw, OFType.STATS_REPLY, transactionId, timeout, unit);
         init();
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
index c514d19907fb1bb11ff9ee340d99274ce47168df..e280358f952e5b489744e2c85e49b92938eb41a0 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java
@@ -30,7 +30,7 @@ import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.types.MacVlanPair;
 import net.floodlightcontroller.util.TimedCache;
@@ -62,7 +62,7 @@ public class OFSwitchImpl implements IOFSwitch {
     protected static Logger log = LoggerFactory.getLogger(OFSwitchImpl.class);
 
     protected ConcurrentMap<Object, Object> attributes;
-    protected IFloodlightProvider floodlightProvider;
+    protected IFloodlightProviderService floodlightProvider;
     protected Date connectedSince;
     protected OFFeaturesReply featuresReply;
     protected String stringId;
@@ -275,7 +275,7 @@ public class OFSwitchImpl implements IOFSwitch {
     /**
      * @param floodlightProvider the floodlightProvider to set
      */
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
+    public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
     }
 
diff --git a/src/main/java/net/floodlightcontroller/core/internal/TerminationStorageExceptionHandler.java b/src/main/java/net/floodlightcontroller/core/internal/TerminationStorageExceptionHandler.java
index 111dc291766f6fef159d585d422f14e606b1569c..9b27ae1db7b20a33eb41ded28f46993b3963f34f 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/TerminationStorageExceptionHandler.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/TerminationStorageExceptionHandler.java
@@ -20,15 +20,15 @@ package net.floodlightcontroller.core.internal;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.storage.IStorageExceptionHandler;
 
 public class TerminationStorageExceptionHandler implements IStorageExceptionHandler {
     protected static Logger log = LoggerFactory.getLogger(TerminationStorageExceptionHandler.class);
 
-    private IFloodlightProvider floodlightProvider;
+    private IFloodlightProviderService floodlightProvider;
     
-    TerminationStorageExceptionHandler(IFloodlightProvider floodlightProvider) {
+    TerminationStorageExceptionHandler(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
     }
     
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..2f90c3a33dd4e49590c050218c7c535e61228fe9
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java
@@ -0,0 +1,45 @@
+package net.floodlightcontroller.core.module;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * The service registry for an IFloodlightProvider.
+ * @author alexreimers
+ */
+public class FloodlightModuleContext implements IFloodlightModuleContext {
+	protected Map<Class<? extends IFloodlightService>, IFloodlightService> serviceMap;
+	
+	/**
+	 * Creates the ModuleContext for use with this IFloodlightProvider.
+	 * This will be used as a module registry for all IFloodlightModule(s).
+	 */
+	public FloodlightModuleContext() {
+		serviceMap = 
+		        new HashMap<Class<? extends IFloodlightService>,
+		                              IFloodlightService>();
+	}
+	
+	/**
+	 * Adds a IFloodlightModule for this Context.
+	 * @param clazz the service class
+	 * @param module The IFloodlightModule to add to the registry
+	 */
+	public void addService(Class<? extends IFloodlightService> clazz, 
+	                       IFloodlightService service) {
+		serviceMap.put(clazz, service);
+	}
+	
+	@SuppressWarnings("unchecked")
+    @Override
+	public <T extends IFloodlightService> T getServiceImpl(Class<T> service) {
+	    IFloodlightService s = serviceMap.get(service);
+		return (T)s;
+	}
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getAllServices() {
+	    return serviceMap.keySet();
+	}
+ }
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleException.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleException.java
new file mode 100644
index 0000000000000000000000000000000000000000..20ccc86d478d0869f71251025960bda89060fd50
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleException.java
@@ -0,0 +1,9 @@
+package net.floodlightcontroller.core.module;
+
+public class FloodlightModuleException extends Exception {
+	private static final long serialVersionUID = 1L;
+
+	public FloodlightModuleException(String error) {
+		super(error);
+	}
+}
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
new file mode 100644
index 0000000000000000000000000000000000000000..9781c398f85404b8055887d34f63953239b54cc8
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
@@ -0,0 +1,289 @@
+package net.floodlightcontroller.core.module;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Queue;
+import java.util.ServiceLoader;
+import java.util.Set;
+
+
+import net.floodlightcontroller.core.internal.CmdLineSettings;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Finds all Floodlight modules in the class path and loads/starts them.
+ * @author alexreimers
+ *
+ */
+public class FloodlightModuleLoader {
+    protected static Logger logger = 
+            LoggerFactory.getLogger(FloodlightModuleLoader.class);
+
+    protected static Map<Class<? extends IFloodlightService>,
+                  Collection<IFloodlightModule>> serviceMap;
+    protected static Map<IFloodlightModule,
+                  Collection<Class<? extends 
+                                   IFloodlightService>>> moduleServiceMap;
+    protected static Map<String, IFloodlightModule> moduleNameMap;
+    protected static Object lock = new Object();
+    
+    protected FloodlightModuleContext floodlightModuleContext;
+	
+	public FloodlightModuleLoader() {
+	    floodlightModuleContext = new FloodlightModuleContext();
+	}
+	
+	/**
+	 * Finds all IFloodlightModule(s) in the classpath. It creates 3 Maps.
+	 * serviceMap -> Maps a service to a module
+	 * moduleServiceMap -> Maps a module to all the services it provides
+	 * moduleNameMap -> Maps the string name to the module
+	 */
+	protected static void findAllModules() {
+	    synchronized (lock) {
+	        if (serviceMap != null) return;
+	        serviceMap = 
+	                new HashMap<Class<? extends IFloodlightService>,
+	                            Collection<IFloodlightModule>>();
+	        moduleServiceMap = 
+	                new HashMap<IFloodlightModule,
+	                            Collection<Class<? extends 
+	                                       IFloodlightService>>>();
+	        moduleNameMap = new HashMap<String, IFloodlightModule>();
+	        
+	        // Get all the current modules in the classpath
+	        ClassLoader cl = Thread.currentThread().getContextClassLoader();
+	        ServiceLoader<IFloodlightModule> moduleLoader
+	            = ServiceLoader.load(IFloodlightModule.class, cl);
+	        // Iterate for each module, iterate through and add it's services
+	        for (IFloodlightModule m : moduleLoader) {
+	            if (logger.isDebugEnabled()) {
+	                logger.debug("Found module " + m.getClass().getName());
+	            }
+
+	            // Set up moduleNameMap
+	            moduleNameMap.put(m.getClass().getCanonicalName(), m);
+
+	            // Set up serviceMap
+	            Collection<Class<? extends IFloodlightService>> servs =
+	                    m.getModuleServices();
+	            if (servs != null) {
+	                moduleServiceMap.put(m, servs);
+	                for (Class<? extends IFloodlightService> s : servs) {
+	                    Collection<IFloodlightModule> mods = 
+	                            serviceMap.get(s);
+	                    if (mods == null) {
+	                        mods = new ArrayList<IFloodlightModule>();
+	                        serviceMap.put(s, mods);
+	                    }
+	                    mods.add(m);
+	                }
+	            }
+	        }
+	    }
+	}
+	
+	/**
+	 * Loads
+	 * @param fName
+	 * @return
+	 * @throws FloodlightModuleException
+	 */
+	public IFloodlightModuleContext loadModulesFromConfig(String fName) 
+	        throws FloodlightModuleException {
+	    Properties prop = new Properties();
+	    
+	    // Load defaults if no properties file exists
+	    if (fName == null) {
+	        logger.debug("No module file specified, using defaults");
+	        String[] mList = new String[2];
+	        mList[0] = "net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher";
+	        mList[1] = "net.floodlightcontroller.forwarding.Forwarding";
+	        return loadModulesFromList(mList);
+	    } else {
+            try {
+                if (fName == CmdLineSettings.DEFAULT_CONFIG_FILE) {
+                    logger.debug("Loading default module file " + fName);
+                    InputStream is = this.getClass().getClassLoader().getResourceAsStream(fName);
+                    if (is == null) {
+                        logger.error("Could not find default properties file!");
+                        System.exit(1);
+                    }
+                    prop.load(is);
+                } else {
+                    logger.debug("Loading modules from file " + fName);
+                    prop.load(new FileInputStream(fName));
+                }
+            } catch (IOException ex) {
+                logger.debug("Properties file " + fName + " not found!");
+                ex.printStackTrace();
+                System.exit(1);
+            }
+            return loadModulesFromList(prop.getProperty("floodlight.modules").split(","));
+	    }
+	}
+	
+	/**
+	 * Loads modules (and their dependencies) specified in the list
+	 * @param mList The array of fully qualified module names
+	 * @return The ModuleContext containing all the loaded modules
+	 * @throws FloodlightModuleException
+	 */
+	public IFloodlightModuleContext loadModulesFromList(String[] mList) 
+            throws FloodlightModuleException {
+        logger.debug("Starting module loader");
+        findAllModules();
+        
+        Set<IFloodlightModule> moduleSet = new HashSet<IFloodlightModule>();
+        Map<Class<? extends IFloodlightService>, IFloodlightModule> moduleMap =
+                new HashMap<Class<? extends IFloodlightService>,
+                            IFloodlightModule>();
+
+        HashSet<String> configMods = new HashSet<String>();
+        configMods.addAll(Arrays.asList(mList));
+        Queue<String> moduleQ = new LinkedList<String>();
+        // Add the explicitly configured modules to the q
+        moduleQ.addAll(configMods);
+        Set<String> modsVisited = new HashSet<String>();
+        
+        while (!moduleQ.isEmpty()) {
+            String moduleName = moduleQ.remove();
+            if (modsVisited.contains(moduleName))
+                continue;
+            modsVisited.add(moduleName);
+            IFloodlightModule module = moduleNameMap.get(moduleName);
+            if (module == null) {
+                throw new FloodlightModuleException("Module " + 
+                        moduleName + " not found");
+            }
+            // Add the module to be loaded
+            addModule(moduleMap, moduleSet, module);
+            // Add it's dep's to the queue
+            Collection<Class<? extends IFloodlightService>> deps = 
+                    module.getModuleDependencies();
+            if (deps != null) {
+                for (Class<? extends IFloodlightService> c : deps) {
+                    IFloodlightModule m = moduleMap.get(c);
+                    if (m == null) {
+                        Collection<IFloodlightModule> mods = serviceMap.get(c);
+                        // Make sure only one module is loaded
+                        if ((mods == null) || (mods.size() == 0)) {
+                            System.out.println(serviceMap.keySet());
+                            throw new FloodlightModuleException("ERROR! Could not " +
+                                    "find an IFloodlightModule that provides service " +
+                                    c.toString());
+                        } else if (mods.size() == 1) {
+                            IFloodlightModule mod = mods.iterator().next();
+                            if (!modsVisited.contains(mod.getClass().getCanonicalName()))
+                                moduleQ.add(mod.getClass().getCanonicalName());
+                        } else {
+                            boolean found = false;
+                            for (IFloodlightModule moduleDep : mods) {
+                                if (configMods.contains(moduleDep.getClass().getCanonicalName())) {
+                                    // Module will be loaded, we can continue
+                                    found = true;
+                                    break;
+                                }
+                            }
+                            if (!found) {
+                                throw new FloodlightModuleException("ERROR! Found more " + 
+                                        "than one (" + mods.size() + ") IFloodlightModules that provides " + 
+                                        "service " + c.toString() + 
+                                        ". Please resolve this in the config");
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        
+        initModules(moduleSet);
+        startupModules(moduleSet);
+        
+        return floodlightModuleContext;
+    }
+	
+	/**
+	 * Add a module to the set of modules to load and register its services
+	 * @param moduleMap the module map
+	 * @param moduleSet the module set
+	 * @param module the module to add
+	 */
+	protected void addModule(Map<Class<? extends IFloodlightService>, 
+                                           IFloodlightModule> moduleMap,
+                            Set<IFloodlightModule> moduleSet,
+                            IFloodlightModule module) {
+        if (!moduleSet.contains(module)) {
+            Collection<Class<? extends IFloodlightService>> servs =
+                    moduleServiceMap.get(module);
+            if (servs != null) {
+                for (Class<? extends IFloodlightService> c : servs)
+                    moduleMap.put(c, module);
+            }
+            moduleSet.add(module);
+        }
+	}
+
+    /**
+     * Allocate service implementations and then init all the modules
+     * @param moduleSet The set of modules to call their init function on
+     * @throws FloodlightModuleException If a module can not properly be loaded
+     */
+    protected void initModules(Set<IFloodlightModule> moduleSet) 
+                                           throws FloodlightModuleException {
+        for (IFloodlightModule module : moduleSet) {            
+            // Get the module's service instance(s)
+            Map<Class<? extends IFloodlightService>, 
+                IFloodlightService> simpls = module.getServiceImpls();
+
+            // add its services to the context
+            if (simpls != null) {
+                for (Entry<Class<? extends IFloodlightService>, 
+                        IFloodlightService> s : simpls.entrySet()) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Setting " + s.getValue() + 
+                                     "  as provider for " + 
+                                     s.getKey().getCanonicalName());
+                    }
+                    floodlightModuleContext.addService(s.getKey(),
+                                                       s.getValue());
+                }
+            }
+        }
+        
+        for (IFloodlightModule module : moduleSet) {
+            // init the module
+            if (logger.isDebugEnabled()) {
+                logger.debug("Initializing " + 
+                             module.getClass().getCanonicalName());
+            }
+            module.init(floodlightModuleContext);
+        }
+    }
+    
+    /**
+     * Call each loaded module's startup method
+     * @param moduleSet the module set to start up
+     */
+    protected void startupModules(Set<IFloodlightModule> moduleSet) {
+        for (IFloodlightModule m : moduleSet) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Starting " + 
+                             m.getClass().getCanonicalName());
+            }
+            m.startUp(floodlightModuleContext);
+        }
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java
new file mode 100644
index 0000000000000000000000000000000000000000..003e0a119d1eeda8abc1a7ee45798e552622956f
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java
@@ -0,0 +1,77 @@
+package net.floodlightcontroller.core.module;
+
+import java.util.Collection;
+import java.util.Map;
+
+
+/**
+ * Defines an interface for loadable Floodlight modules.
+ * 
+ * At a high level, these functions are called in the following order:
+ * <ol>
+ * <li> getServices() : what services does this module provide
+ * <li> getDependencies() : list the dependencies
+ * <li> init() : internal initializations (don't touch other modules)
+ * <li> startUp() : external initializations (<em>do</em> touch other modules)
+ * </ol>
+ * 
+ * @author alexreimers
+ */
+public interface IFloodlightModule {
+	
+	/**
+	 * Return the list of interfaces that this module implements.
+	 * All interfaces must inherit IFloodlightService
+	 * @return
+	 */
+	
+	public Collection<Class<? extends IFloodlightService>> getModuleServices();
+	
+	/**
+	 * Instantiate (as needed) and return objects that implement each
+	 * of the services exported by this module.  The map returned maps
+	 * the implemented service to the object.  The object could be the
+	 * same object or different objects for different exported services.
+	 * @return The map from service interface class to service implementation
+	 */
+	public Map<Class<? extends IFloodlightService>,
+	           IFloodlightService> getServiceImpls();
+	
+	/**
+	 * Get a list of Modules that this module depends on.  The module system
+	 * will ensure that each these dependencies is resolved before the 
+	 * subsequent calls to init().
+	 * @return The Collection of IFloodlightServices that this module depnds
+	 *         on.
+	 */
+	
+	public Collection<Class<? extends IFloodlightService>> getModuleDependencies();
+	
+	/**
+	 * This is a hook for each module to do its <em>internal</em> initialization, 
+	 * e.g., call setService(context.getService("Service"))
+	 * 
+	 * All module dependencies are resolved when this is called, but not every module 
+	 * is initialized.
+	 * 
+	 * @param context
+	 * @throws FloodlightModuleException
+	 */
+	
+	void init(FloodlightModuleContext context) throws FloodlightModuleException;
+	
+	/**
+	 * This is a hook for each module to do its <em>external</em> initializations,
+	 * e.g., register for callbacks or query for state in other modules
+	 * 
+	 * It is expected that this function will not block and that modules that want
+	 * non-event driven CPU will spawn their own threads.
+	 * 
+	 * @param context
+	 */
+	
+	void startUp(FloodlightModuleContext context); 
+	
+	// TODO add getName() getId()
+	
+}
diff --git a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java
new file mode 100644
index 0000000000000000000000000000000000000000..a22c3807201b42d6db2997e1f54f1357e0296ffb
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java
@@ -0,0 +1,21 @@
+package net.floodlightcontroller.core.module;
+
+import java.util.Collection;
+
+	
+public interface IFloodlightModuleContext {	
+    /**
+     * Retrieves a casted version of a module from the registry.
+     * @param name The IFloodlightService object type
+     * @return The IFloodlightService
+     * @throws FloodlightModuleException If the module was not found 
+     * or a ClassCastException was encountered.
+     */
+    public <T extends IFloodlightService> T getServiceImpl(Class<T> service);
+    
+    /**
+     * Returns all loaded services
+     * @return A collection of service classes that have been loaded
+     */
+    public Collection<Class<? extends IFloodlightService>> getAllServices();
+}
diff --git a/src/main/java/net/floodlightcontroller/core/module/IFloodlightService.java b/src/main/java/net/floodlightcontroller/core/module/IFloodlightService.java
new file mode 100644
index 0000000000000000000000000000000000000000..8bf26cca38d3d8a8d0ec0b80f23ea19616fb8327
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightService.java
@@ -0,0 +1,12 @@
+package net.floodlightcontroller.core.module;
+
+/**
+ * This is the base interface for any IFloodlightModule package that provides 
+ * a service.
+ * @author alexreimers
+ *
+ */
+// TODO change this to IFloodlightExclusiveService
+public abstract interface IFloodlightService {
+    // This space is intentionally left blank....don't touch it
+}
diff --git a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java
index 2ef32f13d94978889d3ed387bbe03cf3c31de609..f8509d9223e38b3f689edeb16d1be576e50a8c69 100644
--- a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java
@@ -23,7 +23,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.types.MacVlanPair;
 
 import org.openflow.protocol.OFFeaturesReply;
@@ -80,7 +80,9 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase {
             return model;
         }
         
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();        
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());        
         Long[] switchDpids = floodlightProvider.getSwitches().keySet().toArray(new Long[0]);
         List<GetConcurrentStatsThread> activeThreads = new ArrayList<GetConcurrentStatsThread>(switchDpids.length);
         List<GetConcurrentStatsThread> pendingRemovalThreads = new ArrayList<GetConcurrentStatsThread>();
@@ -167,7 +169,9 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase {
         }
         
         public void run() {
-            IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();        
+            IFloodlightProviderService floodlightProvider = 
+                    (IFloodlightProviderService)getContext().getAttributes().
+                        get(IFloodlightProviderService.class.getCanonicalName());      
 
             if ((requestType == REQUESTTYPE.OFSTATS) && (statType != null)) {
                 switchReply = getSwitchStatistics(switchId, statType);
diff --git a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
index b2d903a6ec6d712f4529c84f05c4480fb6ab6136..c8f74860e7369ecb789be974bc3343ba86afcf78 100644
--- a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java
@@ -22,7 +22,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 
 import org.restlet.resource.Get;
@@ -35,9 +35,10 @@ import org.restlet.resource.ServerResource;
 public class ControllerSwitchesResource extends ServerResource {
     @Get("json")
     public List<Map<String, String>> retrieve() {
-        List<Map<String, String>> switchIds = new ArrayList<Map<String, String>>();        
-
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        List<Map<String, String>> switchIds = new ArrayList<Map<String, String>>();
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());
         Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches();
 
         for (IOFSwitch s: switches.values()) {
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index d798d263665de61349f95e6796f1323b9a236f0b..81fe2fa41852209daabe40eb4641c9cc6e2dd1d1 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -17,6 +17,8 @@
 
 package net.floodlightcontroller.core.web;
 
+import net.floodlightcontroller.restserver.RestletRoutable;
+
 import org.restlet.Context;
 import org.restlet.Restlet;
 import org.restlet.routing.Router;
diff --git a/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java
index e27b0ae31236b65243d6cffb4e558a62415b073b..70e90ed231431b7c88e1377183671698686b5f75 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java
@@ -17,18 +17,19 @@
 
 package net.floodlightcontroller.core.web;
 
-import net.floodlightcontroller.counter.CounterStore;
+import net.floodlightcontroller.counter.ICounterStoreService;
 
 import org.restlet.resource.ResourceException;
 import org.restlet.resource.ServerResource;
 
 public class CounterResourceBase extends ServerResource {
-    protected CounterStore counterStore;
+    protected ICounterStoreService counterStore;
     
     @Override
     protected void doInit() throws ResourceException {
         super.doInit();
         counterStore = 
-            (CounterStore)getContext().getAttributes().get("counterStore");
+            (ICounterStoreService)getContext().getAttributes().
+                get(ICounterStoreService.class.getCanonicalName());
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java b/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java
index 0bd3336657c32d5b9515f673037f528c5557a460..1a41ffc301c6702b78a8b8f484f224d1f7ba2a03 100644
--- a/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java
@@ -76,12 +76,13 @@ public class PacketTraceResource extends ServerResource {
     @Post("json")
     public PacketTraceOutput packettrace(FilterParameters fp) {
         
-        ConcurrentHashMap <String,String> filter = new  ConcurrentHashMap<String,String> ();
+        ConcurrentHashMap <String,String> filter = new ConcurrentHashMap<String,String> ();
         String sid = null;
         PacketTraceOutput output = new PacketTraceOutput();
         OFMessageFilterManager manager = 
                 (OFMessageFilterManager)getContext()
-                    .getAttributes().get("messageFilterManager");
+                    .getAttributes().
+                        get(OFMessageFilterManager.class.getCanonicalName());
 
         if (manager == null) {
             sid = null;
diff --git a/src/main/java/net/floodlightcontroller/core/web/StaticFlowEntryPusherResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/StaticFlowEntryPusherResourceBase.java
index d1b0abb088c6ad6779173a8b4208e63b1c7192e3..61254552261ed868edde881ca3b30abcc1ab779e 100644
--- a/src/main/java/net/floodlightcontroller/core/web/StaticFlowEntryPusherResourceBase.java
+++ b/src/main/java/net/floodlightcontroller/core/web/StaticFlowEntryPusherResourceBase.java
@@ -28,6 +28,7 @@ public class StaticFlowEntryPusherResourceBase extends ServerResource {
     protected void doInit() throws ResourceException {
         super.doInit();
         staticFlowEntryPusher = 
-             (StaticFlowEntryPusher)getContext().getAttributes().get("staticFlowEntryPusher");
+             (StaticFlowEntryPusher)getContext().getAttributes().
+                 get(IStaticFlowEntryPusherService.class);
     }
 }
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/web/StorageSourceTablesResource.java b/src/main/java/net/floodlightcontroller/core/web/StorageSourceTablesResource.java
index e657251e87bc0b0cf7da94c610e0c918764d857f..51f514f50506a0cf7ff0db1bd5306bedda6e41c9 100644
--- a/src/main/java/net/floodlightcontroller/core/web/StorageSourceTablesResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/StorageSourceTablesResource.java
@@ -2,7 +2,7 @@ package net.floodlightcontroller.core.web;
 
 import java.util.Set;
 
-import net.floodlightcontroller.storage.IStorageSource;
+import net.floodlightcontroller.storage.IStorageSourceService;
 
 import org.restlet.resource.Get;
 import org.restlet.resource.ServerResource;
@@ -10,7 +10,8 @@ import org.restlet.resource.ServerResource;
 public class StorageSourceTablesResource extends ServerResource {
     @Get("json")
     public Set<String> retrieve() {
-        IStorageSource storageSource = (IStorageSource)getContext().getAttributes().get("storageSource");
+        IStorageSourceService storageSource = (IStorageSourceService)getContext().
+                getAttributes().get(IStorageSourceService.class.getCanonicalName());
         Set<String> allTableNames = storageSource.getAllTableNames();
         return allTableNames;
     }
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java
index c3d8ae6ac4d34ae6ffa2efcbf1ff41c09e4ab422..8ac83ce8f1a6aa3843a0f023fb0550d6cf2c99f2 100644
--- a/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java
@@ -23,7 +23,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 
 import org.openflow.util.HexString;
@@ -36,7 +36,9 @@ import org.restlet.resource.ServerResource;
 public class SwitchClustersResource extends ServerResource {
     @Get("json")
     public Map<String, List<String>> retrieve() {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());
         Map<String, List<String>> switchClusterMap = new HashMap<String, List<String>>();
         for (Entry<Long, IOFSwitch> entry : floodlightProvider.getSwitches().entrySet()) {
             Long clusterDpid = entry.getValue().getSwitchClusterId();
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchCounterCategoriesResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchCounterCategoriesResource.java
index dbce9f0880e46bb74eb910c2753e9d39c5a1c9d0..f14d7062eb658f334f8b11108c5f9dfe6d5e20af 100644
--- a/src/main/java/net/floodlightcontroller/core/web/SwitchCounterCategoriesResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/SwitchCounterCategoriesResource.java
@@ -26,9 +26,9 @@ import java.util.Map;
 import org.openflow.util.HexString;
 import org.restlet.resource.Get;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
-import net.floodlightcontroller.counter.CounterStore;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.counter.CounterStore.NetworkLayer;
+import net.floodlightcontroller.counter.ICounterStoreService;
 
 /**
  * Get the counter categories for a particular switch
@@ -37,7 +37,9 @@ import net.floodlightcontroller.counter.CounterStore.NetworkLayer;
 public class SwitchCounterCategoriesResource extends CounterResourceBase {
     @Get("json")
     public Map<String, Object> retrieve() {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());
         HashMap<String,Object> model = new HashMap<String,Object>();
         
         String switchID = (String) getRequestAttributes().get("switchId");
@@ -69,7 +71,7 @@ public class SwitchCounterCategoriesResource extends CounterResourceBase {
         try {
             counterName = URLDecoder.decode(counterName, "UTF-8");
             layer = URLDecoder.decode(layer, "UTF-8");
-            fullCounterName = switchID + CounterStore.TitleDelimitor + counterName;
+            fullCounterName = switchID + ICounterStoreService.TitleDelimitor + counterName;
         } catch (UnsupportedEncodingException e) {
             //Just leave counterTitle undecoded if there is an issue - fail silently
         }
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchCounterResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchCounterResource.java
index 143121417dc2ba0a715395ae3dcb2fbeb96fe435..0af59c42fa5fdb8eb46bcc66cf48395ec90a7383 100644
--- a/src/main/java/net/floodlightcontroller/core/web/SwitchCounterResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/SwitchCounterResource.java
@@ -25,9 +25,9 @@ import java.util.Map;
 import org.openflow.util.HexString;
 import org.restlet.resource.Get;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
-import net.floodlightcontroller.counter.CounterStore;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.counter.ICounter;
+import net.floodlightcontroller.counter.ICounterStoreService;
 
 /**
  * Get counters for a particular switch 
@@ -36,7 +36,9 @@ import net.floodlightcontroller.counter.ICounter;
 public class SwitchCounterResource extends CounterResourceBase {
     @Get("json")
     public Map<String, Object> retrieve() {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());
         HashMap<String,Object> model = new HashMap<String,Object>();
         
         String switchID = (String) getRequestAttributes().get("switchId");
@@ -63,7 +65,7 @@ public class SwitchCounterResource extends CounterResourceBase {
         try {
             counterName = URLDecoder.decode(counterName, "UTF-8");
             fullCounterName = 
-                switchID + CounterStore.TitleDelimitor + counterName;
+                switchID + ICounterStoreService.TitleDelimitor + counterName;
         } catch (UnsupportedEncodingException e) {
             //Just leave counterTitle undecoded if there is an issue - fail silently
         }
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java
index 8ea10996543a0bdf1490383a58755c94aff07fe3..83234ce62ed12bd456258056da2408b713fa2f3f 100644
--- a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java
+++ b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java
@@ -26,7 +26,7 @@ import java.util.Map;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.types.MacVlanPair;
 
@@ -66,7 +66,9 @@ public class SwitchResourceBase extends ServerResource {
     }
     
     protected List<OFStatistics> getSwitchStatistics(long switchId, OFStatisticsType statType) {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());
         
         IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
         Future<List<OFStatistics>> future;
@@ -132,7 +134,9 @@ public class SwitchResourceBase extends ServerResource {
      * @return A list of switch table entries
      */
     protected List<Map<String, Object>> getSwitchTableJson(long switchId) {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());
 
         IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
         List<Map<String, Object>> switchTableJson = null;
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java
index 0f10c2538e1c888fd2db3c98a16d659b0ebf4702..41c779ba9d1e5641adf6552e613c2202d5097747 100644
--- a/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java
@@ -21,7 +21,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 
 import org.openflow.protocol.OFFeaturesReply;
@@ -42,7 +42,9 @@ public class SwitchStatisticsResource extends SwitchResourceBase {
 
     @Get("json")
     public Map<String, Object> retrieve() {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = 
+                (IFloodlightProviderService)getContext().getAttributes().
+                    get(IFloodlightProviderService.class.getCanonicalName());
         
         HashMap<String,Object> result = new HashMap<String,Object>();
         List<OFStatistics> values = null;
diff --git a/src/main/java/net/floodlightcontroller/counter/CounterStore.java b/src/main/java/net/floodlightcontroller/counter/CounterStore.java
index 0da77e20088bf59851a427b6bd686884885b8495..585afc6a3f2b031933037c0ff216a2393cb0cd5d 100644
--- a/src/main/java/net/floodlightcontroller/counter/CounterStore.java
+++ b/src/main/java/net/floodlightcontroller/counter/CounterStore.java
@@ -35,12 +35,7 @@ import javax.annotation.PostConstruct;
  * @author kyle
  *
  */
-public class CounterStore {
-    public final static String TitleDelimitor = "__";
-
-    /** L2 EtherType subCategories */
-    public final static String L3ET_IPV4 = "L3_IPv4";
-
+public class CounterStore implements ICounterStoreService {
     public enum NetworkLayer {
         L3, L4
     }
@@ -121,10 +116,7 @@ public class CounterStore {
         return fullCounterName;
     }
 
-    /**
-     * Retrieve a list of subCategories by counterName.
-     * null if nothing.
-     */
+    @Override
     public List<String> getAllCategories(String counterName, NetworkLayer layer) {
         if (layeredCategories.containsKey(layer)) {
             Map<String, List<String>> counterToCategories = layeredCategories.get(layer);
@@ -135,14 +127,7 @@ public class CounterStore {
         return null;
     }
     
-    /**
-     * Create a new ICounter and set the title.  Note that the title must be unique, otherwise this will
-     * throw an IllegalArgumentException.
-     * 
-     * @param key
-     * @param type
-     * @return
-     */
+    @Override
     public ICounter createCounter(String key, CounterValue.CounterType type) {
         CounterEntry ce;
         ICounter c;
@@ -175,9 +160,7 @@ public class CounterStore {
             }}, 100, 100, TimeUnit.MILLISECONDS);
     }
     
-    /**
-     * Retrieves a counter with the given title, or null if none can be found.
-     */
+    @Override
     public ICounter getCounter(String key) {
         CounterEntry counter = nameToCEIndex.get(key);
         if (counter != null) {
@@ -187,11 +170,10 @@ public class CounterStore {
         }
     }
 
-    /**
-     * Returns an immutable map of title:counter with all of the counters in the store.
-     * 
-     * (Note - this method may be slow - primarily for debugging/UI)
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.counter.ICounterStoreService#getAll()
      */
+    @Override
     public Map<String, ICounter> getAll() {
         Map<String, ICounter> ret = new ConcurrentHashMap<String, ICounter>();
         for(Map.Entry<String, CounterEntry> counterEntry : this.nameToCEIndex.entrySet()) {
diff --git a/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java b/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java
new file mode 100644
index 0000000000000000000000000000000000000000..86e71f8d695f148ff38e7415eb9bca2822d9007e
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.counter;
+
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.counter.CounterStore.NetworkLayer;
+
+public interface ICounterStoreService extends IFloodlightService {
+
+    public final static String TitleDelimitor = "__";
+    /** L2 EtherType subCategories */
+    public final static String L3ET_IPV4 = "L3_IPv4";
+
+    /**
+     * Retrieve a list of subCategories by counterName.
+     * null if nothing.
+     */
+    public List<String> getAllCategories(String counterName,
+                                         NetworkLayer layer);
+
+    /**
+     * Create a new ICounter and set the title.  Note that the title must be 
+     * unique, otherwise this will throw an IllegalArgumentException.
+     * 
+     * @param key
+     * @param type
+     * @return
+     */
+    public ICounter createCounter(String key, CounterValue.CounterType type);
+
+    /**
+     * Retrieves a counter with the given title, or null if none can be found.
+     */
+    public ICounter getCounter(String key);
+
+    /**
+     * Returns an immutable map of title:counter with all of the counters in the store.
+     * 
+     * (Note - this method may be slow - primarily for debugging/UI)
+     */
+    public Map<String, ICounter> getAll();
+}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManager.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java
similarity index 90%
rename from src/main/java/net/floodlightcontroller/devicemanager/IDeviceManager.java
rename to src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java
index 14bed96ad758f53bf2f59ac5cd4c880b2fd843e7..e0bd44f193d8026c7e78b087abb6edc3dde038be 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManager.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java
@@ -21,12 +21,14 @@ import java.util.Collection;
 
 import net.floodlightcontroller.core.FloodlightContextStore;
 
+import net.floodlightcontroller.core.module.IFloodlightService;
+
 /**
  * Device manager allows interacting with devices on the network.  Note
  * that under normal circumstances, {@link Device} objects should be retrieved
  * from the {@link FloodlightContext} rather than from {@link IDeviceManager}.
  */
-public interface IDeviceManager {
+public interface IDeviceManagerService extends IFloodlightService {
     /**
      * The source device for the current packet-in, if applicable.
      */
@@ -45,7 +47,7 @@ public interface IDeviceManager {
      */
     public static final FloodlightContextStore<IDevice> fcStore = 
         new FloodlightContextStore<IDevice>();
-    
+
     /**
      * Set the entity classifier for the device manager to use to
      * differentiate devices on the network.  If no classifier is set,
@@ -54,7 +56,7 @@ public interface IDeviceManager {
      * @param classifier the classifier to set.
      */
     public void setEntityClassifier(IEntityClassifier classifier);
-    
+
     /**
      * Flush and/or reclassify all entities in a class
      *
@@ -63,7 +65,7 @@ public interface IDeviceManager {
      * flushed entities
      */
     public void flushEntityCache(IEntityClass entityClass, boolean reclassify);
-    
+
     /**
      * Search for a device using entity fields.  Only the key fields as
      * defined by the {@link IEntityClassifier} will be important in this
@@ -79,10 +81,16 @@ public interface IDeviceManager {
     public IDevice findDevice(long macAddress, Integer ipv4Address,
                               Short vlan, Long switchDPID,
                               Integer switchPort);
-    
+
     /**
      * Get an unmodifiable collection view over all devices currently known.
      * @return the collection of all devices
      */
     public Collection<? extends IDevice> getAllDevices();
+
+    /**
+     * Adds a listener to listen for IDeviceManagerServices notifications
+     * @param listener The listener that wants the notifications
+     */
+    public void addListener(IDeviceManagerAware listener);
 }
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index 04fe294fc8a04d73dd9f6793f556292b9dffb6fb..3ce0d6d832a62ae1984cc228e130498f5f4617a7 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -22,28 +22,35 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.ConcurrentModificationException;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchListener;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceManager;
+import net.floodlightcontroller.devicemanager.IDeviceManagerService;
 import net.floodlightcontroller.devicemanager.IEntityClass;
 import net.floodlightcontroller.devicemanager.IEntityClassifier;
 import net.floodlightcontroller.devicemanager.IEntityClassifier.EntityField;
+import net.floodlightcontroller.devicemanager.IDeviceManagerAware;
 import net.floodlightcontroller.packet.ARP;
 import net.floodlightcontroller.packet.DHCP;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.storage.IStorageSource;
+import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.IStorageSourceListener;
-import net.floodlightcontroller.topology.ITopology;
-import net.floodlightcontroller.topology.ITopologyAware;
+import net.floodlightcontroller.topology.ITopologyService;
+import net.floodlightcontroller.topology.ITopologyListener;
 import org.openflow.protocol.OFMessage;
 import org.openflow.protocol.OFPacketIn;
 import org.openflow.protocol.OFPortStatus;
@@ -57,21 +64,23 @@ import org.slf4j.LoggerFactory;
  * within the network.
  * @author readams
  */
-public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener,
-        IOFSwitchListener, ITopologyAware, IStorageSourceListener {  
+public class DeviceManagerImpl implements 
+        IDeviceManagerService, IOFMessageListener,
+        IOFSwitchListener, ITopologyListener, 
+        IStorageSourceListener, IFloodlightModule {  
     protected static Logger logger = 
         LoggerFactory.getLogger(DeviceManagerImpl.class);
 
-    protected IFloodlightProvider floodlightProvider;
-    protected ITopology topology;
-    protected IStorageSource storageSource;
+    protected IFloodlightProviderService floodlightProvider;
+    protected ITopologyService topology;
+    protected IStorageSourceService storageSource;
     
     /**
      * This is the master device map that maps device IDs to {@link Device}
      * objects.
      */
     protected ConcurrentHashMap<Long, Device> deviceMap;
-    
+
     /**
      * Counter used to generate device keys
      */
@@ -135,10 +144,13 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener,
             if (!keyFieldsMatchPrimary)
                 classIndex = new ConcurrentHashMap<IndexedEntity, Long>();
         }
-
-        
     }
     
+    /**
+     * Device manager event listeners
+     */
+    protected Set<IDeviceManagerAware> deviceManagerAware;
+    
     // **************
     // IDeviceManager
     // **************
@@ -171,11 +183,15 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener,
         return Collections.unmodifiableCollection(deviceMap.values());
     }
     
+    @Override
+    public void addListener(IDeviceManagerAware listener) {
+        deviceManagerAware.add(listener);
+    }
+    
     // ******************
     // IOFMessageListener
     // ******************
 
-
     @Override
     public String getName() {
         return "devicemanager";
@@ -280,27 +296,54 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener,
         // TODO Auto-generated method stub
     }
 
-    // **************
-    // Initialization
-    // **************
-
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
-        this.floodlightProvider = floodlightProvider;
+    // *****************
+    // IFloodlightModule
+    // *****************
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l =
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IDeviceManagerService.class);
+        return l;
     }
 
-    public void setStorageSource(IStorageSource storageSource) {
-        this.storageSource = storageSource;
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+            IFloodlightService> m =
+            new HashMap<Class<? extends IFloodlightService>,
+                        IFloodlightService>();
+        // We are the class that implements the service
+        m.put(IDeviceManagerService.class, this);
+        return m;
     }
 
-    public void setTopology(ITopology topology) {
-        this.topology = topology;
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        Collection<Class<? extends IFloodlightService>> l =
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IFloodlightProviderService.class);
+        l.add(IStorageSourceService.class);
+        l.add(ITopologyService.class);
+        return l;
     }
-    
-    public void init() {
+
+    @Override
+    public void init(FloodlightModuleContext fmc) {
+        this.deviceManagerAware = new HashSet<IDeviceManagerAware>();
         
+        this.floodlightProvider = 
+                fmc.getServiceImpl(IFloodlightProviderService.class);
+        this.storageSource =
+                fmc.getServiceImpl(IStorageSourceService.class);
+        this.topology =
+                fmc.getServiceImpl(ITopologyService.class);
     }
-
-    public void startUp() {
+    
+    @Override
+    public void startUp(FloodlightModuleContext fmc) {
         if (entityClassifier == null)
             setEntityClassifier(new DefaultEntityClassifier());
         
@@ -309,8 +352,16 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener,
         classStateMap = 
                 new ConcurrentHashMap<IEntityClass, ClassState>();
         
+        if (topology != null) {
+            // Register to get updates from topology
+            topology.addListener(this);
+        } else {
+            logger.error("Could add not toplogy listener");
+        }
+        
         floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
         floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this);
+        floodlightProvider.addOFSwitchListener(this);
         
         // XXX - TODO entity aging timer
     }
@@ -336,8 +387,8 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener,
                                              FloodlightContext cntx) {
         try {
             Ethernet eth = 
-                    IFloodlightProvider.bcStore.
-                    get(cntx,IFloodlightProvider.CONTEXT_PI_PAYLOAD);
+                    IFloodlightProviderService.bcStore.
+                    get(cntx,IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
 
             // Extract source entity information
             Entity srcEntity = 
@@ -734,5 +785,4 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener,
         
         return true;
     }
-    
 }
diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
index 9fd7fb857150cbd15003ecccdb670d6cc130c905..7a59d45a18f2f0b6abe39c0da4442468aadf64de 100644
--- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
@@ -21,19 +21,27 @@ package net.floodlightcontroller.forwarding;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceManager;
+import net.floodlightcontroller.devicemanager.IDeviceManagerService;
 import net.floodlightcontroller.devicemanager.SwitchPort;
+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.counter.ICounterStoreService;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.routing.ForwardingBase;
 import net.floodlightcontroller.routing.IRoutingDecision;
+import net.floodlightcontroller.routing.IRoutingEngineService;
 import net.floodlightcontroller.routing.Route;
+import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.topology.LinkInfo;
 import net.floodlightcontroller.topology.SwitchPortTuple;
 
@@ -48,13 +56,13 @@ import org.openflow.util.HexString;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class Forwarding extends ForwardingBase {
+public class Forwarding extends ForwardingBase implements IFloodlightModule {
     protected static Logger log = LoggerFactory.getLogger(Forwarding.class);
 
     @Override
     public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) {
-        Ethernet eth = IFloodlightProvider.bcStore.get(cntx, 
-                                                       IFloodlightProvider.CONTEXT_PI_PAYLOAD);
+        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, 
+                                                       IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
         if (eth.isBroadcast() || eth.isMulticast()) {
             // For now we treat multicast as broadcast
             doFlood(sw, pi, cntx);
@@ -73,13 +81,13 @@ public class Forwarding extends ForwardingBase {
 
         // Check if we have the location of the destination
         IDevice dstDevice = 
-                IDeviceManager.fcStore.get(cntx, 
-                                           IDeviceManager.CONTEXT_DST_DEVICE);
+                IDeviceManagerService.fcStore.
+                    get(cntx, IDeviceManagerService.CONTEXT_DST_DEVICE);
         
         if (dstDevice != null) {
             IDevice srcDevice =
-                    IDeviceManager.fcStore.
-                        get(cntx, IDeviceManager.CONTEXT_SRC_DEVICE);
+                    IDeviceManagerService.fcStore.
+                        get(cntx, IDeviceManagerService.CONTEXT_SRC_DEVICE);
             Long srcIsland = sw.getSwitchClusterId();
             
             if (srcDevice == null) {
@@ -262,4 +270,48 @@ public class Forwarding extends ForwardingBase {
         return srcTuple.getSwitchDPID() == dstTuple.getSwitchDPID() &&
                srcTuple.getPort() != dstTuple.getPort();
     }
+
+    // IFloodlightModule methods
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        // We don't export any services
+        return null;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        // We don't have any services
+        return null;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IFloodlightProviderService.class);
+        l.add(IDeviceManagerService.class);
+        l.add(IRoutingEngineService.class);
+        l.add(ITopologyService.class);
+        l.add(ICounterStoreService.class);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+        this.setFloodlightProvider(context.getServiceImpl(IFloodlightProviderService.class));
+        this.setDeviceManager(context.getServiceImpl(IDeviceManagerService.class));
+        this.setRoutingEngine(context.getServiceImpl(IRoutingEngineService.class));
+        this.setTopology(context.getServiceImpl(ITopologyService.class));
+        this.setCounterStore(context.getServiceImpl(ICounterStoreService.class));
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        if (log.isDebugEnabled()) {
+            log.debug("Starting " + this.getClass().getCanonicalName());
+        }
+        super.startUp();
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/hub/Hub.java b/src/main/java/net/floodlightcontroller/hub/Hub.java
index 29b26f31610f939db6296f72bb59c78b843f94d0..db20e43f069643e0d9b29d9d9db3d0c800b787b2 100644
--- a/src/main/java/net/floodlightcontroller/hub/Hub.java
+++ b/src/main/java/net/floodlightcontroller/hub/Hub.java
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.util.Collections;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
 
@@ -43,12 +43,12 @@ import org.slf4j.LoggerFactory;
 public class Hub implements IOFMessageListener {
     protected static Logger log = LoggerFactory.getLogger(Hub.class);
 
-    protected IFloodlightProvider floodlightProvider;
+    protected IFloodlightProviderService floodlightProvider;
 
     /**
      * @param floodlightProvider the floodlightProvider to set
      */
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
+    public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
     }
 
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
index 0c1a383380da6708fe228ad3c7a686f4be4ec8cd..f677a76f7bef219aa44ff0dd314d09ec5ceab43e 100644
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
+++ b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
@@ -35,12 +35,13 @@ import java.util.Arrays;
 import java.util.List;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.counter.CounterStore;
 import net.floodlightcontroller.counter.CounterValue;
 import net.floodlightcontroller.counter.ICounter;
+import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.packet.Ethernet;
 
 import org.openflow.protocol.OFError;
@@ -62,8 +63,8 @@ import org.slf4j.LoggerFactory;
 
 public class LearningSwitch implements IOFMessageListener {
     protected static Logger log = LoggerFactory.getLogger(LearningSwitch.class);
-    protected IFloodlightProvider floodlightProvider;
-    protected CounterStore counterStore;
+    protected IFloodlightProviderService floodlightProvider;
+    protected ICounterStoreService counterStore;
 
     // flow-mod - for use in the cookie
     public static final int LEARNING_SWITCH_APP_ID = 1;
@@ -84,15 +85,15 @@ public class LearningSwitch implements IOFMessageListener {
     /**
      * @param floodlightProvider the floodlightProvider to set
      */
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
+    public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
     }
     
-    public CounterStore getCounterStore() {
+    public ICounterStoreService getCounterStore() {
         return counterStore;
     }
     
-    public void setCounterStore(CounterStore counterStore) {
+    public void setCounterStore(ICounterStoreService counterStore) {
         this.counterStore = counterStore;
     }
     
@@ -257,7 +258,7 @@ public class LearningSwitch implements IOFMessageListener {
         }
     }
     
-    private Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi) {
+    private Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
         // Read in packet data headers by using OFMatch
         OFMatch match = new OFMatch();
         match.loadFromPacket(pi.getPacketData(), pi.getInPort(), sw.getId());
@@ -378,7 +379,7 @@ public class LearningSwitch implements IOFMessageListener {
     public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
         switch (msg.getType()) {
             case PACKET_IN:
-                return this.processPacketInMessage(sw, (OFPacketIn) msg);
+                return this.processPacketInMessage(sw, (OFPacketIn) msg, cntx);
             case PORT_STATUS:
                 return this.processPortStatusMessage(sw, (OFPortStatus) msg);
             case FLOW_REMOVED:
diff --git a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java
index 9af4ba19659f5888bd5581a8d7609c053c44b2e1..70f5735aaf89105fc2bf378b9cb0a518e4119268 100644
--- a/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java
+++ b/src/main/java/net/floodlightcontroller/perfmon/CumulativeTimeBucket.java
@@ -191,7 +191,7 @@ public class CumulativeTimeBucket {
         cumulativeTimeBkt.avgTotalProcTime_us = 0;
         cumulativeTimeBkt.sigmaTotalProcTime_us = 0;
         for (int idx = FlListenerID.FL_FIRST_LISTENER_ID; 
-                        idx <= PktinProcessingTime.BB_LAST_LISTENER_ID; idx++) {
+                        idx <= PktInProcessingTime.BB_LAST_LISTENER_ID; idx++) {
             OneComponentTime oct = cumulativeTimeBkt.tComps.oneComp[idx];
             oct.pktCnt = 0;
             oct.sumProcTime_us = 0;
diff --git a/src/main/java/net/floodlightcontroller/perfmon/IPktInProcessingTimeService.java b/src/main/java/net/floodlightcontroller/perfmon/IPktInProcessingTimeService.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6bf1dd9e8349e3810b818532715a54f6eed1778
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/perfmon/IPktInProcessingTimeService.java
@@ -0,0 +1,43 @@
+package net.floodlightcontroller.perfmon;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.perfmon.PktInProcessingTime.CircularTimeBucketSet;
+import net.floodlightcontroller.perfmon.PktInProcessingTime.PerfMonConfigs;
+
+public interface IPktInProcessingTimeService extends IFloodlightService {
+
+    public Long getLastPktTime_ns();
+
+    public void setLastPktTime_ns(Long lastPktTime_ns);
+
+    public long getCurBucketStartTime();
+
+    public void setCurBucketStartTime(long curBucketStartTime);
+
+    public CumulativeTimeBucket getCtb();
+
+    public void setCtb(CumulativeTimeBucket ctb);
+
+    public CircularTimeBucketSet getCtbs();
+
+    public void setCtbs(CircularTimeBucketSet ctbs);
+
+    public PerfMonConfigs getPerfMonCfgs();
+
+    public void setPerfMonCfgs(PerfMonConfigs perfMonCfgs);
+
+    public int getNumComponents();
+
+    public void setNumComponents(int numComponents);
+
+    public long getStartTimeOnePkt();
+
+    // Component refers to software component like forwarding
+    public long getStartTimeOneComponent();
+
+    public void updateCumulativeTimeOneComp(long onePktOneCompProcTime_ns,
+                                            int id);
+
+    public void updateCumulativeTimeTotal(long onePktStartTime_ns);
+
+}
diff --git a/src/main/java/net/floodlightcontroller/perfmon/PktinProcessingTime.java b/src/main/java/net/floodlightcontroller/perfmon/PktInProcessingTime.java
similarity index 76%
rename from src/main/java/net/floodlightcontroller/perfmon/PktinProcessingTime.java
rename to src/main/java/net/floodlightcontroller/perfmon/PktInProcessingTime.java
index c0e7dfa03c7c02355d5a9370f465c4d2863bca4c..ea89fd824200f4da76e10827118bec859bf57095 100644
--- a/src/main/java/net/floodlightcontroller/perfmon/PktinProcessingTime.java
+++ b/src/main/java/net/floodlightcontroller/perfmon/PktInProcessingTime.java
@@ -3,7 +3,16 @@
  */
 package net.floodlightcontroller.perfmon;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
 import net.floodlightcontroller.core.IOFMessageListener.FlListenerID;
+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 org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -12,7 +21,8 @@ import org.slf4j.LoggerFactory;
  * @author subrata
  *
  */
-public class PktinProcessingTime  {
+public class PktInProcessingTime
+    implements IFloodlightModule, IPktInProcessingTimeService  {
 
     /***
      * This class contains a set of buckets (called time buckets as the
@@ -40,7 +50,7 @@ public class PktinProcessingTime  {
      */   
 
     protected static  Logger  logger = 
-        LoggerFactory.getLogger(PktinProcessingTime.class);
+        LoggerFactory.getLogger(PktInProcessingTime.class);
 
     /***
      * procTimeMonitoringState: true if monitoring is on, default is false
@@ -85,7 +95,7 @@ public class PktinProcessingTime  {
         }
     }
 
-    protected PerfMonConfigs  perfMonCfgs;
+    protected PerfMonConfigs perfMonCfgs;
     // Maintains the time when the last packet was processed
     protected long lastPktTime_ns; 
     protected long curBucketStartTime;
@@ -96,39 +106,87 @@ public class PktinProcessingTime  {
     private int numBuckets;             // number of time buckets, each 10s long
 
 
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#getLastPktTime_ns()
+     */
+    @Override
     public Long getLastPktTime_ns() {
         return lastPktTime_ns;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#setLastPktTime_ns(java.lang.Long)
+     */
+    @Override
     public void setLastPktTime_ns(Long lastPktTime_ns) {
         this.lastPktTime_ns = lastPktTime_ns;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#getCurBucketStartTime()
+     */
+    @Override
     public long getCurBucketStartTime() {
         return curBucketStartTime;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#setCurBucketStartTime(long)
+     */
+    @Override
     public void setCurBucketStartTime(long curBucketStartTime) {
         this.curBucketStartTime = curBucketStartTime;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#getCtb()
+     */
+    @Override
     public CumulativeTimeBucket getCtb() {
         return ctb;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#setCtb(net.floodlightcontroller.perfmon.CumulativeTimeBucket)
+     */
+    @Override
     public void setCtb(CumulativeTimeBucket ctb) {
         this.ctb = ctb;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#getCtbs()
+     */
+    @Override
     public CircularTimeBucketSet getCtbs() {
         return ctbs;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#setCtbs(net.floodlightcontroller.perfmon.PktinProcessingTime.CircularTimeBucketSet)
+     */
+    @Override
     public void setCtbs(CircularTimeBucketSet ctbs) {
         this.ctbs = ctbs;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#getPerfMonCfgs()
+     */
+    @Override
     public PerfMonConfigs getPerfMonCfgs() {
         return perfMonCfgs;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#setPerfMonCfgs(net.floodlightcontroller.perfmon.PktinProcessingTime.PerfMonConfigs)
+     */
+    @Override
     public void setPerfMonCfgs(PerfMonConfigs perfMonCfgs) {
         this.perfMonCfgs = perfMonCfgs;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#getNumComponents()
+     */
+    @Override
     public int getNumComponents() {
         return numComponents;
     }
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#setNumComponents(int)
+     */
+    @Override
     public void setNumComponents(int numComponents) {
         this.numComponents = numComponents;
     }
@@ -139,18 +197,7 @@ public class PktinProcessingTime  {
     public void setNumBuckets(int numBuckets) {
         this.numBuckets = numBuckets;
     }
-    // Constructor
-    public PktinProcessingTime() {
-        FlListenerID.populateCompNames();
-        setNumComponents(BB_LAST_LISTENER_ID + 1);
-        perfMonCfgs = new PerfMonConfigs();
-        numBuckets = BUCKET_SET_SIZE;
-        ctbs = new CircularTimeBucketSet(getNumComponents(), numBuckets);
-        ctb  = ctbs.timeBucketSet[ctbs.curBucketIdx];
-        ctb.startTime_ms = System.currentTimeMillis();
-        ctb.startTime_ns = System.nanoTime();
-    }
-
+    
     /***
      * BUCKET_SET_SIZE buckets each holding 10s of processing time data, a total
      * of 30*10s = 5mins of processing time data is maintained
@@ -217,6 +264,10 @@ public class PktinProcessingTime  {
         }
     }
 
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#getStartTimeOnePkt()
+     */
+    @Override
     public long getStartTimeOnePkt() {
         if (this.perfMonCfgs.procTimeMonitoringState) {
             long startTime_ns = System.nanoTime();
@@ -227,6 +278,10 @@ public class PktinProcessingTime  {
     }
 
     // Component refers to software component like forwarding
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#getStartTimeOneComponent()
+     */
+    @Override
     public long getStartTimeOneComponent() {
         if (this.perfMonCfgs.procTimeMonitoringState) {
             return System.nanoTime();
@@ -234,6 +289,10 @@ public class PktinProcessingTime  {
         return 0L;
     }
 
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#updateCumulativeTimeOneComp(long, int)
+     */
+    @Override
     public void updateCumulativeTimeOneComp(
                                 long onePktOneCompProcTime_ns, int id) {
         if (this.perfMonCfgs.procTimeMonitoringState) {
@@ -253,6 +312,10 @@ public class PktinProcessingTime  {
         }
     }
 
+    /* (non-Javadoc)
+     * @see net.floodlightcontroller.perfmon.IPktInProcessingTimeService#updateCumulativeTimeTotal(long)
+     */
+    @Override
     public void updateCumulativeTimeTotal(long onePktStartTime_ns) {
         if (this.perfMonCfgs.procTimeMonitoringState) {
             // There is no api to get time in microseconds, milliseconds is 
@@ -374,4 +437,55 @@ public class PktinProcessingTime  {
             ctb.initializeCumulativeTimeBucket(ctb);
         }
     }
+
+    public PktInProcessingTime() {
+        perfMonCfgs = new PerfMonConfigs();
+    }
+    
+    // IFloodlightModule methods
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IPktInProcessingTimeService.class);
+        return l;
+    }
+    
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+        IFloodlightService> m = 
+            new HashMap<Class<? extends IFloodlightService>,
+                        IFloodlightService>();
+        // We are the class that implements the service
+        m.put(IPktInProcessingTimeService.class, this);
+        return m;
+    }
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        // We don't have any dependencies
+        return null;
+    }
+    
+    @Override
+    public void init(FloodlightModuleContext context)
+                                             throws FloodlightModuleException {
+        // no-op
+    }
+    
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // Our 'constructor'
+        FlListenerID.populateCompNames();
+        setNumComponents(BB_LAST_LISTENER_ID + 1);
+        perfMonCfgs = new PerfMonConfigs();
+        numBuckets = BUCKET_SET_SIZE;
+        ctbs = new CircularTimeBucketSet(getNumComponents(), numBuckets);
+        ctb  = ctbs.timeBucketSet[ctbs.curBucketIdx];
+        ctb.startTime_ms = System.currentTimeMillis();
+        ctb.startTime_ns = System.nanoTime();
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/restserver/IRestApiService.java b/src/main/java/net/floodlightcontroller/restserver/IRestApiService.java
new file mode 100644
index 0000000000000000000000000000000000000000..d90679580e0adfbc645368dac58c179ef1490846
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/restserver/IRestApiService.java
@@ -0,0 +1,16 @@
+package net.floodlightcontroller.restserver;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+public interface IRestApiService extends IFloodlightService {
+    /**
+     * Adds a REST API
+     * @param routeable
+     */
+    public void addRestletRoutable(RestletRoutable routable);
+
+    /**
+     * Runs the REST API server
+     */
+    public void run();
+}
diff --git a/src/main/java/net/floodlightcontroller/restserver/RestApiServer.java b/src/main/java/net/floodlightcontroller/restserver/RestApiServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..95a3b8dee730dbc6c21fbc1c733a3111deae3bad
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/restserver/RestApiServer.java
@@ -0,0 +1,158 @@
+package net.floodlightcontroller.restserver;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.restlet.Application;
+import org.restlet.Component;
+import org.restlet.Context;
+import org.restlet.Request;
+import org.restlet.Response;
+import org.restlet.Restlet;
+import org.restlet.data.Protocol;
+import org.restlet.data.Reference;
+import org.restlet.routing.Filter;
+import org.restlet.routing.Router;
+import org.restlet.routing.Template;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+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.web.JacksonCustomConverter;
+
+public class RestApiServer
+    implements IFloodlightModule, IRestApiService {
+    protected static Logger logger = LoggerFactory.getLogger(RestApiServer.class);
+    protected List<RestletRoutable> restlets;
+    protected int restPort = 8080;
+    protected FloodlightModuleContext fmlContext;
+    
+    // ***********
+    // Application
+    // ***********
+    
+    protected class RestApplication extends Application {
+        protected Context context;
+        
+        public RestApplication() {
+            super(new Context());
+            this.context = getContext();
+        }
+        
+        @Override
+        public Restlet createInboundRoot() {
+            Router baseRouter = new Router(context);
+            baseRouter.setDefaultMatchingMode(Template.MODE_STARTS_WITH);
+            for (RestletRoutable rr : restlets) {
+                baseRouter.attach(rr.basePath(), rr.getRestlet(context));
+            }
+
+            Filter slashFilter = new Filter() {            
+                @Override
+                protected int beforeHandle(Request request, Response response) {
+                    Reference ref = request.getResourceRef();
+                    String originalPath = ref.getPath();
+                    if (originalPath.contains("//"))
+                    {
+                        String newPath = originalPath.replaceAll("/+", "/");
+                        ref.setPath(newPath);
+                    }
+                    return Filter.CONTINUE;
+                }
+
+            };
+            slashFilter.setNext(baseRouter);
+            
+            return slashFilter;
+        }
+        
+        public void run(FloodlightModuleContext fmlContext) {
+            // Add everything in the module context to the rest
+            for (Class<? extends IFloodlightService> s : fmlContext.getAllServices()) {
+                context.getAttributes().put(s.getCanonicalName(), 
+                                            fmlContext.getServiceImpl(s));
+            }
+            
+            // Use our custom serializers
+            JacksonCustomConverter.replaceConverter();
+            
+            // Start listening for REST requests
+            try {
+                final Component component = new Component();
+                component.getServers().add(Protocol.HTTP, restPort);
+                component.getDefaultHost().attach(this);
+                component.start();
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+    
+    // ***************
+    // IRestApiService
+    // ***************
+    
+    @Override
+    public void addRestletRoutable(RestletRoutable routable) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Adding REST API routable " 
+                    + routable.getClass().getCanonicalName());
+        }
+        restlets.add(routable);
+    }
+    
+    @Override
+    public void run() {
+        RestApplication restApp = new RestApplication();
+        restApp.run(fmlContext);
+    }
+    
+    // *****************
+    // IFloodlightModule
+    // *****************
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> services =
+                new ArrayList<Class<? extends IFloodlightService>>(1);
+        services.add(IRestApiService.class);
+        return services;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+        IFloodlightService> m = 
+            new HashMap<Class<? extends IFloodlightService>,
+                        IFloodlightService>();
+        m.put(IRestApiService.class, this);
+        return m;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        // We don't have any
+        return null;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+            throws FloodlightModuleException {
+        // This has to be done here since we don't know what order the
+        // startUp methods will be called
+        this.restlets = new ArrayList<RestletRoutable>();
+        this.fmlContext = context;
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext Context) {
+        // no-op
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/web/RestletRoutable.java b/src/main/java/net/floodlightcontroller/restserver/RestletRoutable.java
similarity index 96%
rename from src/main/java/net/floodlightcontroller/core/web/RestletRoutable.java
rename to src/main/java/net/floodlightcontroller/restserver/RestletRoutable.java
index a0dd751dad4a9b577d80a090dee2528f7919a339..cb7dfce8c26e8aa7eb83a1e6f2cc688345d564ff 100644
--- a/src/main/java/net/floodlightcontroller/core/web/RestletRoutable.java
+++ b/src/main/java/net/floodlightcontroller/restserver/RestletRoutable.java
@@ -15,7 +15,7 @@
 *    under the License.
 **/
 
-package net.floodlightcontroller.core.web;
+package net.floodlightcontroller.restserver;
 
 import org.restlet.Context;
 import org.restlet.Restlet;
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
index 37dea45a0b81f49c1f897bb3ae3c6d0e5e71d4c2..1987d0fac511bff6eef9f0c38ea471fee890ec72 100644
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
@@ -1,19 +1,19 @@
 /**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    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.
-**/
+ *    Copyright 2011, Big Switch Networks, Inc. 
+ *    Originally created by David Erickson, Stanford University
+ * 
+ *    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 net.floodlightcontroller.routing;
 
@@ -24,24 +24,25 @@ import java.util.List;
 import java.util.Map;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.util.AppCookie;
 import net.floodlightcontroller.counter.CounterStore;
 import net.floodlightcontroller.counter.CounterValue;
 import net.floodlightcontroller.counter.ICounter;
+import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.devicemanager.DeviceNetworkAddress;
-import net.floodlightcontroller.devicemanager.IDeviceManager;
 import net.floodlightcontroller.devicemanager.IDeviceManagerAware;
+import net.floodlightcontroller.devicemanager.IDeviceManagerService;
 import net.floodlightcontroller.devicemanager.SwitchPort;
 import net.floodlightcontroller.devicemanager.internal.Device;
 import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.routing.IRoutingEngine;
+import net.floodlightcontroller.routing.IRoutingEngineService;
 import net.floodlightcontroller.routing.IRoutingDecision;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.routing.Route;
-import net.floodlightcontroller.topology.ITopology;
+import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.topology.SwitchPortTuple;
 
 import org.openflow.protocol.OFFlowMod;
@@ -58,151 +59,197 @@ import org.openflow.util.U16;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public abstract class ForwardingBase implements IOFMessageListener, IDeviceManagerAware {
-    protected static Logger log = LoggerFactory.getLogger(ForwardingBase.class);
-    
-    public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT=5; // in seconds
-
-    protected IFloodlightProvider floodlightProvider;
-    protected IDeviceManager deviceManager;
-    protected IRoutingEngine routingEngine;
-    protected ITopology topology;
-    protected CounterStore counterStore;
-    
+public abstract class ForwardingBase implements
+    IOFMessageListener,
+    IDeviceManagerAware {
+    protected static Logger log =
+            LoggerFactory.getLogger(ForwardingBase.class);
+
+    public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT = 5; // in seconds
+
+    protected IFloodlightProviderService floodlightProvider;
+    protected IDeviceManagerService deviceManager;
+    protected IRoutingEngineService routingEngine;
+    protected ITopologyService topology;
+    protected ICounterStoreService counterStore;
+
     // flow-mod - for use in the cookie
-    public static final int FORWARDING_APP_ID = 2; // TODO: This must be managed by a global APP_ID class
+    public static final int FORWARDING_APP_ID = 2; // TODO: This must be managed
+                                                   // by a global APP_ID class
 
     // Comparator for sorting by SwitchCluster
     public Comparator<SwitchPort> clusterIdComparator =
             new Comparator<SwitchPort>() {
-        @Override
-        public int compare(SwitchPort d1, SwitchPort d2) {
-            Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches();
-            IOFSwitch sw1 = switches.get(d1.getSwitchDPID());
-            IOFSwitch sw2 = switches.get(d2.getSwitchDPID());
-
-            Long d1ClusterId = sw1.getSwitchClusterId();
-            Long d2ClusterId = sw2.getSwitchClusterId();
-            
-            return d1ClusterId.compareTo(d2ClusterId);
-        }
-    };
-    
+                @Override
+                public int compare(SwitchPort d1, SwitchPort d2) {
+                    Map<Long, IOFSwitch> switches =
+                            floodlightProvider.getSwitches();
+                    IOFSwitch sw1 = switches.get(d1.getSwitchDPID());
+                    IOFSwitch sw2 = switches.get(d2.getSwitchDPID());
+
+                    Long d1ClusterId = sw1.getSwitchClusterId();
+                    Long d2ClusterId = sw2.getSwitchClusterId();
+
+                    return d1ClusterId.compareTo(d2ClusterId);
+                }
+            };
+
     public void startUp() {
+        deviceManager.addListener(this);
         floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
     }
 
-    public void shutDown() {
-        floodlightProvider.removeOFMessageListener(OFType.PACKET_IN, this);
-    }
-
     @Override
     public String getName() {
         return "forwarding";
     }
-    
+
     @Override
     public int getId() {
         return FlListenerID.FORWARDINGBASE;
     }
 
     /**
-      * All subclasses must define this function if they want any specific forwarding action
-     * @param sw Switch that the packet came in from
-     * @param pi The packet that came in
-     * @param decision Any decision made by a policy engine
+     * All subclasses must define this function if they want any specific
+     * forwarding action
+     * 
+     * @param sw
+     *            Switch that the packet came in from
+     * @param pi
+     *            The packet that came in
+     * @param decision
+     *            Any decision made by a policy engine
      */
-    public abstract Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx);
+    public abstract Command
+            processPacketInMessage(IOFSwitch sw, OFPacketIn pi,
+                                   IRoutingDecision decision,
+                                   FloodlightContext cntx);
 
     @Override
-    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
+    public Command receive(IOFSwitch sw, OFMessage msg,
+                           FloodlightContext cntx) {
         switch (msg.getType()) {
             case PACKET_IN:
                 IRoutingDecision decision = null;
-                if (cntx != null) decision = 
-                    IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION); 
-                
-                return this.processPacketInMessage(sw, (OFPacketIn) msg, decision, cntx);
+                if (cntx != null)
+                                 decision =
+                                         IRoutingDecision.rtStore.get(cntx,
+                                                                      IRoutingDecision.CONTEXT_DECISION);
+
+                return this.processPacketInMessage(sw,
+                                                   (OFPacketIn) msg,
+                                                   decision,
+                                                   cntx);
         }
-        log.error("received an unexpected message {} from switch {}", msg, sw);
+        log.error("received an unexpected message {} from switch {}",
+                  msg,
+                  sw);
         return Command.CONTINUE;
     }
 
     private void updateCounterStore(IOFSwitch sw, OFFlowMod flowMod) {
         if (counterStore != null) {
             String packetName = flowMod.getType().toClass().getName();
-            packetName = packetName.substring(packetName.lastIndexOf('.')+1);
+            packetName =
+                    packetName.substring(packetName.lastIndexOf('.') + 1);
             // flowmod is per switch. portid = -1
-            String counterName = CounterStore.createCounterName(sw.getStringId(), -1, packetName);
+            String counterName =
+                    CounterStore.createCounterName(sw.getStringId(),
+                                                   -1,
+                                                   packetName);
             try {
                 ICounter counter = counterStore.getCounter(counterName);
                 if (counter == null) {
-                    counter = counterStore.createCounter(counterName, CounterValue.CounterType.LONG);
+                    counter =
+                            counterStore.createCounter(counterName,
+                                                       CounterValue.CounterType.LONG);
                 }
                 counter.increment();
-            }
-            catch (IllegalArgumentException e) {
+            } catch (IllegalArgumentException e) {
                 log.error("Invalid Counter, " + counterName);
             }
         }
     }
-    
+
     /**
      * Push routes from back to front
-     * @param route Route to push
-     * @param match OpenFlow fields to match on
-     * @param srcSwPort Source switch port for the first hop
-     * @param dstSwPort Destination switch port for final hop
-     * @param bufferId BufferId of the original PacketIn
-     * @return srcSwitchIincluded True if the source switch is included in this route
+     * 
+     * @param route
+     *            Route to push
+     * @param match
+     *            OpenFlow fields to match on
+     * @param srcSwPort
+     *            Source switch port for the first hop
+     * @param dstSwPort
+     *            Destination switch port for final hop
+     * @param bufferId
+     *            BufferId of the original PacketIn
+     * @return srcSwitchIincluded True if the source switch is included in this
+     *         route
      */
-    public boolean pushRoute(Route route, OFMatch match, 
-                             Integer wildcard_hints,
-                             SwitchPort srcSwPort,
-                             SwitchPort dstSwPort,
-                             int bufferId,
-                             IOFSwitch srcSwitch, 
-                             OFPacketIn pi, 
+    public boolean pushRoute(Route route, OFMatch match,
+                             Integer wildcard_hints, SwitchPort srcSwPort,
+                             SwitchPort dstSwPort, int bufferId,
+                             IOFSwitch srcSwitch, OFPacketIn pi,
                              FloodlightContext cntx,
                              boolean reqeustFlowRemovedNotifn) {
         long cookie = AppCookie.makeCookie(FORWARDING_APP_ID, 0);
-        return pushRoute(route, match, wildcard_hints, srcSwPort, dstSwPort, 
-                bufferId, srcSwitch, pi, cookie, cntx, reqeustFlowRemovedNotifn);
+        return pushRoute(route,
+                         match,
+                         wildcard_hints,
+                         srcSwPort,
+                         dstSwPort,
+                         bufferId,
+                         srcSwitch,
+                         pi,
+                         cookie,
+                         cntx,
+                         reqeustFlowRemovedNotifn);
     }
-    
+
     /**
      * Push routes from back to front
-     * @param route Route to push
-     * @param match OpenFlow fields to match on
-     * @param srcSwPort Source switch port for the first hop
-     * @param dstSwPort Destination switch port for final hop
-     * @param bufferId BufferId of the original PacketIn
-     * @param cookie The cookie to set in each flow_mod
-     * @return srcSwitchIincluded True if the source switch is included in this route
+     * 
+     * @param route
+     *            Route to push
+     * @param match
+     *            OpenFlow fields to match on
+     * @param srcSwPort
+     *            Source switch port for the first hop
+     * @param dstSwPort
+     *            Destination switch port for final hop
+     * @param bufferId
+     *            BufferId of the original PacketIn
+     * @param cookie
+     *            The cookie to set in each flow_mod
+     * @return srcSwitchIincluded True if the source switch is included in this
+     *         route
      */
-    public boolean pushRoute(Route route, OFMatch match, Integer wildcard_hints,
-                             SwitchPort srcSwPort,
+    public boolean pushRoute(Route route, OFMatch match,
+                             Integer wildcard_hints, SwitchPort srcSwPort,
                              SwitchPort dstSwPort, int bufferId,
-                             IOFSwitch srcSwitch, OFPacketIn pi, long cookie, 
-                             FloodlightContext cntx,
+                             IOFSwitch srcSwitch, OFPacketIn pi,
+                             long cookie, FloodlightContext cntx,
                              boolean reqeustFlowRemovedNotifn) {
 
         boolean srcSwitchIncluded = false;
-        OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
+        OFFlowMod fm =
+                (OFFlowMod) floodlightProvider.getOFMessageFactory()
+                                              .getMessage(OFType.FLOW_MOD);
         OFActionOutput action = new OFActionOutput();
         List<OFAction> actions = new ArrayList<OFAction>();
         actions.add(action);
-        fm.setIdleTimeout((short)5)
-            .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-            .setCookie(cookie)
-            .setMatch(match)
-            .setActions(actions)
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
+        fm.setIdleTimeout((short) 5)
+          .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+          .setCookie(cookie)
+          .setMatch(match)
+          .setActions(actions)
+          .setLengthU(OFFlowMod.MINIMUM_LENGTH
+                  + OFActionOutput.MINIMUM_LENGTH);
 
         Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches();
         IOFSwitch sw = switches.get(dstSwPort.getSwitchDPID());
-        ((OFActionOutput)fm.getActions().get(0)).
-            setPort((short)dstSwPort.getPort());
+        ((OFActionOutput) fm.getActions().get(0)).setPort((short) dstSwPort.getPort());
 
         if (route != null) {
             for (int routeIndx = route.getPath().size() - 1; routeIndx >= 0; --routeIndx) {
@@ -213,14 +260,22 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
                     updateCounterStore(sw, fm);
                     if (log.isDebugEnabled()) {
                         log.debug("Pushing Route flowmod routeIndx={} sw={} inPort={} outPort={}",
-                                  new Object[] { routeIndx, sw, fm.getMatch().getInputPort(), 
-                                                 ((OFActionOutput)fm.getActions().get(0)).getPort() });
+                                  new Object[] {
+                                                routeIndx,
+                                                sw,
+                                                fm.getMatch().getInputPort(),
+                                                ((OFActionOutput) fm.getActions()
+                                                                    .get(0)).getPort() });
                     }
                     sw.write(fm, cntx);
 
                     // Push the packet out the source switch
                     if (sw.getId() == srcSwitch.getId()) {
-                        pushPacket(srcSwitch, match, pi, ((OFActionOutput)fm.getActions().get(0)).getPort(), cntx);
+                        pushPacket(srcSwitch,
+                                   match,
+                                   pi,
+                                   ((OFActionOutput) fm.getActions().get(0)).getPort(),
+                                   cntx);
                         srcSwitchIncluded = true;
                     }
                 } catch (IOException e) {
@@ -233,34 +288,43 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
                 }
 
                 // setup for the next loop iteration
-                ((OFActionOutput)fm.getActions().get(0)).setPort(link.getOutPort());
+                ((OFActionOutput) fm.getActions().get(0)).setPort(link.getOutPort());
                 if (routeIndx > 0) {
-                    sw = floodlightProvider.getSwitches().get(route.getPath().get(routeIndx-1).getDst());
+                    sw =
+                            floodlightProvider.getSwitches()
+                                              .get(route.getPath()
+                                                        .get(routeIndx - 1)
+                                                        .getDst());
                 } else {
-                    sw = floodlightProvider.getSwitches().get(route.getId().getSrc());
+                    sw =
+                            floodlightProvider.getSwitches()
+                                              .get(route.getId().getSrc());
                 }
                 if (sw == null) {
                     if (log.isWarnEnabled()) {
                         log.warn("Unable to push route, switch at DPID {} not available",
-                                (routeIndx > 0) ? HexString.toHexString(route.getPath()
-                                        .get(routeIndx - 1).getDst()) : HexString
-                                        .toHexString(route.getId().getSrc()));
+                                 (routeIndx > 0)
+                                         ? HexString.toHexString(route.getPath()
+                                                                      .get(routeIndx - 1)
+                                                                      .getDst())
+                                         : HexString.toHexString(route.getId()
+                                                                      .getSrc()));
                     }
                     return srcSwitchIncluded;
                 }
             }
         }
-     
+
         // set the original match for the first switch, and buffer id
         fm.setMatch(match);
         fm.setBufferId(bufferId);
         fm.setMatch(wildcard(match, sw, wildcard_hints));
-        fm.getMatch().setInputPort((short)srcSwPort.getPort());
-        // Set the flag to request flow-mod removal notifications only for the 
+        fm.getMatch().setInputPort((short) srcSwPort.getPort());
+        // Set the flag to request flow-mod removal notifications only for the
         // source switch. The removal message is used to maintain the flow
         // cache. Don't set the flag for ARP messages - TODO generalize check
-        if ((reqeustFlowRemovedNotifn) &&
-            (match.getDataLayerType() != Ethernet.TYPE_ARP)) {
+        if ((reqeustFlowRemovedNotifn)
+                && (match.getDataLayerType() != Ethernet.TYPE_ARP)) {
             fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
             match.setWildcards(fm.getMatch().getWildcards());
         }
@@ -268,15 +332,21 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
         updateCounterStore(sw, fm);
         try {
             log.debug("pushRoute flowmod sw={} inPort={} outPort={}",
-                      new Object[] { sw, fm.getMatch().getInputPort(), 
-                                    ((OFActionOutput)fm.getActions().get(0)).getPort() });
+                      new Object[] {
+                                    sw,
+                                    fm.getMatch().getInputPort(),
+                                    ((OFActionOutput) fm.getActions().get(0)).getPort() });
             log.info("Flow mod sent: Wildcard={} match={}",
-                    Integer.toHexString(fm.getMatch().getWildcards()),
-                    fm.getMatch().toString());
+                     Integer.toHexString(fm.getMatch().getWildcards()),
+                     fm.getMatch().toString());
             sw.write(fm, cntx);
 
             if (sw.getId() == srcSwitch.getId()) {
-                pushPacket(srcSwitch, match, pi, ((OFActionOutput)fm.getActions().get(0)).getPort(), cntx);
+                pushPacket(srcSwitch,
+                           match,
+                           pi,
+                           ((OFActionOutput) fm.getActions().get(0)).getPort(),
+                           cntx);
                 srcSwitchIncluded = true;
             }
             match = fm.getMatch();
@@ -287,37 +357,43 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
         return srcSwitchIncluded;
     }
 
-    protected OFMatch wildcard(OFMatch match, IOFSwitch sw, Integer wildcard_hints) {
+    protected OFMatch wildcard(OFMatch match, IOFSwitch sw,
+                               Integer wildcard_hints) {
         if (wildcard_hints != null) {
             return match.clone().setWildcards(wildcard_hints.intValue());
         }
         return match.clone();
     }
 
-    public void pushPacket(IOFSwitch sw, OFMatch match, OFPacketIn pi, short outport, FloodlightContext cntx) {
-        
+    public void pushPacket(IOFSwitch sw, OFMatch match, OFPacketIn pi,
+                           short outport, FloodlightContext cntx) {
+
         if (pi == null) {
             return;
         }
-        
+
         if (log.isDebugEnabled()) {
-            log.debug("PacketOut srcSwitch={} match={} pi={}", new Object[] {sw, match, pi});
+            log.debug("PacketOut srcSwitch={} match={} pi={}",
+                      new Object[] { sw, match, pi });
         }
-        
-        OFPacketOut po = (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
+
+        OFPacketOut po =
+                (OFPacketOut) floodlightProvider.getOFMessageFactory()
+                                                .getMessage(OFType.PACKET_OUT);
 
         // set actions
         List<OFAction> actions = new ArrayList<OFAction>();
         actions.add(new OFActionOutput(outport, (short) 0));
 
         po.setActions(actions)
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
-        short poLength = (short)(po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
-        
+          .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
+        short poLength =
+                (short) (po.getActionsLength() + OFPacketOut.MINIMUM_LENGTH);
+
         // set buffer_id, in_port
         po.setBufferId(pi.getBufferId());
         po.setInPort(pi.getInPort());
-        
+
         // set data - only if buffer_id == -1
         if (pi.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
             byte[] packetData = pi.getPacketData();
@@ -326,7 +402,7 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
         }
 
         po.setLength(poLength);
-        
+
         try {
             sw.write(po, cntx);
         } catch (IOException e) {
@@ -334,40 +410,44 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
         }
     }
 
-    public static boolean blockHost(IFloodlightProvider floodlightProvider, 
-            SwitchPortTuple sw_tup, long host_mac, 
-            short hardTimeout) {
+    public static boolean
+            blockHost(IFloodlightProviderService floodlightProvider,
+                      SwitchPortTuple sw_tup, long host_mac,
+                      short hardTimeout) {
 
         if ((sw_tup == null) || sw_tup.getSw() == null) {
             return false;
         }
 
         IOFSwitch sw = sw_tup.getSw();
-        short inputPort = sw_tup.getPort().shortValue();    
+        short inputPort = sw_tup.getPort().shortValue();
         log.debug("blockHost sw={} port={} mac={}",
-                new Object[] { sw, sw_tup.getPort(), new Long(host_mac) });
+                  new Object[] { sw, sw_tup.getPort(), new Long(host_mac) });
 
         // Create flow-mod based on packet-in and src-switch
-        OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
+        OFFlowMod fm =
+                (OFFlowMod) floodlightProvider.getOFMessageFactory()
+                                              .getMessage(OFType.FLOW_MOD);
         OFMatch match = new OFMatch();
-        List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to drop
+        List<OFAction> actions = new ArrayList<OFAction>(); // Set no action to
+                                                            // drop
         match.setDataLayerSource(Ethernet.toByteArray(host_mac))
-            .setInputPort(inputPort)
-            .setWildcards(OFMatch.OFPFW_ALL & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_IN_PORT);
+             .setInputPort(inputPort)
+             .setWildcards(OFMatch.OFPFW_ALL & ~OFMatch.OFPFW_DL_SRC
+                     & ~OFMatch.OFPFW_IN_PORT);
         fm.setCookie(AppCookie.makeCookie(FORWARDING_APP_ID, 0))
-            .setHardTimeout((short)hardTimeout)
-            .setIdleTimeout((short)5)
-            .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-            .setMatch(match)
-            .setActions(actions)
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH);
+          .setHardTimeout((short) hardTimeout)
+          .setIdleTimeout((short) 5)
+          .setBufferId(OFPacketOut.BUFFER_ID_NONE)
+          .setMatch(match)
+          .setActions(actions)
+          .setLengthU(OFFlowMod.MINIMUM_LENGTH); // +OFActionOutput.MINIMUM_LENGTH);
 
         try {
             log.debug("write drop flow-mod sw={} match={} flow-mod={}",
-                       new Object[] {sw, match, fm});
+                      new Object[] { sw, match, fm });
             sw.write(fm, null);
-        }
-        catch (IOException e) {
+        } catch (IOException e) {
             log.error("Failure writing deny flow mod", e);
             return false;
         }
@@ -376,38 +456,44 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
     }
 
     /**
-     * @param floodlightProvider the floodlightProvider to set
+     * @param floodlightProvider
+     *            the floodlightProvider to set
      */
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
+    public
+            void
+            setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
     }
 
     /**
-     * @param routingEngine the routingEngine to set
+     * @param routingEngine
+     *            the routingEngine to set
      */
-    public void setRoutingEngine(IRoutingEngine routingEngine) {
+    public void setRoutingEngine(IRoutingEngineService routingEngine) {
         this.routingEngine = routingEngine;
     }
 
     /**
-     * @param deviceManager the deviceManager to set
+     * @param deviceManager
+     *            the deviceManager to set
      */
-    public void setDeviceManager(IDeviceManager deviceManager) {
+    public void setDeviceManager(IDeviceManagerService deviceManager) {
         this.deviceManager = deviceManager;
     }
 
     /**
-     * @param topology the topology to set
+     * @param topology
+     *            the topology to set
      */
-    public void setTopology(ITopology topology) {
+    public void setTopology(ITopologyService topology) {
         this.topology = topology;
     }
 
-    public CounterStore getCounterStore() {
+    public ICounterStoreService getCounterStore() {
         return counterStore;
     }
 
-    public void setCounterStore(CounterStore counterStore) {
+    public void setCounterStore(ICounterStoreService counterStore) {
         this.counterStore = counterStore;
     }
 
@@ -423,40 +509,41 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
 
     @Override
     public void deviceMoved(Device device, IOFSwitch oldSw, Short oldPort,
-            IOFSwitch sw, Short port) {
+                            IOFSwitch sw, Short port) {
         // Build flow mod to delete based on destination mac == device mac
         OFMatch match = new OFMatch();
         match.setDataLayerDestination(Ethernet.toByteArray(device.getMACAddress()));
         match.setWildcards(OFMatch.OFPFW_ALL ^ OFMatch.OFPFW_DL_DST);
-        OFMessage fm = ((OFFlowMod) floodlightProvider.getOFMessageFactory()
-            .getMessage(OFType.FLOW_MOD))
-            .setCommand(OFFlowMod.OFPFC_DELETE)
-            .setOutPort((short) OFPort.OFPP_NONE.getValue())
-            .setMatch(match)
-            .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH));
+        OFMessage fm =
+                ((OFFlowMod) floodlightProvider.getOFMessageFactory()
+                                               .getMessage(OFType.FLOW_MOD)).setCommand(OFFlowMod.OFPFC_DELETE)
+                                                                            .setOutPort((short) OFPort.OFPP_NONE.getValue())
+                                                                            .setMatch(match)
+                                                                            .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH));
 
         // Flush to all switches
         for (IOFSwitch outSw : floodlightProvider.getSwitches().values()) {
             try {
                 outSw.write(fm, null);
             } catch (IOException e) {
-                log.error("Failure sending flow mod delete for moved device", e);
+                log.error("Failure sending flow mod delete for moved device",
+                          e);
             }
         }
     }
 
     @Override
     public void deviceNetworkAddressAdded(Device device,
-            DeviceNetworkAddress address) {
-        
+                                          DeviceNetworkAddress address) {
+
     }
 
     @Override
     public void deviceNetworkAddressRemoved(Device device,
-            DeviceNetworkAddress address) {
-        
+                                            DeviceNetworkAddress address) {
+
     }
-    
+
     @Override
     public void deviceVlanChanged(Device device) {
 
@@ -464,8 +551,7 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
 
     @Override
     public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        return (type.equals(OFType.PACKET_IN) &&
-                (name.equals("topology") || name.equals("devicemanager")));
+        return (type.equals(OFType.PACKET_IN) && (name.equals("topology") || name.equals("devicemanager")));
     }
 
     @Override
diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingEngine.java b/src/main/java/net/floodlightcontroller/routing/IRoutingEngineService.java
similarity index 94%
rename from src/main/java/net/floodlightcontroller/routing/IRoutingEngine.java
rename to src/main/java/net/floodlightcontroller/routing/IRoutingEngineService.java
index 1a04ebbab7a07af154087e65139b259c1aef388b..768d242646b8122a0cc2264d4a6723d18184722a 100644
--- a/src/main/java/net/floodlightcontroller/routing/IRoutingEngine.java
+++ b/src/main/java/net/floodlightcontroller/routing/IRoutingEngineService.java
@@ -18,6 +18,7 @@
 package net.floodlightcontroller.routing;
 
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.routing.Route;
 
 /**
@@ -25,7 +26,7 @@ import net.floodlightcontroller.routing.Route;
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public interface IRoutingEngine {
+public interface IRoutingEngineService extends IFloodlightService {
     public Route getRoute(IOFSwitch src, IOFSwitch dst);
 
     public Route getRoute(Long srcDpid, Long dstDpid);
diff --git a/src/main/java/net/floodlightcontroller/routing/dijkstra/RoutingImpl.java b/src/main/java/net/floodlightcontroller/routing/dijkstra/RoutingImpl.java
index 2f8553ef0f79fe0e81e2e157cabe24899dfb17ee..ff1cf1d16e551374f6adbdd6099bc19f538e80c7 100644
--- a/src/main/java/net/floodlightcontroller/routing/dijkstra/RoutingImpl.java
+++ b/src/main/java/net/floodlightcontroller/routing/dijkstra/RoutingImpl.java
@@ -20,8 +20,11 @@
  */
 package net.floodlightcontroller.routing.dijkstra;
 
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.Map;
 import java.util.PriorityQueue;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -31,19 +34,25 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 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.routing.BroadcastTree;
-import net.floodlightcontroller.routing.IRoutingEngine;
+import net.floodlightcontroller.routing.IRoutingEngineService;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.routing.RouteId;
-import net.floodlightcontroller.topology.ITopologyAware;
+import net.floodlightcontroller.topology.ITopologyListener;
+import net.floodlightcontroller.topology.ITopologyService;
 
 /**
  * Floodlight component to find shortest paths based on dijkstra's algorithm
  *
  * @author Mandeep Dhami (mandeep.dhami@bigswitch.com)
  */
-public class RoutingImpl implements IRoutingEngine, ITopologyAware {
+public class RoutingImpl 
+    implements IRoutingEngineService, ITopologyListener, IFloodlightModule {
     
     public static final int MAX_LINK_WEIGHT = 1000;
     public static final int MAX_PATH_WEIGHT = Integer.MAX_VALUE - MAX_LINK_WEIGHT - 1;
@@ -55,17 +64,7 @@ public class RoutingImpl implements IRoutingEngine, ITopologyAware {
     protected HashMap<Long, HashMap<Long, Link>> nexthoplinkmaps;
     protected HashMap<Long, HashMap<Long, Long>> nexthopnodemaps;
     protected LRUHashMap<RouteId, Route> pathcache;
-    
-    public RoutingImpl() {                
-        lock = new ReentrantReadWriteLock();
-
-        network = new HashMap<Long, HashMap<Link, Link>>();
-        nexthoplinkmaps = new HashMap<Long, HashMap<Long, Link>>();
-        nexthopnodemaps = new HashMap<Long, HashMap<Long, Long>>();
-        pathcache = new LRUHashMap<RouteId, Route>(PATH_CACHE_SIZE);
-        
-        log.info("Initialized Dijkstra RouterImpl");
-    }
+    protected ITopologyService topology;
    
     @Override
     public boolean routeExists(Long srcId, Long dstId) {
@@ -121,7 +120,9 @@ public class RoutingImpl implements IRoutingEngine, ITopologyAware {
         }
 
         lock.readLock().unlock();
-        log.debug("getRoute: {} -> {}", id, result);
+        if (log.isDebugEnabled()) {
+            log.debug("getRoute: {} -> {}", id, result);
+        }
         return result;
     }
 
@@ -152,7 +153,9 @@ public class RoutingImpl implements IRoutingEngine, ITopologyAware {
 
         Route result = null;
         if (path != null) result = new Route(id, path);
-        log.debug("buildroute: {}", result);
+        if (log.isDebugEnabled()) {
+            log.debug("buildroute: {}", result);
+        }
         return result;
     }
 
@@ -321,10 +324,7 @@ public class RoutingImpl implements IRoutingEngine, ITopologyAware {
         BroadcastTree ret = new BroadcastTree(nexthoplinks, nexthopnodes);
         return ret;
     }
-
-    public void startUp() {}
-    public void shutDown() {}
-
+    
     @Override
     public void clusterMerged() {
         // no-op
@@ -335,4 +335,50 @@ public class RoutingImpl implements IRoutingEngine, ITopologyAware {
         // Ignored by RoutingImpl
     }
 
+    // IFloodlightModule
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IRoutingEngineService.class);
+        return l;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+        IFloodlightService> m = 
+            new HashMap<Class<? extends IFloodlightService>,
+                        IFloodlightService>();
+        // We are the class that implements the service
+        m.put(IRoutingEngineService.class, this);
+        return m;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(ITopologyService.class);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+                                             throws FloodlightModuleException {
+        topology = context.getServiceImpl(ITopologyService.class);
+        lock = new ReentrantReadWriteLock();
+        network = new HashMap<Long, HashMap<Link, Link>>();
+        nexthoplinkmaps = new HashMap<Long, HashMap<Long, Link>>();
+        nexthopnodemaps = new HashMap<Long, HashMap<Long, Long>>();
+        pathcache = new LRUHashMap<RouteId, Route>(PATH_CACHE_SIZE);
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // Register to get updates from topology
+        topology.addListener(this);
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
similarity index 95%
rename from src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusher.java
rename to src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
index 9962b391bd2f1e627667435e5ef4c9ba6f210edf..4d3e572d802b4d19e1e1f3fce50275d9b64158d9 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusher.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
@@ -21,13 +21,15 @@ import java.util.HashMap;
 import java.util.List;
 
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.IFloodlightService;
+
 import org.openflow.protocol.OFFlowMod;
 
 /**
  * Represents the parts of the staticflowentry that are exposed as a service to other floodlight apps
  *
  */
-public interface IStaticFlowEntryPusher {
+public interface IStaticFlowEntryPusherService extends IFloodlightService {
     /**
      * Pushes a flow-mod to this switch as a one-time push
      * 
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
index b1ca17b463d393de02fb872cc04661842a982dea..15cb5309156a89a299868ffad9fc8481bcac18db 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
@@ -24,16 +24,22 @@ package net.floodlightcontroller.staticflowentry;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchListener;
+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 org.codehaus.jackson.JsonParseException;
 import org.codehaus.jackson.JsonParser;
@@ -51,7 +57,8 @@ import org.openflow.util.U16;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class StaticFlowEntryPusher implements IStaticFlowEntryPusher, IOFSwitchListener {
+public class StaticFlowEntryPusher 
+    implements IStaticFlowEntryPusherService, IOFSwitchListener, IFloodlightModule {
 
     // Utility data structure
     private class FlowModFields {
@@ -63,32 +70,18 @@ public class StaticFlowEntryPusher implements IStaticFlowEntryPusher, IOFSwitchL
     }
 
     protected static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusher.class);
-    protected IFloodlightProvider floodlightProvider;
+    protected IFloodlightProviderService floodlightProvider;
 
     protected ArrayList<String> flowmodList;
     protected ArrayList<IOFSwitch> activeSwitches;
     protected HashMap<Long, HashMap<String, OFFlowMod>> flowmods;
     protected int pushEntriesFrequency = 25000; // milliseconds
     protected Runnable pushEntriesTimer;
-
-    public StaticFlowEntryPusher() {
-        flowmodList = new ArrayList<String>();
-        flowmods = new HashMap<Long, HashMap<String, OFFlowMod>>(); 
-        activeSwitches = new ArrayList<IOFSwitch>();
-    }
     
     @Override
     public String getName() {
         return "staticflowentry";
     }
-
-    public IFloodlightProvider getFloodlightProvider() {
-        return floodlightProvider;
-    }
-
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
-        this.floodlightProvider = floodlightProvider;
-    }
     
     /**
      * Gets the static flow entry push interval
@@ -604,7 +597,68 @@ public class StaticFlowEntryPusher implements IStaticFlowEntryPusher, IOFSwitchL
         return entryCookie;
     }
 
-    public void startUp() {
+    /**
+     * Pushes all entries associated with all switches (from the store)
+     */
+    protected void pushAllEntries() {
+        for (IOFSwitch sw : activeSwitches) {
+            for (OFFlowMod fm : getEntries(sw).values()) {
+                pushEntry(sw, fm);
+            }
+        }
+    }
+    
+    public void shutDown() {
+        log.info("shutdown");
+        pushEntriesTimer = null;
+        floodlightProvider.removeOFSwitchListener(this);
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IStaticFlowEntryPusherService.class);
+        return l;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+            IFloodlightService> m = 
+            new HashMap<Class<? extends IFloodlightService>,
+                    IFloodlightService>();
+        // We are the class that implements the service
+        m.put(IStaticFlowEntryPusherService.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);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+            throws FloodlightModuleException {
+        // Wire up all our dependencies
+        floodlightProvider = 
+                context.getServiceImpl(IFloodlightProviderService.class);
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // This is our 'constructor'
+        if (log.isDebugEnabled()) {
+            log.debug("Starting " + this.getClass().getCanonicalName());
+        }
+        flowmodList = new ArrayList<String>();
+        flowmods = new HashMap<Long, HashMap<String, OFFlowMod>>(); 
+        activeSwitches = new ArrayList<IOFSwitch>();
         floodlightProvider.addOFSwitchListener(this);        
         pushEntriesTimer = new Runnable() {
             @Override
@@ -624,21 +678,4 @@ public class StaticFlowEntryPusher implements IStaticFlowEntryPusher, IOFSwitchL
                                                            pushEntriesFrequency, 
                                                            TimeUnit.MILLISECONDS);
     }
-
-    /**
-     * Pushes all entries associated with all switches (from the store)
-     */
-    protected void pushAllEntries() {
-        for (IOFSwitch sw : activeSwitches) {
-            for (OFFlowMod fm : getEntries(sw).values()) {
-                pushEntry(sw, fm);
-            }
-        }
-    }
-    
-    public void shutDown() {
-        log.info("shutdown");
-        pushEntriesTimer = null;
-        floodlightProvider.removeOFSwitchListener(this);
-    }
 }
diff --git a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
index 2c5bd128e551b4300291e63c69edefeba265547d..e80c86bb0a7e1e19eb02791a0289c43a06548c80 100644
--- a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
@@ -18,6 +18,8 @@
 package net.floodlightcontroller.storage;
 
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -27,14 +29,23 @@ import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
+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.counter.ICounter;
 import net.floodlightcontroller.counter.CounterStore;
+import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.counter.CounterValue.CounterType;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.storage.web.StorageWebRoutable;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public abstract class AbstractStorageSource implements IStorageSource {
+public abstract class AbstractStorageSource 
+    implements IStorageSourceService, IFloodlightModule {
     protected static Logger logger = LoggerFactory.getLogger(AbstractStorageSource.class);
 
     // Shared instance of the executor to use to execute the storage tasks.
@@ -52,13 +63,16 @@ public abstract class AbstractStorageSource implements IStorageSource {
     protected final static String STORAGE_DELETE_COUNTER_NAME = "StorageDelete";
     
     protected Set<String> allTableNames = new CopyOnWriteArraySet<String>();
-    protected CounterStore counterStore;
+    protected ICounterStoreService counterStore;
     protected ExecutorService executorService = defaultExecutorService;
     protected IStorageExceptionHandler exceptionHandler;
 
     private Map<String, Set<IStorageSourceListener>> listeners =
         new ConcurrentHashMap<String, Set<IStorageSourceListener>>();
 
+    // Our dependencies
+    protected IRestApiService restApi = null;
+    
     abstract class StorageCallable<V> implements Callable<V> {
         public V call() {
             try {
@@ -93,12 +107,6 @@ public abstract class AbstractStorageSource implements IStorageSource {
         this.executorService = defaultExecutorService;
     }
 
-    public AbstractStorageSource(ExecutorService executorService,
-            IStorageExceptionHandler exceptionHandler) {
-        setExecutorService(executorService);
-        this.exceptionHandler = exceptionHandler;
-    }
-
     public void setExecutorService(ExecutorService executorService) {
         this.executorService = (executorService != null) ?
                 executorService : defaultExecutorService;
@@ -460,4 +468,47 @@ public abstract class AbstractStorageSource implements IStorageSource {
             notifyListeners(notification);
     }
     
+    // IFloodlightModule
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IStorageSourceService.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(IStorageSourceService.class, this);
+        return m;
+    }
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IRestApiService.class);
+        l.add(ICounterStoreService.class);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+            throws FloodlightModuleException {
+        restApi =
+           context.getServiceImpl(IRestApiService.class);
+        counterStore =
+            context.getServiceImpl(ICounterStoreService.class);
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        restApi.addRestletRoutable(new StorageWebRoutable());
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/storage/IStorageSource.java b/src/main/java/net/floodlightcontroller/storage/IStorageSourceService.java
similarity index 97%
rename from src/main/java/net/floodlightcontroller/storage/IStorageSource.java
rename to src/main/java/net/floodlightcontroller/storage/IStorageSourceService.java
index d4d1195e1c7efb6c5f85665fd52e0c5055422690..de87476418d5f67ce801f66a4d150f60e8a1f980 100644
--- a/src/main/java/net/floodlightcontroller/storage/IStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/IStorageSourceService.java
@@ -22,9 +22,10 @@ import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.Future;
 
-import net.floodlightcontroller.perfmon.PktinProcessingTime;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
 
-public interface IStorageSource {
+public interface IStorageSourceService extends IFloodlightService {
 
     /** Set the column to be used as the primary key for a table. This should
      * be guaranteed to be unique for all of the rows in the table, although the
@@ -329,5 +330,5 @@ public interface IStorageSource {
      */
     public void notifyListeners(List<StorageSourceNotification> notifications);
 
-    public void setPktinProcessingTime(PktinProcessingTime pktinProcessingTime);
+    public void setPktinProcessingTime(IPktInProcessingTimeService pktinProcessingTime);
 }
diff --git a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
index 181bd9fd12d6041b150f691bab6264fbb17b9609..a122a05d298ce0694f877e928e98ac160fecac17 100644
--- a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
@@ -17,7 +17,8 @@
 
 package net.floodlightcontroller.storage.memory;
 
-import net.floodlightcontroller.perfmon.PktinProcessingTime;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.perfmon.IPktInProcessingTimeService;
 import net.floodlightcontroller.storage.nosql.NoSqlStorageSource;
 import net.floodlightcontroller.storage.SynchronousExecutorService;
 
@@ -33,18 +34,13 @@ import net.floodlightcontroller.storage.StorageException;
 public class MemoryStorageSource extends NoSqlStorageSource {
     
     private Map<String, MemoryTable> tableMap = new HashMap<String,MemoryTable>();
-    
-    PktinProcessingTime pktinProcessingTime;
-    
-    public MemoryStorageSource() {
-        super(new SynchronousExecutorService(), null);
-    }
+    IPktInProcessingTimeService pktinProcessingTime;
     
     synchronized private MemoryTable getTable(String tableName, boolean create) {
         MemoryTable table = tableMap.get(tableName);
         if (table == null) {
             if (!create)
-                throw new StorageException("Table does not exist");
+                throw new StorageException("Table " + tableName + " does not exist");
             table = new MemoryTable(tableName);
             tableMap.put(tableName, table);
         }
@@ -175,7 +171,15 @@ public class MemoryStorageSource extends NoSqlStorageSource {
     }
     
     public void setPktinProcessingTime(
-            PktinProcessingTime pktinProcessingTime) {
+            IPktInProcessingTimeService pktinProcessingTime) {
         this.pktinProcessingTime = pktinProcessingTime;
     }
+
+    // IFloodlightModule methods
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        super.startUp(context);
+        executorService = new SynchronousExecutorService();
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java
index 37e02f71d1ecc18dbdaa974f7b14e863dac5510f..d7e5f956b4ddee76c68c99cc802a2fa447b19a00 100644
--- a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java
@@ -33,7 +33,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TimeZone;
-import java.util.concurrent.ExecutorService;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -43,7 +42,6 @@ import net.floodlightcontroller.storage.CompoundPredicate;
 import net.floodlightcontroller.storage.IPredicate;
 import net.floodlightcontroller.storage.IQuery;
 import net.floodlightcontroller.storage.IResultSet;
-import net.floodlightcontroller.storage.IStorageExceptionHandler;
 import net.floodlightcontroller.storage.OperatorPredicate;
 import net.floodlightcontroller.storage.RowOrdering;
 import net.floodlightcontroller.storage.StorageException;
@@ -525,11 +523,6 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
         super();
     }
     
-    public NoSqlStorageSource(ExecutorService executorService,
-            IStorageExceptionHandler exceptionHandler) {
-        super(executorService, exceptionHandler);
-    }
-    
     @Override
     public void createTable(String tableName, Set<String> indexedColumns) {
         super.createTable(tableName, indexedColumns);
diff --git a/src/main/java/net/floodlightcontroller/storage/web/StorageNotifyResource.java b/src/main/java/net/floodlightcontroller/storage/web/StorageNotifyResource.java
index 17d129444d95ca9890688679fe83721ab34954f4..fcfa96f40d6b0e27271f48b9a91524d5b6a52a0e 100644
--- a/src/main/java/net/floodlightcontroller/storage/web/StorageNotifyResource.java
+++ b/src/main/java/net/floodlightcontroller/storage/web/StorageNotifyResource.java
@@ -21,7 +21,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import net.floodlightcontroller.storage.IStorageSource;
+import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.StorageSourceNotification;
 
 import org.codehaus.jackson.map.ObjectMapper;
@@ -42,8 +42,9 @@ public class StorageNotifyResource extends ServerResource {
             mapper.readValue(entity, 
                     new TypeReference<List<StorageSourceNotification>>(){});
         
-        IStorageSource storageSource = 
-            (IStorageSource)getContext().getAttributes().get("storageSource");
+        IStorageSourceService storageSource = 
+            (IStorageSourceService)getContext().getAttributes().
+                get(IStorageSourceService.class.getCanonicalName());
         storageSource.notifyListeners(notifications);
         
         HashMap<String, Object> model = new HashMap<String,Object>();
diff --git a/src/main/java/net/floodlightcontroller/storage/web/StorageWebRoutable.java b/src/main/java/net/floodlightcontroller/storage/web/StorageWebRoutable.java
index 8f25d914b10f303f543bac5c83301d1579291e58..681847d8fa1013ef1a39c299ba2a03f8e710d6b1 100644
--- a/src/main/java/net/floodlightcontroller/storage/web/StorageWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/storage/web/StorageWebRoutable.java
@@ -21,7 +21,7 @@ import org.restlet.Context;
 import org.restlet.Restlet;
 import org.restlet.routing.Router;
 
-import net.floodlightcontroller.core.web.RestletRoutable;
+import net.floodlightcontroller.restserver.RestletRoutable;
 
 /**
  * Creates a router to handle the storage web URIs
diff --git a/src/main/java/net/floodlightcontroller/topology/ITopologyAware.java b/src/main/java/net/floodlightcontroller/topology/ITopologyListener.java
similarity index 92%
rename from src/main/java/net/floodlightcontroller/topology/ITopologyAware.java
rename to src/main/java/net/floodlightcontroller/topology/ITopologyListener.java
index 464996f167e4f1ff13c377120bab6369f7e13429..d27a1aa5fdade6b419e9eff7283f9af2e7584470 100644
--- a/src/main/java/net/floodlightcontroller/topology/ITopologyAware.java
+++ b/src/main/java/net/floodlightcontroller/topology/ITopologyListener.java
@@ -24,7 +24,7 @@ import net.floodlightcontroller.core.IOFSwitch;
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public interface ITopologyAware {
+public interface ITopologyListener {
     /**
      * @param srcSw the source switch
      * @param srcPort the source port from the source switch
@@ -56,9 +56,12 @@ public interface ITopologyAware {
             IOFSwitch dstSw, short dstPort);
     
     /**
-     * @param sw
+     * @param sw The IOFSwitch that has been updated
      */
     public void updatedSwitch(IOFSwitch sw);
     
+    /**
+     * Happens when the switch clusters are recomputed
+     */
     void clusterMerged();
 }
diff --git a/src/main/java/net/floodlightcontroller/topology/ITopology.java b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
similarity index 90%
rename from src/main/java/net/floodlightcontroller/topology/ITopology.java
rename to src/main/java/net/floodlightcontroller/topology/ITopologyService.java
index 0816124a0b979258fc2420ce07db0bdd09ebcc0f..36fa63711e38fdf931c9e4c95616355180ae48f5 100644
--- a/src/main/java/net/floodlightcontroller/topology/ITopology.java
+++ b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
@@ -25,14 +25,16 @@ package net.floodlightcontroller.topology;
 
 import java.util.Map;
 import java.util.Set;
+
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.IFloodlightService;
 
 /**
  *
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public interface ITopology {
+public interface ITopologyService extends IFloodlightService {
     /**
      * Query to determine if the specified switch id and port are
      * connected to another switch or not.  If so, this means the link
@@ -93,4 +95,10 @@ public interface ITopology {
      * as an endpoint.
      */
     public Map<IOFSwitch, Set<LinkTuple>> getSwitchLinks();
+    
+    /**
+     * Adds a listener to listen for ITopologyService messages
+     * @param listener The listener that wants the notifications
+     */
+    public void addListener(ITopologyListener listener);
 }
diff --git a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java
index 8ca453c3935a4a7cc3c125419bc9736e056288e0..7bc8580d37fbdd885fe296b9065d5e338f50287e 100644
--- a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java
+++ b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java
@@ -24,6 +24,7 @@ import java.net.NetworkInterface;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -39,30 +40,36 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchListener;
+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.SingletonTask;
 import net.floodlightcontroller.packet.BPDU;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.packet.LLDP;
 import net.floodlightcontroller.packet.LLDPTLV;
+import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.routing.BroadcastTree;
-import net.floodlightcontroller.routing.IRoutingEngine;
+import net.floodlightcontroller.routing.IRoutingEngineService;
 import net.floodlightcontroller.storage.IResultSet;
-import net.floodlightcontroller.storage.IStorageSource;
+import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.IStorageSourceListener;
 import net.floodlightcontroller.storage.OperatorPredicate;
 import net.floodlightcontroller.storage.StorageException;
+import net.floodlightcontroller.topology.ITopologyService;
+import net.floodlightcontroller.topology.ITopologyListener;
 import net.floodlightcontroller.topology.BroadcastDomain;
-import net.floodlightcontroller.topology.ITopology;
-import net.floodlightcontroller.topology.ITopologyAware;
 import net.floodlightcontroller.topology.LinkInfo;
 import net.floodlightcontroller.topology.LinkTuple;
 import net.floodlightcontroller.topology.SwitchCluster;
 import net.floodlightcontroller.topology.SwitchPortTuple;
+import net.floodlightcontroller.topology.web.TopologyWebRoutable;
 import net.floodlightcontroller.util.ClusterDFS;
 import net.floodlightcontroller.util.EventHistory;
 import net.floodlightcontroller.util.EventHistory.EvAction;
@@ -106,8 +113,10 @@ import org.slf4j.LoggerFactory;
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
-                                            IStorageSourceListener, ITopology {
+public class TopologyImpl 
+        implements IOFMessageListener, IOFSwitchListener, 
+                   IStorageSourceListener, ITopologyService,
+                   IFloodlightModule {
     protected static Logger log = LoggerFactory.getLogger(TopologyImpl.class);
 
     // Names of table/fields for links in the storage API
@@ -124,16 +133,15 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
     private static final String SWITCH_TABLE_NAME = "controller_switch";
     private static final String SWITCH_CORE_SWITCH = "core_switch";
 
-    //
+    protected IFloodlightProviderService floodlightProvider;
+    protected IStorageSourceService storageSource;
+    protected IRoutingEngineService routingEngine;
+    protected IRestApiService restApi;
+    
     private static final String LLDP_STANDARD_DST_MAC_STRING = "01:80:c2:00:00:00";
     // BigSwitch OUI is 5C:16:C7, so 5D:16:C7 is the multicast version
     private static final String LLDP_BSN_DST_MAC_STRING = "5d:16:c7:00:00:01";
 
-
-    protected IFloodlightProvider floodlightProvider;
-    protected IStorageSource storageSource;
-    protected IRoutingEngine routingEngine;
-
     /**
      * Map from link to the most recent time it was verified functioning
      */
@@ -164,7 +172,7 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
     protected Map<IOFSwitch, Set<LinkTuple>> switchLinks;
     /* topology aware components are called in the order they were added to the
      * the array */
-    protected ArrayList<ITopologyAware> topologyAware;
+    protected ArrayList<ITopologyListener> topologyAware;
     protected BlockingQueue<Update> updates;
     protected Thread updatesThread;
 
@@ -245,29 +253,12 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
             this.operation = operation;
         }
     }
-
-    public TopologyImpl() {
-        this.lock = new ReentrantReadWriteLock();
-        this.updates = new LinkedBlockingQueue<Update>();
-        this.links = new HashMap<LinkTuple, LinkInfo>();
-        this.portLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>();
-        this.portBroadcastDomainLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>();
-        this.switchLinks = new HashMap<IOFSwitch, Set<LinkTuple>>();
-        this.evHistTopologySwitch =
-            new EventHistory<EventHistoryTopologySwitch>("Topology: Switch");
-        this.evHistTopologyLink =
-            new EventHistory<EventHistoryTopologyLink>("Topology: Link");
-        this.evHistTopologyCluster =
-            new EventHistory<EventHistoryTopologyCluster>("Topology: Cluster");
-
-        setControllerTLV();
-    }
-
+    
     private void doUpdatesThread() throws InterruptedException {
         do {
             Update update = updates.take();
             if (topologyAware != null) {
-                for (ITopologyAware ta : topologyAware) { // order maintained
+                for (ITopologyListener ta : topologyAware) { // order maintained
                     if (log.isDebugEnabled()) {
                         log.debug("Dispatching topology update {} {} {} {} {}",
                                   new Object[]{update.operation,
@@ -304,88 +295,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
         detectLoop();
     }
 
-    public void startUp() {
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-        floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this);
-        floodlightProvider.addOFSwitchListener(this);
-
-        ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor();
-
-        Runnable lldpSendTimer = new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    sendLLDPs();
-
-                    if (!shuttingDown) {
-                        ScheduledExecutorService ses =
-                            floodlightProvider.getScheduledExecutor();
-                                    ses.schedule(this, lldpFrequency,
-                                                        TimeUnit.MILLISECONDS);
-                    }
-                } catch (StorageException e) {
-                    log.error("Storage exception in LLDP send timer; " +
-                              "terminating process", e);
-                    floodlightProvider.terminate();
-                } catch (Exception e) {
-                    log.error("Exception in LLDP send timer", e);
-                }
-            }
-        };
-        ses.schedule(lldpSendTimer, 1000, TimeUnit.MILLISECONDS);
-
-        Runnable timeoutLinksTimer = new Runnable() {
-            @Override
-            public void run() {
-                log.trace("Running timeoutLinksTimer");
-                try {
-                    timeoutLinks();
-                    if (!shuttingDown) {
-                        ScheduledExecutorService ses =
-                            floodlightProvider.getScheduledExecutor();
-                        ses.schedule(this, lldpTimeout, TimeUnit.MILLISECONDS);
-                    }
-                } catch (StorageException e) {
-                    log.error("Storage exception in link timer; " +
-                              "terminating process", e);
-                    floodlightProvider.terminate();
-                } catch (Exception e) {
-                    log.error("Exception in timeoutLinksTimer", e);
-                }
-            }
-        };
-        ses.schedule(timeoutLinksTimer, 1000, TimeUnit.MILLISECONDS);
-
-        updatesThread = new Thread(new Runnable () {
-            @Override
-            public void run() {
-                while (true) {
-                    try {
-                        doUpdatesThread();
-                    } catch (InterruptedException e) {
-                        return;
-                    }
-                }
-            }}, "Topology Updates");
-        updatesThread.start();
-
-        try {
-            storageSource.addListener(SWITCH_TABLE_NAME, this);
-        }
-        catch (StorageException ex) {
-            log.error("Error in installing listener for switch table - {}", SWITCH_TABLE_NAME);
-            // floodlightProvider.terminate();  // For now, log this error and continue
-        }
-    }
-
-    protected void shutDown() {
-        shuttingDown = true;
-        floodlightProvider.removeOFSwitchListener(this);
-        floodlightProvider.removeOFMessageListener(OFType.PACKET_IN, this);
-        floodlightProvider.removeOFMessageListener(OFType.PORT_STATUS, this);
-        updatesThread.interrupt();
-    }
-
     /**
      *  Detect loops in the openflow clusters and construct spanning trees
      *  for broadcast
@@ -611,7 +520,7 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
     public String getName() {
         return "topology";
     }
-
+ 
     @Override
     public int getId() {
         return FlListenerID.TOPOLOGYIMPL;
@@ -667,7 +576,7 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
             // This is not the LLDP sent by this controller.
             // If the LLDP message has multicast bit set, then we need to broadcast
             // the packet as a regular packet.
-            Ethernet eth = IFloodlightProvider.bcStore.get(cntx, IFloodlightProvider.CONTEXT_PI_PAYLOAD);
+            Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
             if (eth.isMulticast()) {
                 if (log.isTraceEnabled())
                     log.trace("Received a multicast LLDP packet from a different controller, allowing the packet to follow normal processing chain.");
@@ -733,9 +642,9 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
 
     protected Command handlePacketIn(IOFSwitch sw, OFPacketIn pi,
                                      FloodlightContext cntx) {
-        Ethernet eth =
-            IFloodlightProvider.bcStore.get(cntx,
-                                        IFloodlightProvider.CONTEXT_PI_PAYLOAD);
+        Ethernet eth = 
+            IFloodlightProviderService.bcStore.get(cntx, 
+                                        IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
 
         if (eth.getPayload() instanceof LLDP)  {
             String dstMacString = HexString.toHexString(eth.getDestinationMACAddress());
@@ -1138,7 +1047,7 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
      * Sets the IFloodlightProvider for this TopologyImpl.
      * @param floodlightProvider the floodlightProvider to set
      */
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
+    public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
     }
     
@@ -1300,7 +1209,7 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
      * compute connected components.
      */
     protected void updateBroadcastDomains() {
-        Map<SwitchPortTuple, Set<LinkTuple>> pbdLinks =  getPortBroadcastDomainLinks();
+        Map<SwitchPortTuple, Set<LinkTuple>> pbdLinks = getPortBroadcastDomainLinks();
         Set<SwitchPortTuple> visitedSwt = new HashSet<SwitchPortTuple>();
         Map<Long, BroadcastDomain> bdMap = new HashMap<Long, BroadcastDomain>();
         Map<SwitchPortTuple, BroadcastDomain> spbdMap = new HashMap<SwitchPortTuple, BroadcastDomain>();
@@ -1712,20 +1621,17 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
         String id = getLinkId(lt);
         storageSource.deleteRowAsync(LINK_TABLE_NAME, id);
     }
-
-    /**
-     * @param topologyAware the topologyAware to set
-     */
-    public void setTopologyAware(ArrayList<ITopologyAware> topologyAware) {
-        // TODO make this a copy on write set or lock it somehow
-        this.topologyAware = topologyAware;
+    
+    @Override
+    public void addListener(ITopologyListener listener) {
+        topologyAware.add(listener);
     }
-
+    
     /**
      * Register a topology aware component
      * @param topoAwareComponent
      */
-    public void addTopologyAware(ITopologyAware topoAwareComponent) {
+    public void addTopologyAware(ITopologyListener topoAwareComponent) {
         // TODO make this a copy on write set or lock it somehow
         this.topologyAware.add(topoAwareComponent);
     }
@@ -1734,7 +1640,7 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
      * Deregister a topology aware component
      * @param topoAwareComponent
      */
-    public void removeTopologyAware(ITopologyAware topoAwareComponent) {
+    public void removeTopologyAware(ITopologyListener topoAwareComponent) {
         // TODO make this a copy on write set or lock it somehow
         this.topologyAware.remove(topoAwareComponent);
     }
@@ -1743,27 +1649,23 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
      * Sets the IStorageSource to use for ITology
      * @param storageSource the storage source to use
      */
-    public void setStorageSource(IStorageSource storageSource) {
+    public void setStorageSource(IStorageSourceService storageSource) {
         this.storageSource = storageSource;
-        storageSource.createTable(LINK_TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID);
     }
 
     /**
      * Gets the storage source for this ITopology
      * @return The IStorageSource ITopology is writing to
      */
-    public IStorageSource getStorageSource() {
+    public IStorageSourceService getStorageSource() {
         return storageSource;
     }
 
     /**
      * @param routingEngine the storage source to use for persisting link info
      */
-    public void setRoutingEngine(IRoutingEngine routingEngine) {
+    public void setRoutingEngine(IRoutingEngineService routingEngine) {
         this.routingEngine = routingEngine;
-        storageSource.createTable(LINK_TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID);
     }
 
     @Override
@@ -1832,6 +1734,154 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
         // Ignore delete events, the switch delete will do the right thing on it's own
     }
 
+    // IFloodlightModule classes
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(ITopologyService.class);
+        return l;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        Map<Class<? extends IFloodlightService>,
+        IFloodlightService> m = 
+            new HashMap<Class<? extends IFloodlightService>,
+                        IFloodlightService>();
+        // We are the class that implements the service
+        m.put(ITopologyService.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(IStorageSourceService.class);
+        l.add(IRoutingEngineService.class);
+        l.add(IRestApiService.class);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+                      throws FloodlightModuleException {
+        floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+        storageSource = context.getServiceImpl(IStorageSourceService.class);
+        routingEngine = context.getServiceImpl(IRoutingEngineService.class);
+        restApi = context.getServiceImpl(IRestApiService.class);
+        
+        // We create this here because there is no ordering guarantee
+        this.topologyAware = new ArrayList<ITopologyListener>();
+        this.lock = new ReentrantReadWriteLock();
+        this.updates = new LinkedBlockingQueue<Update>();
+        this.links = new HashMap<LinkTuple, LinkInfo>();
+        this.portLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>();
+        this.portBroadcastDomainLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>();
+        this.switchLinks = new HashMap<IOFSwitch, Set<LinkTuple>>();
+        this.evHistTopologySwitch =
+            new EventHistory<EventHistoryTopologySwitch>("Topology: Switch");
+        this.evHistTopologyLink =
+            new EventHistory<EventHistoryTopologyLink>("Topology: Link");
+        this.evHistTopologyCluster =
+            new EventHistory<EventHistoryTopologyCluster>("Topology: Cluster");
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // Create our storage tables
+        storageSource.createTable(LINK_TABLE_NAME, null);
+        storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID);
+        storageSource.createTable(LINK_TABLE_NAME, null);
+        storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID);
+        // Register for storage updates for the switch table
+        try {
+            storageSource.addListener(SWITCH_TABLE_NAME, this);
+        } catch (StorageException ex) {
+            log.error("Error in installing listener for switch table - {}", SWITCH_TABLE_NAME);
+        }
+        
+        ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor();
+
+        // Setup sending out LLDPs
+        Runnable lldpSendTimer = new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    sendLLDPs();
+
+                    if (!shuttingDown) {
+                        ScheduledExecutorService ses = 
+                            floodlightProvider.getScheduledExecutor();
+                                    ses.schedule(this, lldpFrequency, 
+                                                        TimeUnit.MILLISECONDS);
+                    }
+                } catch (StorageException e) {
+                    log.error("Storage exception in LLDP send timer; " + 
+                              "terminating process", e);
+                    floodlightProvider.terminate();
+                } catch (Exception e) {
+                    log.error("Exception in LLDP send timer", e);
+                }
+            }   
+        };
+        ses.schedule(lldpSendTimer, 1000, TimeUnit.MILLISECONDS);
+
+        Runnable timeoutLinksTimer = new Runnable() {
+            @Override
+            public void run() {
+                log.trace("Running timeoutLinksTimer");
+                try {
+                    timeoutLinks();
+                    if (!shuttingDown) {
+                        ScheduledExecutorService ses = 
+                            floodlightProvider.getScheduledExecutor();
+                        ses.schedule(this, lldpTimeout, TimeUnit.MILLISECONDS);
+                    }
+                } catch (StorageException e) {
+                    log.error("Storage exception in link timer; " + 
+                              "terminating process", e);
+                    floodlightProvider.terminate();
+                } catch (Exception e) {
+                    log.error("Exception in timeoutLinksTimer", e);
+                }
+            }
+        };
+        ses.schedule(timeoutLinksTimer, 1000, TimeUnit.MILLISECONDS);
+
+        updatesThread = new Thread(new Runnable () {
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        doUpdatesThread();
+                    } catch (InterruptedException e) {
+                        return;
+                    } 
+                }
+            }}, "Topology Updates");
+        updatesThread.start();
+        
+        // Register for the OpenFlow messages we want to receive
+        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+        floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this);
+        // Register for switch updates
+        floodlightProvider.addOFSwitchListener(this);
+        
+        // init our rest api
+        if (restApi != null) {
+            restApi.addRestletRoutable(new TopologyWebRoutable());
+        } else {
+            log.error("Could not instantiate REST API");
+        }
+
+        setControllerTLV();
+    }
+
     // ****************************************************
     // Topology Manager's Event History members and methods
     // ****************************************************
diff --git a/src/main/java/net/floodlightcontroller/topology/web/LinksResource.java b/src/main/java/net/floodlightcontroller/topology/web/LinksResource.java
index 48b2f664870de232a968e2fd8cf7065bdb4a92c3..9c4f57d5d9ad6ee6ae55f9f6cd698629d447d710 100644
--- a/src/main/java/net/floodlightcontroller/topology/web/LinksResource.java
+++ b/src/main/java/net/floodlightcontroller/topology/web/LinksResource.java
@@ -3,7 +3,7 @@ package net.floodlightcontroller.topology.web;
 import java.util.HashSet;
 import java.util.Set;
 
-import net.floodlightcontroller.topology.ITopology;
+import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.topology.LinkTuple;
 
 import org.restlet.resource.Get;
@@ -12,7 +12,8 @@ import org.restlet.resource.ServerResource;
 public class LinksResource extends ServerResource {
     @Get("json")
     public Set<LinkTuple> retrieve() {
-        ITopology topo = (ITopology)getContext().getAttributes().get("topology");
+        ITopologyService topo = (ITopologyService)getContext().getAttributes().
+                get(ITopologyService.class.getCanonicalName());
         Set <LinkTuple> links = new HashSet<LinkTuple>();
         if (topo != null) {
             for (Set<LinkTuple> linkSet : topo.getSwitchLinks().values()) {
diff --git a/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRouteable.java b/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
similarity index 85%
rename from src/main/java/net/floodlightcontroller/topology/web/TopologyWebRouteable.java
rename to src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
index 096b4601c56a3588f6f2d48c9bffeec8bc9e5d5e..fa918c450dbe250d973861db226afa8f26f5ac06 100644
--- a/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRouteable.java
+++ b/src/main/java/net/floodlightcontroller/topology/web/TopologyWebRoutable.java
@@ -4,10 +4,10 @@ import org.restlet.Context;
 import org.restlet.Restlet;
 import org.restlet.routing.Router;
 
-import net.floodlightcontroller.core.web.RestletRoutable;
 import net.floodlightcontroller.core.web.SwitchClustersResource;
+import net.floodlightcontroller.restserver.RestletRoutable;
 
-public class TopologyWebRouteable implements RestletRoutable {
+public class TopologyWebRoutable implements RestletRoutable {
     /**
      * Create the Restlet router and bind to the proper resources.
      */
diff --git a/src/main/java/net/floodlightcontroller/util/TimedCache.java b/src/main/java/net/floodlightcontroller/util/TimedCache.java
index 107da08217c46962b7d70b0f8b3fcfb3628ef658..857d57de9046fb02abb5778f63b2666dcd15d446 100644
--- a/src/main/java/net/floodlightcontroller/util/TimedCache.java
+++ b/src/main/java/net/floodlightcontroller/util/TimedCache.java
@@ -20,7 +20,6 @@ package net.floodlightcontroller.util;
 import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
 import java.util.concurrent.ConcurrentMap;
 
-
 /**
  * The key is any object/hash-code
  * The value is time-stamp in milliseconds
@@ -29,7 +28,7 @@ import java.util.concurrent.ConcurrentMap;
  * 
  * @param <K> Type of the values in this cache
  */
-public class TimedCache<K> {
+public class TimedCache<K> {    
     private final long timeoutInterval;    //specified in milliseconds.
 	private ConcurrentMap<K, Long> cache;
     private long cacheHits;
@@ -85,4 +84,4 @@ public class TimedCache<K> {
         this.cacheHits++;
         return true;
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
new file mode 100644
index 0000000000000000000000000000000000000000..1207638607366e0818a2c375d8b16f68a2ee760e
--- /dev/null
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -0,0 +1,10 @@
+net.floodlightcontroller.core.CoreModule
+net.floodlightcontroller.storage.memory.MemoryStorageSource
+net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl
+net.floodlightcontroller.topology.internal.TopologyImpl
+net.floodlightcontroller.routing.dijkstra.RoutingImpl
+net.floodlightcontroller.forwarding.Forwarding
+net.floodlightcontroller.core.OFMessageFilterManager
+net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher
+net.floodlightcontroller.perfmon.PktInProcessingTime
+net.floodlightcontroller.restserver.RestApiServer
\ No newline at end of file
diff --git a/src/main/resources/floodlightdefault.properties b/src/main/resources/floodlightdefault.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6d2dbca087f960ab50baae674e40c72fce4c1ef5
--- /dev/null
+++ b/src/main/resources/floodlightdefault.properties
@@ -0,0 +1 @@
+floodlight.modules = net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,net.floodlightcontroller.forwarding.Forwarding
diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index ae443bb462f3d623529e71c73d6d49d637b7aee4..2ba77e55e207a5e63670a74d5d0bd2d57ab41a70 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -29,11 +29,15 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.IOFMessageFilterManagerService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFMessageListener.Command;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.OFMessageFilterManager;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleLoader;
+import net.floodlightcontroller.core.module.IFloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.packet.ARP;
 import net.floodlightcontroller.packet.Ethernet;
@@ -66,11 +70,14 @@ public class ControllerTest extends FloodlightTestCase {
     private Controller controller;
 
     @Override
-    public void setUp() {
+    public void setUp() throws Exception {
         super.setUp();
-
-        controller = new Controller();
-        controller.init();
+        FloodlightModuleLoader fml = new FloodlightModuleLoader();
+        IFloodlightModuleContext moduleContext = fml.loadModulesFromList(
+            new String[]  {"net.floodlightcontroller.core.CoreModule"});
+        controller = 
+            (Controller) moduleContext.
+                getServiceImpl(IFloodlightProviderService.class);
     }
 
     public Controller getController() {
@@ -280,13 +287,16 @@ public class ControllerTest extends FloodlightTestCase {
 
     @Test
     public void testMessageFilterManager() throws Exception {
-
-        MockFloodlightProvider mbp = new MockFloodlightProvider();
+        FloodlightModuleContext fmCntx = new FloodlightModuleContext();
+        MockFloodlightProvider mfp = new MockFloodlightProvider();
+        OFMessageFilterManager mfm = new OFMessageFilterManager();
+        fmCntx.addService(IOFMessageFilterManagerService.class, mfm);
+        fmCntx.addService(IFloodlightProviderService.class, mfp);
         String sid = null;
 
-        OFMessageFilterManager mfm = new OFMessageFilterManager();
-        mfm.init(mbp);
-        mfm.startUp();
+        
+        mfm.init(fmCntx);
+        mfm.startUp(fmCntx);
 
         ConcurrentHashMap <String, String> filter;
         int i;
@@ -353,22 +363,22 @@ public class ControllerTest extends FloodlightTestCase {
         .setLengthU(OFPacketOut.MINIMUM_LENGTH+packetOut.getActionsLength()+testPacketSerialized.length);
 
         FloodlightContext cntx = new FloodlightContext();
-        IFloodlightProvider.bcStore.put(cntx, IFloodlightProvider.CONTEXT_PI_PAYLOAD, (Ethernet) testPacket);
+        IFloodlightProviderService.bcStore.put(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD, (Ethernet) testPacket);
 
 
         // Let's check the listeners.
         List <IOFMessageListener> lm; 
 
         // Check to see if all the listeners are active.
-        lm = mbp.getListeners().get(OFType.PACKET_OUT);
+        lm = mfp.getListeners().get(OFType.PACKET_OUT);
         assertTrue(lm.size() == 1);
         assertTrue(lm.get(0).equals(mfm));
 
-        lm = mbp.getListeners().get(OFType.FLOW_MOD);
+        lm = mfp.getListeners().get(OFType.FLOW_MOD);
         assertTrue(lm.size() == 1);
         assertTrue(lm.get(0).equals(mfm));
 
-        lm = mbp.getListeners().get(OFType.PACKET_IN);
+        lm = mfp.getListeners().get(OFType.PACKET_IN);
         assertTrue(lm.size() == 1);
         assertTrue(lm.get(0).equals(mfm));
 
diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
index 9758c6a08abf8a21a4f2e09897b0a8d9d75b9d6d..86d3427d61712901cb2a4bf0509fc90ea367703e 100644
--- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
+++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
@@ -18,6 +18,7 @@
 package net.floodlightcontroller.core.test;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -26,12 +27,17 @@ import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.ScheduledExecutorService;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFMessageListener;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.IOFSwitchFilter;
 import net.floodlightcontroller.core.IOFSwitchListener;
 import net.floodlightcontroller.core.IOFMessageListener.Command;
+import net.floodlightcontroller.core.internal.CmdLineSettings;
+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.packet.Ethernet;
 
 import org.openflow.protocol.OFMessage;
@@ -43,7 +49,7 @@ import org.openflow.protocol.factory.BasicFactory;
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public class MockFloodlightProvider implements IFloodlightProvider {
+public class MockFloodlightProvider implements IFloodlightModule, IFloodlightProviderService {
     protected Map<OFType, List<IOFMessageListener>> listeners;
     protected List<IOFSwitchListener> switchListeners;
     protected Map<Long, IOFSwitch> switches;
@@ -123,8 +129,8 @@ public class MockFloodlightProvider implements IFloodlightProvider {
                 OFPacketIn pi = (OFPacketIn)msg;
                 Ethernet eth = new Ethernet();
                 eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
-                IFloodlightProvider.bcStore.put(bc, 
-                        IFloodlightProvider.CONTEXT_PI_PAYLOAD, 
+                IFloodlightProviderService.bcStore.put(bc, 
+                        IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
                         eth);
             }
             while (it.hasNext() && !Command.STOP.equals(result)) {
@@ -194,4 +200,49 @@ public class MockFloodlightProvider implements IFloodlightProvider {
     public BasicFactory getOFMessageFactory() {
         return factory;
     }
+
+    @Override
+    public void run() {
+        // no-op
+    }
+
+    @Override
+    public void setCmdLineOptions(CmdLineSettings settings) {
+        // no-op
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>>
+            getModuleDependencies() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public
+            void
+            init(FloodlightModuleContext context)
+                                                 throws FloodlightModuleException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // TODO Auto-generated method stub
+        
+    }
 }
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
index 4e559b775845a226b78f09d18ec6f3eda19aa2fa..227c7937b6f239ee0b73e8b7a5e91d589db71b4f 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
@@ -32,21 +32,26 @@ import static org.easymock.EasyMock.replay;
 import static org.easymock.EasyMock.reset;
 import static org.easymock.EasyMock.verify;
 
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.devicemanager.DeviceAttachmentPoint;
 import net.floodlightcontroller.devicemanager.IEntityClass;
 import net.floodlightcontroller.devicemanager.IEntityClassifier;
 import net.floodlightcontroller.devicemanager.IEntityClassifier.EntityField;
 import net.floodlightcontroller.devicemanager.SwitchPort;
+import net.floodlightcontroller.devicemanager.IDeviceManagerService;
 import net.floodlightcontroller.packet.ARP;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPacket;
 import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.storage.IStorageSource;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.restserver.RestApiServer;
+import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.memory.MemoryStorageSource;
 import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.topology.ITopology;
+import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.topology.SwitchPortTuple;
 
 import static org.junit.Assert.*;
@@ -67,18 +72,26 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
     private byte[] testPacketSerialized;
     MockFloodlightProvider mockFloodlightProvider;
     DeviceManagerImpl deviceManager;
-    IStorageSource storageSource;
+    MemoryStorageSource storageSource;
     
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         super.setUp();
 
+        FloodlightModuleContext fmc = new FloodlightModuleContext();
+        RestApiServer restApi = new RestApiServer();
         mockFloodlightProvider = getMockFloodlightProvider();
         deviceManager = new DeviceManagerImpl();
+        fmc.addService(IDeviceManagerService.class, deviceManager);
         storageSource = new MemoryStorageSource();
-        deviceManager.setFloodlightProvider(mockFloodlightProvider);
-        deviceManager.setStorageSource(storageSource);
-        deviceManager.startUp();
+        fmc.addService(IStorageSourceService.class, storageSource);
+        fmc.addService(IFloodlightProviderService.class, mockFloodlightProvider);
+        fmc.addService(IRestApiService.class, restApi);
+        restApi.init(fmc);
+        storageSource.init(fmc);
+        deviceManager.init(fmc);
+        storageSource.startUp(fmc);
+        deviceManager.startUp(fmc);
         
         // Build our test packet
         this.testPacket = new Ethernet()
@@ -241,9 +254,9 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         IOFSwitch mockSwitch = createMock(IOFSwitch.class);
         expect(mockSwitch.getId()).andReturn(1L).anyTimes();
         expect(mockSwitch.getStringId()).andReturn("00:00:00:00:00:00:00:01").anyTimes();
-        ITopology mockTopology = createMock(ITopology.class);
+        ITopologyService mockTopology = createMock(ITopologyService.class);
         expect(mockTopology.isInternal(mockSwitch, (short)1)).andReturn(false).anyTimes();
-        deviceManager.setTopology(mockTopology);
+        deviceManager.topology = mockTopology;
 
         Date currentDate = new Date();
         
@@ -304,7 +317,6 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         fail();
     }
     
-    
     @Test
     public void testDeviceUpdateLastSeenToStorage() throws Exception {
         fail();
@@ -317,7 +329,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         // Mock up our expected behavior
         IOFSwitch mockSwitch = createNiceMock(IOFSwitch.class);
         expect(mockSwitch.getId()).andReturn(1L).atLeastOnce();
-        ITopology mockTopology = createNiceMock(ITopology.class);
+        ITopologyService mockTopology = createNiceMock(ITopologyService.class);
         //expect(mockTopology.isInternal(new SwitchPortTuple(mockSwitch, 1))).andReturn(false);
         deviceManager.setTopology(mockTopology);
 
@@ -367,7 +379,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         IOFSwitch mockSwitch = createMock(IOFSwitch.class);
         expect(mockSwitch.getId()).andReturn(1L).anyTimes();
         expect(mockSwitch.getStringId()).andReturn("00:00:00:00:00:00:00:01").anyTimes();
-        ITopology mockTopology = createMock(ITopology.class);
+        ITopologyService mockTopology = createMock(ITopologyService.class);
         expect(mockSwitch.getPort((short)1)).andReturn(port1).anyTimes();
         expect(mockSwitch.getPort((short)2)).andReturn(port2).anyTimes();
         expect(mockTopology.isInternal(new SwitchPortTuple(mockSwitch, 1)))
@@ -423,7 +435,6 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
     }
     
     private void setupPortChannel() {
-        
         storageSource.insertRow(DeviceManagerImpl.PORT_CHANNEL_TABLE_NAME, pcPort1);
         storageSource.insertRow(DeviceManagerImpl.PORT_CHANNEL_TABLE_NAME, pcPort2);
         deviceManager.readPortChannelConfigFromStorage();
@@ -459,7 +470,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         expect(mockSwitch.getPort((short)2)).andReturn(port2).anyTimes();
         expect(mockSwitch.getId()).andReturn(1L).anyTimes();
         expect(mockSwitch.getStringId()).andReturn("00:00:00:00:00:00:00:01").anyTimes();
-        ITopology mockTopology = createMock(ITopology.class);
+        ITopologyService mockTopology = createMock(ITopologyService.class);
         expect(mockTopology.isInternal(new SwitchPortTuple(mockSwitch, 1)))
                            .andReturn(false).atLeastOnce();
         expect(mockTopology.isInternal(new SwitchPortTuple(mockSwitch, 2)))
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
index 4a3d3c450fa1c82da11e882cc8a1c4bc2a81a4a7..4e2fb6cddd9baebbaa55dc8bc47b4a0a30b35cce 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/test/MockDeviceManager.java
@@ -23,12 +23,17 @@ import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
 import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceManager;
 import net.floodlightcontroller.devicemanager.IEntityClass;
 import net.floodlightcontroller.devicemanager.IEntityClassifier;
 import net.floodlightcontroller.devicemanager.internal.Device;
+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.devicemanager.IDeviceManagerAware;
+import net.floodlightcontroller.devicemanager.IDeviceManagerService;
 
-public class MockDeviceManager implements IDeviceManager {
+public class MockDeviceManager implements IFloodlightModule, IDeviceManagerService {
     protected Map<Long, Device> devices;
 
     public MockDeviceManager() {
@@ -73,4 +78,45 @@ public class MockDeviceManager implements IDeviceManager {
         // TODO Auto-generated method stub
         return null;
     }
+
+    @Override
+    public void addListener(IDeviceManagerAware listener) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Map<Class<? extends IFloodlightService>, IFloodlightService>
+            getServiceImpls() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>>
+            getModuleDependencies() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public
+            void
+            init(FloodlightModuleContext context)
+                                                 throws FloodlightModuleException {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // TODO Auto-generated method stub
+        
+    }
 }
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index e55152a48b4083550f626dda399f2ad998ccd567..06a6b19b85c5f7324ae411b61e1caf7c4bdf7a3f 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -31,23 +31,23 @@ import java.util.List;
 import java.util.Map;
 
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.devicemanager.IDeviceManager;
 import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
 import net.floodlightcontroller.devicemanager.internal.Device;
 import net.floodlightcontroller.devicemanager.internal.Entity;
+import net.floodlightcontroller.devicemanager.IDeviceManagerService;
 import net.floodlightcontroller.packet.Data;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.IPacket;
 import net.floodlightcontroller.packet.IPv4;
 import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.routing.IRoutingEngine;
+import net.floodlightcontroller.routing.IRoutingEngineService;
 import net.floodlightcontroller.routing.Link;
 import net.floodlightcontroller.routing.Route;
 import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.topology.ITopology;
+import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.forwarding.Forwarding;
 
 import org.easymock.Capture;
@@ -67,10 +67,10 @@ import org.openflow.protocol.action.OFActionOutput;
 public class ForwardingTest extends FloodlightTestCase {
     protected MockFloodlightProvider mockFloodlightProvider;
     protected FloodlightContext cntx;
-    protected IDeviceManager deviceManager;
-    protected IRoutingEngine routingEngine;
+    protected IDeviceManagerService deviceManager;
+    protected IRoutingEngineService routingEngine;
     protected Forwarding forwarding;
-    protected ITopology topology;
+    protected ITopologyService topology;
     protected IOFSwitch sw1, sw2;
     protected Device srcDevice, dstDevice1, dstDevice2;
     protected OFPacketIn packetIn;
@@ -81,16 +81,16 @@ public class ForwardingTest extends FloodlightTestCase {
     protected Date currentDate;
     
     @Override
-    public void setUp() {
+    public void setUp() throws Exception {
         super.setUp();
 
         // Mock context
         cntx = new FloodlightContext();
         mockFloodlightProvider = getMockFloodlightProvider();
         forwarding = getForwarding();
-        deviceManager = createMock(IDeviceManager.class);
-        routingEngine = createMock(IRoutingEngine.class);
-        topology = createMock(ITopology.class);
+        deviceManager = createMock(IDeviceManagerService.class);
+        routingEngine = createMock(IRoutingEngineService.class);
+        topology = createMock(ITopologyService.class);
         forwarding.setFloodlightProvider(mockFloodlightProvider);
         forwarding.setDeviceManager(deviceManager);
         forwarding.setRoutingEngine(routingEngine);
@@ -213,12 +213,14 @@ public class ForwardingTest extends FloodlightTestCase {
                               ~OFMatch.OFPFW_NW_DST_MASK;
 
         // Add the packet to the context store
-        IFloodlightProvider.bcStore.put(cntx, 
-                                        IFloodlightProvider.CONTEXT_PI_PAYLOAD, 
-                                        (Ethernet)testPacket);
-        IDeviceManager.fcStore.put(cntx, 
-                                   IDeviceManager.CONTEXT_SRC_DEVICE,
-                                   srcDevice);
+        IFloodlightProviderService.bcStore.
+            put(cntx, 
+                IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
+                (Ethernet)testPacket);
+        IDeviceManagerService.fcStore.
+            put(cntx, 
+                IDeviceManagerService.CONTEXT_SRC_DEVICE,
+                srcDevice);
     }
 
     private Forwarding getForwarding() {
@@ -236,9 +238,10 @@ public class ForwardingTest extends FloodlightTestCase {
                 new Capture<FloodlightContext>(CaptureType.ALL);
 
         // Set destination as sw2 and Mock route
-        IDeviceManager.fcStore.put(cntx, 
-                                   IDeviceManager.CONTEXT_DST_DEVICE, 
-                                   dstDevice1);
+        IDeviceManagerService.fcStore.
+            put(cntx, 
+                IDeviceManagerService.CONTEXT_DST_DEVICE, 
+                dstDevice1);
 
         Route route = new Route(1L, 2L);
         route.setPath(new ArrayList<Link>());
@@ -296,9 +299,10 @@ public class ForwardingTest extends FloodlightTestCase {
     @Test
     public void testForwardSingleSwitchPath() throws Exception {        
         // Set destination as local and Mock route
-        IDeviceManager.fcStore.put(cntx, 
-                                   IDeviceManager.CONTEXT_DST_DEVICE, 
-                                   dstDevice2);
+        IDeviceManagerService.fcStore.
+            put(cntx, 
+                IDeviceManagerService.CONTEXT_DST_DEVICE, 
+                dstDevice2);
         expect(routingEngine.getRoute(1L, 1L)).andReturn(null).atLeastOnce();
         
         // Expected Flow-mods
diff --git a/src/test/java/net/floodlightcontroller/hub/HubTest.java b/src/test/java/net/floodlightcontroller/hub/HubTest.java
index 6311b2518e067349f215be66b6775adb375739f1..b4a215cd066a7772fc669683dba47aedeb8e7bca 100644
--- a/src/test/java/net/floodlightcontroller/hub/HubTest.java
+++ b/src/test/java/net/floodlightcontroller/hub/HubTest.java
@@ -60,7 +60,7 @@ public class HubTest extends FloodlightTestCase {
     private Hub hub;
     
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         super.setUp();
 
         mockFloodlightProvider = getMockFloodlightProvider();
diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
index ecbb4d2a2991a54a25276e3ee19c133e27b06bdc..613f8990dacbf0e965b9426b39cebd5b144cf9cd 100644
--- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
+++ b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
@@ -63,7 +63,7 @@ public class LearningSwitchTest extends FloodlightTestCase {
     private LearningSwitch learningSwitch;
     
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         super.setUp();
 
         mockFloodlightProvider = getMockFloodlightProvider();
diff --git a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java
index fbd700e28ddaf385f36fc07cf0dbfbd5e836962e..825f2f1194f9bb1639f13dabd362c76cf18b435a 100644
--- a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java
+++ b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java
@@ -27,9 +27,10 @@ import org.openflow.util.HexString;
 public class StaticFlowEntryPusherTest extends FloodlightTestCase {
     String flowMod1, flowMod2;
     static String TestSwitch1DPID = "00:00:00:00:00:00:00:01";
+    StaticFlowEntryPusher staticFlowEntryPusher;
     
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         super.setUp();
         flowMod1 = "{\"switch\": \"00:00:00:00:00:00:00:01\", " +
                    "\"name\": \"flow-mod-1\", " +
@@ -46,13 +47,17 @@ public class StaticFlowEntryPusherTest extends FloodlightTestCase {
                    "\"ingress-port\": \"2\"," +
                    "\"active\": \"true\", " +
                    "\"actions\": \"output=3\"}";
+
+        staticFlowEntryPusher = new StaticFlowEntryPusher();
+        staticFlowEntryPusher.floodlightProvider = 
+                getMockFloodlightProvider();
+        staticFlowEntryPusher.setFlowPushTime(200);
+        staticFlowEntryPusher.startUp(null);
     }
     
     @Test
     public void testAddAndRemoveEntries() throws Exception {
-        StaticFlowEntryPusher staticFlowEntryPusher = 
-                new StaticFlowEntryPusher();
-        staticFlowEntryPusher.setFlowPushTime(200);
+        
         IOFSwitch mockSwitch = createMock(IOFSwitch.class);
         long dpid = HexString.toLong(TestSwitch1DPID);
         Capture<OFMessage> writeCapture = new Capture<OFMessage>(CaptureType.ALL);
@@ -70,9 +75,6 @@ public class StaticFlowEntryPusherTest extends FloodlightTestCase {
         Map<Long, IOFSwitch> switchMap = new HashMap<Long, IOFSwitch>();
         switchMap.put(dpid, mockSwitch);
         mockFloodlightProvider.setSwitches(switchMap);
-        staticFlowEntryPusher.setFloodlightProvider(mockFloodlightProvider);
-        staticFlowEntryPusher.startUp();
-        
         // if someone calls getId(), return this dpid instead
         expect(mockSwitch.getId()).andReturn(dpid).anyTimes();
         replay(mockSwitch);
@@ -93,8 +95,9 @@ public class StaticFlowEntryPusherTest extends FloodlightTestCase {
         while (count >= 0) {
             Thread.sleep(staticFlowEntryPusher.getFlowPushTime());
 
-            if (writeCapture.getValues().size() >= 4)
+            if (writeCapture.getValues().size() >= 4) {
                 break;
+            }
 
             count -= 1;
         }
diff --git a/src/test/java/net/floodlightcontroller/storage/memory/tests/MemoryStorageTest.java b/src/test/java/net/floodlightcontroller/storage/memory/tests/MemoryStorageTest.java
index 9e8d7c0a82b0f0afe484804208a00d795a93f678..c2500662218deb316fcb2cb620f766c04012c3a6 100644
--- a/src/test/java/net/floodlightcontroller/storage/memory/tests/MemoryStorageTest.java
+++ b/src/test/java/net/floodlightcontroller/storage/memory/tests/MemoryStorageTest.java
@@ -17,6 +17,9 @@
 
 package net.floodlightcontroller.storage.memory.tests;
 
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.restserver.RestApiServer;
 import net.floodlightcontroller.storage.memory.MemoryStorageSource;
 import net.floodlightcontroller.storage.tests.StorageTest;
 import org.junit.Before;
@@ -24,8 +27,15 @@ import org.junit.Before;
 public class MemoryStorageTest extends StorageTest {
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         storageSource = new MemoryStorageSource();
+        restApi = new RestApiServer();
+        FloodlightModuleContext fmc = new FloodlightModuleContext();
+        fmc.addService(IRestApiService.class, restApi);
+        restApi.init(fmc);
+        storageSource.init(fmc);
+        restApi.startUp(fmc);
+        storageSource.startUp(fmc);
         super.setUp();
     }
 }
diff --git a/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java b/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java
index 78957a3fdc3b10c8692743f1df20f2fd596bcce1..a76b98cbc6ed716532a74aacb3e321ade40a300c 100644
--- a/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java
+++ b/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java
@@ -30,25 +30,27 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
-import net.floodlightcontroller.perfmon.PktinProcessingTime;
+import net.floodlightcontroller.perfmon.PktInProcessingTime;
+import net.floodlightcontroller.restserver.RestApiServer;
 import net.floodlightcontroller.storage.CompoundPredicate;
 import net.floodlightcontroller.storage.IStorageExceptionHandler;
 import net.floodlightcontroller.storage.IPredicate;
 import net.floodlightcontroller.storage.IQuery;
 import net.floodlightcontroller.storage.IResultSet;
 import net.floodlightcontroller.storage.IRowMapper;
-import net.floodlightcontroller.storage.IStorageSource;
 import net.floodlightcontroller.storage.IStorageSourceListener;
 import net.floodlightcontroller.storage.NullValueStorageException;
 import net.floodlightcontroller.storage.OperatorPredicate;
 import net.floodlightcontroller.storage.RowOrdering;
+import net.floodlightcontroller.storage.nosql.NoSqlStorageSource;
 import net.floodlightcontroller.test.FloodlightTestCase;
 
 import org.junit.Test;
 
 public abstract class StorageTest extends FloodlightTestCase {
     
-    protected IStorageSource storageSource;
+    protected NoSqlStorageSource storageSource;
+    protected RestApiServer restApi;
     
     protected String PERSON_TABLE_NAME = "Person";
     
@@ -138,9 +140,10 @@ public abstract class StorageTest extends FloodlightTestCase {
         }
     }
     
-    public void setUp() {
+    public void setUp() throws Exception {
         super.setUp();
-        PktinProcessingTime pktinProcessingTime = new PktinProcessingTime();
+        PktInProcessingTime pktinProcessingTime = new PktInProcessingTime();
+        pktinProcessingTime.startUp(null);
         storageSource.setPktinProcessingTime(pktinProcessingTime);
         Set<String> indexedColumnNames = new HashSet<String>();
         indexedColumnNames.add(PERSON_LAST_NAME);
diff --git a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
index 46a0ede9763abfbfaa59db7505ff532d9e947f33..ac711dbd3837d2109c45905761798df975cef2e1 100644
--- a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
+++ b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
@@ -19,7 +19,7 @@ package net.floodlightcontroller.test;
 
 import junit.framework.TestCase;
 import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProvider;
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.test.MockFloodlightProvider;
 import net.floodlightcontroller.packet.Ethernet;
 
@@ -34,8 +34,6 @@ import org.openflow.protocol.OFType;
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
 public class FloodlightTestCase extends TestCase {
-
-
     protected MockFloodlightProvider mockFloodlightProvider;
 
     public MockFloodlightProvider getMockFloodlightProvider() {
@@ -56,15 +54,15 @@ public class FloodlightTestCase extends TestCase {
             OFPacketIn pi = (OFPacketIn)m;
             Ethernet eth = new Ethernet();
             eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length);
-            IFloodlightProvider.bcStore.put(bc, 
-                    IFloodlightProvider.CONTEXT_PI_PAYLOAD, 
+            IFloodlightProviderService.bcStore.put(bc, 
+                    IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
                     eth);
         }
         return bc;
     }
     
     @Override
-    public void setUp() {
+    public void setUp() throws Exception {
         mockFloodlightProvider = new MockFloodlightProvider();
     }
  
diff --git a/src/test/java/net/floodlightcontroller/topology/internal/TopologyImplTest.java b/src/test/java/net/floodlightcontroller/topology/internal/TopologyImplTest.java
index 399bc3af6f9c076ed10c073a0c171d2f843f3b3b..eb6a3f58d197a28bba5a26427a138cc213efb0ce 100644
--- a/src/test/java/net/floodlightcontroller/topology/internal/TopologyImplTest.java
+++ b/src/test/java/net/floodlightcontroller/topology/internal/TopologyImplTest.java
@@ -33,11 +33,16 @@ import org.junit.Test;
 import org.openflow.protocol.OFPortStatus;
 import org.openflow.protocol.OFPhysicalPort;
 
+import net.floodlightcontroller.core.IFloodlightProviderService;
 import net.floodlightcontroller.core.IOFSwitch;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.routing.IRoutingEngineService;
 import net.floodlightcontroller.routing.dijkstra.RoutingImpl;
+import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.memory.MemoryStorageSource;
 import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.topology.ITopologyAware;
+import net.floodlightcontroller.topology.ITopologyListener;
+import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.topology.LinkInfo;
 import net.floodlightcontroller.topology.LinkTuple;
 
@@ -59,17 +64,20 @@ public class TopologyImplTest extends FloodlightTestCase {
     }
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         super.setUp();
+        FloodlightModuleContext cntx = new FloodlightModuleContext();
         topology = new TopologyImpl();
-        topology.setFloodlightProvider(getMockFloodlightProvider());
-        topology.setStorageSource(new MemoryStorageSource());
         RoutingImpl routingEngine = new RoutingImpl();
-        topology.setRoutingEngine(routingEngine);
-        ArrayList<ITopologyAware> topologyAware = new ArrayList<ITopologyAware>();
-        topologyAware.add(routingEngine);
-        topology.setTopologyAware(topologyAware);
-        topology.startUp();
+        topology.topologyAware = new ArrayList<ITopologyListener>();
+        cntx.addService(IRoutingEngineService.class, routingEngine);
+        cntx.addService(ITopologyService.class, topology);
+        cntx.addService(IStorageSourceService.class, new MemoryStorageSource());
+        cntx.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
+        routingEngine.init(cntx);
+        topology.init(cntx);
+        routingEngine.startUp(cntx);
+        topology.startUp(cntx);
     }
 
     @Test