From 8393667f500ba486673ccd7885559d00283ab393 Mon Sep 17 00:00:00 2001
From: Alex Reimers <alex@bigswitch.com>
Date: Fri, 27 Jan 2012 16:18:39 -0800
Subject: [PATCH] Finished module loading system (execpt for all the things
 that don't work yet).

---
 ...htcontroller.core.module.IFloodlightModule |   7 +
 .../floodlightcontroller/core/CoreModule.java |  44 ++-
 ...r.java => IFloodlightProviderService.java} |   7 +-
 .../core/IOFMessageFilterManagerService.java  |  10 +
 .../net/floodlightcontroller/core/Main.java   |   7 +-
 .../core/OFMessageFilterManager.java          | 114 ++++---
 .../core/internal/Controller.java             | 287 ++++++-----------
 .../core/internal/OFMessageFuture.java        |   8 +-
 .../core/internal/OFStatisticsFuture.java     |   6 +-
 .../core/internal/OFSwitchImpl.java           |   6 +-
 .../TerminationStorageExceptionHandler.java   |   6 +-
 .../core/module/FloodlightModuleContext.java  |  50 +--
 .../core/module/FloodlightModuleLoader.java   | 218 ++++++++-----
 .../core/module/IFloodlightModule.java        |  23 +-
 .../core/module/IFloodlightModuleContext.java |  15 +-
 .../core/web/AllSwitchStatisticsResource.java |   6 +-
 .../core/web/ControllerSwitchesResource.java  |   4 +-
 .../core/web/CounterResource.java             |  10 +-
 .../core/web/CounterResourceBase.java         |   6 +-
 .../core/web/SwitchClustersResource.java      |   4 +-
 .../web/SwitchCounterCategoriesResource.java  |   8 +-
 .../core/web/SwitchCounterResource.java       |  12 +-
 .../core/web/SwitchResourceBase.java          |   6 +-
 .../core/web/SwitchStatisticsResource.java    |   4 +-
 .../counter/ConcurrentCounter.java            |   4 +-
 .../counter/CountBuffer.java                  |   2 +-
 .../counter/CountSeries.java                  |   2 +-
 .../counter/CounterStore.java                 |  50 +--
 .../{ICounterService.java => ICounter.java}   |   4 +-
 .../counter/ICounterStoreService.java         |  43 +++
 .../counter/SimpleCounter.java                |   4 +-
 .../devicemanager/IDeviceManagerService.java  |   6 +
 .../internal/DeviceManagerImpl.java           | 167 ++++++----
 .../forwarding/Forwarding.java                |  67 +++-
 .../net/floodlightcontroller/hub/Hub.java     |   6 +-
 .../learningswitch/LearningSwitch.java        |  17 +-
 .../routing/ForwardingBase.java               |  30 +-
 ...Engine.java => IRoutingEngineService.java} |   3 +-
 .../routing/dijkstra/RoutingImpl.java         |  88 ++++--
 .../IStaticFlowEntryPusherService.java        |   3 +-
 .../StaticFlowEntryPusher.java                | 107 ++++---
 .../storage/AbstractStorageSource.java        |  18 +-
 .../storage/memory/MemoryStorageSource.java   |  47 ++-
 .../storage/nosql/NoSqlStorageSource.java     |   7 -
 .../topology/ITopologyService.java            |   7 +-
 .../topology/internal/TopologyImpl.java       | 292 +++++++++---------
 .../core/internal/ControllerTest.java         |   4 +-
 .../core/test/MockFloodlightProvider.java     |   8 +-
 .../internal/DeviceManagerImplTest.java       |   2 +-
 .../forwarding/ForwardingTest.java            |  10 +-
 .../StaticFlowEntryPusherTest.java            |   4 +-
 .../test/FloodlightTestCase.java              |   6 +-
 52 files changed, 1095 insertions(+), 781 deletions(-)
 rename src/main/java/net/floodlightcontroller/core/{IFloodlightProvider.java => IFloodlightProviderService.java} (96%)
 create mode 100644 src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java
 rename src/main/java/net/floodlightcontroller/counter/{ICounterService.java => ICounter.java} (93%)
 create mode 100644 src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java
 rename src/main/java/net/floodlightcontroller/routing/{IRoutingEngine.java => IRoutingEngineService.java} (94%)

diff --git a/src/main/java/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/java/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index adb57d6b7..9d4a19046 100644
--- a/src/main/java/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/java/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -1 +1,8 @@
 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
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/core/CoreModule.java b/src/main/java/net/floodlightcontroller/core/CoreModule.java
index 67a9680b9..0dc6d9de1 100644
--- a/src/main/java/net/floodlightcontroller/core/CoreModule.java
+++ b/src/main/java/net/floodlightcontroller/core/CoreModule.java
@@ -2,48 +2,64 @@ 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.counter.CounterStore;
+import net.floodlightcontroller.counter.ICounterStoreService;
+import net.floodlightcontroller.storage.IStorageSourceService;
 
 public class CoreModule implements IFloodlightModule {
-    protected static Collection<Class<? extends IFloodlightService>> services;
     Controller controller;
     
-    static {
-        services = new ArrayList<Class<? extends IFloodlightService>>(1);
-        services.add(IFloodlightProvider.class);
-    }
-    
     @Override
     public Collection<Class<? extends IFloodlightService>> getServices() {
+        Collection<Class<? extends IFloodlightService>> services =
+                new ArrayList<Class<? extends IFloodlightService>>(2);
+        services.add(IFloodlightProviderService.class);
+        services.add(ICounterStoreService.class);
         return services;
     }
 
     @Override
-    public Collection<IFloodlightService> getServiceImpls() {
-        Collection<IFloodlightService> l = new ArrayList<IFloodlightService>(1);
+    public Map<Class<? extends IFloodlightService>,
+               IFloodlightService> getServiceImpls() {
         controller = new Controller();
-        l.add(controller);
-        return l;
+        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<? extends IFloodlightService> getDependencies() {
-        return null;
+    public Collection<Class<? extends IFloodlightService>> getDependencies() {
+        Collection<Class<? extends IFloodlightService>> dependencies =
+            new ArrayList<Class<? extends IFloodlightService>>(1);
+        dependencies.add(IStorageSourceService.class);
+        return dependencies;
     }
 
     @Override
     public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+        IStorageSourceService storage = 
+                (IStorageSourceService)
+                context.getServiceImpl(IStorageSourceService.class);
+        controller.setStorageSourceService(storage);
         controller.init();
     }
 
     @Override
     public void startUp(FloodlightModuleContext context) {
         controller.startupComponents();
-        controller.run();
     }
-
 }
diff --git a/src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
similarity index 96%
rename from src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java
rename to src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
index a9547e84f..5980ba9f1 100644
--- a/src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java
+++ b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java
@@ -33,7 +33,7 @@ import org.openflow.protocol.factory.BasicFactory;
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public interface IFloodlightProvider extends IFloodlightService {
+public interface IFloodlightProviderService extends IFloodlightService {
 
     /**
      * A value stored in the floodlight context containing a parsed packet
@@ -133,4 +133,9 @@ public interface IFloodlightProvider extends IFloodlightService {
      * @return an OpenFlow message factory
      */
     public BasicFactory getOFMessageFactory();
+
+    /**
+     * Run the main I/O loop of the Controller.
+     */
+    public void run();
 }
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 000000000..df77cdf45
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java
@@ -0,0 +1,10 @@
+package net.floodlightcontroller.core;
+
+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
index f217118b3..d681f8ee9 100644
--- a/src/main/java/net/floodlightcontroller/core/Main.java
+++ b/src/main/java/net/floodlightcontroller/core/Main.java
@@ -2,6 +2,7 @@ package net.floodlightcontroller.core;
 
 import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.core.module.FloodlightModuleLoader;
+import net.floodlightcontroller.core.module.IFloodlightModuleContext;
 
 /**
  * Host for the Floodlight main method
@@ -19,7 +20,9 @@ public class Main {
                 "org.restlet.ext.slf4j.Slf4jLoggerFacade");
         
         FloodlightModuleLoader fml = new FloodlightModuleLoader();
-        fml.loadModulesFromConfig();
+        IFloodlightModuleContext moduleContext = fml.loadModulesFromConfig();
+        IFloodlightProviderService controller =
+                moduleContext.getServiceImpl(IFloodlightProviderService.class);
+        controller.run();
     }
-
 }
diff --git a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
index b096f79cc..4cde652ce 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,14 @@ 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.packet.Ethernet;
 import net.floodlightcontroller.packetstreamer.thrift.*;
 
-public class OFMessageFilterManager implements IOFMessageListener {
+public class OFMessageFilterManager 
+        implements IOFMessageListener, IFloodlightModule, IOFMessageFilterManagerService {
 
     /**
      * @author Srini
@@ -65,7 +71,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 +97,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 +199,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 +253,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 +440,7 @@ public class OFMessageFilterManager implements IOFMessageListener {
         }
     }
 
+    @Override
     public String getDataAsString(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
 
         Ethernet eth;
@@ -495,8 +472,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());
                 }
@@ -526,8 +503,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());
                 }
@@ -561,4 +538,63 @@ public class OFMessageFilterManager implements IOFMessageListener {
         return this.getDataAsString(sw, msg, cntx).getBytes();
     }
 
+    // IFloodlightModule methods
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getServices() {
+        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>> getDependencies() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IFloodlightProviderService.class);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context) 
+            throws FloodlightModuleException {
+        if (log.isDebugEnabled()) {
+            log.debug("Init " + this.getClass().getCanonicalName());
+        }
+
+        
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // This is our 'constructor'
+        if (log.isDebugEnabled()) {
+            log.debug("Starting " + this.getClass().getCanonicalName());
+        }
+        this.floodlightProvider = 
+                context.getServiceImpl(IFloodlightProviderService.class);
+        if (this.floodlightProvider == null) {
+            System.out.println("FLOODLIGHTPROVDIER IS NUL!!!!!");
+        }
+        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/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 7ce555637..dd8bea7e7 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -25,7 +25,6 @@ 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,14 +45,13 @@ 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.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;
@@ -61,26 +59,19 @@ 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.ICounterService;
+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.storage.IResultSet;
 import net.floodlightcontroller.storage.IStorageExceptionHandler;
 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.ITopologyListener;
-import net.floodlightcontroller.topology.internal.TopologyImpl;
 import net.floodlightcontroller.topology.web.TopologyWebRouteable;
 
 import org.jboss.netty.bootstrap.ServerBootstrap;
@@ -100,8 +91,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;
@@ -150,7 +139,7 @@ import org.slf4j.LoggerFactory;
  */
 public class Controller
     extends Application
-    implements IFloodlightProvider, IOFController {
+    implements IFloodlightProviderService, IOFController {
     
     protected static Logger log = LoggerFactory.getLogger(Controller.class);
     
@@ -161,19 +150,14 @@ public class Controller
     protected ConcurrentHashMap<Long, IOFSwitch> switches;
     protected Set<IOFSwitchListener> switchListeners;
     protected BlockingQueue<Update> updates;
-    protected CounterStore counterStore;
+    protected ICounterStoreService counterStore;
 
     protected ScheduledExecutorService executor = 
             Executors.newScheduledThreadPool(5);
     
     protected IStorageSourceService storageSource;
-    protected TopologyImpl topology;
-    protected DeviceManagerImpl deviceManager;
-    protected RoutingImpl routingEngine;
-    protected Forwarding forwarding;
-    protected OFMessageFilterManager messageFilterManager;
+    //protected IOFMessageFilterManagerService messageFilterManager;
     protected PktinProcessingTime pktinProcTime;
-    private StaticFlowEntryPusher staticFlowEntryPusher;
     protected long ptWarningThresholdInNano;
     
     protected List<RestletRoutable> restlets;
@@ -240,6 +224,18 @@ public class Controller
         this.moduleFile = settings.getModuleFile();
     }
     
+    // ***************
+    // Getters/Setters
+    // ***************
+    
+    public void setStorageSourceService(IStorageSourceService storageSource) {
+        this.storageSource = storageSource;
+    }
+    
+    public void setCounterStore(ICounterStoreService counterStore) {
+        this.counterStore = counterStore;
+    }
+    
     // **********************
     // ChannelUpstreamHandler
     // **********************
@@ -657,28 +653,28 @@ public class Controller
                                                NetworkLayer.L3);
         
         try {
-            ICounterService portCounter = 
+            ICounter portCounter = 
                     counterStore.getCounter(portCounterName);
             if (portCounter == null) {
                 portCounter = 
                         counterStore.createCounter(portCounterName, 
                                                    CounterType.LONG);
             }
-            ICounterService switchCounter = 
+            ICounter switchCounter = 
                     counterStore.getCounter(switchCounterName);
             if (switchCounter == null) {
                 switchCounter = 
                         counterStore.createCounter(switchCounterName, 
                                                    CounterType.LONG);
             }
-            ICounterService portL3Counter = 
+            ICounter portL3Counter = 
                     counterStore.getCounter(portL3CategoryCounterName);
             if (portL3Counter == null) {
                 portL3Counter = 
                         counterStore.createCounter(portL3CategoryCounterName,
                                                    CounterType.LONG);
             }
-            ICounterService switchL3Counter = 
+            ICounter switchL3Counter = 
                     counterStore.getCounter(switchL3CategoryCounterName);
             if (switchL3Counter == null) {
                 switchL3Counter = 
@@ -690,7 +686,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 && 
@@ -712,14 +708,14 @@ public class Controller
                                                        l4Type, 
                                                        NetworkLayer.L4);
                 
-                ICounterService portL4Counter = 
+                ICounter portL4Counter = 
                         counterStore.getCounter(portL4CategoryCounterName);
                 if (portL4Counter == null) {
                     portL4Counter = 
                             counterStore.createCounter(portL4CategoryCounterName, 
                                                        CounterType.LONG);
                 }
-                ICounterService switchL4Counter = 
+                ICounter switchL4Counter = 
                         counterStore.getCounter(switchL4CategoryCounterName);
                 if (switchL4Counter == null) {
                     switchL4Counter = 
@@ -780,8 +776,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);
                     }
                     
@@ -789,10 +785,10 @@ public class Controller
                     // The context would have the necessary information for
                     // the OFMessageFilterManager's getDataToString to work
                     // for packet-ins.
-                    if (log.isDebugEnabled()) {
-                        String str = messageFilterManager.getDataAsString(sw, m, bc);
-                        log.trace("{}", str);
-                    }
+                    //if (log.isDebugEnabled()) {
+                    //    String str = messageFilterManager.getDataAsString(sw, m, bc);
+                    //    log.trace("{}", str);
+                    //}
 
 
                     // Get the starting time (overall and per-component) of 
@@ -828,8 +824,8 @@ public class Controller
                 long processingTime = System.nanoTime() - startTime;
                 if (ptWarningThresholdInNano > 0 && processingTime > ptWarningThresholdInNano) {
                     log.warn("Time to process packet-in: {} us", processingTime/1000.0);
-                    if (eth != null)
-                        log.warn("{}", messageFilterManager.getDataAsString(sw, m, bContext));
+                    //if (eth != null)
+                    //    log.warn("{}", messageFilterManager.getDataAsString(sw, m, bContext));
                 }
         }
     }
@@ -1059,10 +1055,10 @@ public class Controller
     @Override
     public void handleOutgoingMessage(IOFSwitch sw, OFMessage m,
                                       FloodlightContext bc) {
-        if (log.isDebugEnabled()) {
-            String str = messageFilterManager.getDataAsString(sw, m, bc);
-            log.trace("{}", str);
-        }
+        //if (log.isDebugEnabled()) {
+        //    String str = messageFilterManager.getDataAsString(sw, m, bc);
+        //    log.trace("{}", str);
+        //}
 
         List<IOFMessageListener> listeners = null;
         if (messageListeners.containsKey(m.getType())) {
@@ -1135,58 +1131,6 @@ public class Controller
     // **************
     // 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(IStorageSourceService 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();
@@ -1252,17 +1196,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>();
@@ -1430,78 +1363,20 @@ public class Controller
      * new components
      */
     public 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);        
-        
-        HashSet<ITopologyListener> topologyAware = new HashSet<ITopologyListener>();
-        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() {
-        storageSource = new 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);
+        JacksonCustomConverter.replaceConverter();        
     }
     
     /**
      * Initialize the rest context
      */
     protected void initRestContext(Context context) {
+        /*
         context.getAttributes().put("floodlightProvider", this);
         context.getAttributes().put("counterStore", counterStore);
         context.getAttributes().put("storageSource", storageSource);
@@ -1514,35 +1389,55 @@ public class Controller
                                         staticFlowEntryPusher);
         }
         context.getAttributes().put("topology", topology);
+        */
     }
     
     /**
      * Startup all of the controller's components
      */
     public void startupComponents() {
-        // now, do our own init
-        try {
-            log.debug("Doing controller internal setup");
-            this.startUp();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
+        log.debug("Doing controller internal setup");
+        // Set floodlight to terminate on a storage exception
+        IStorageExceptionHandler handler = 
+                new TerminationStorageExceptionHandler(this);
+        storageSource.setExceptionHandler(handler);
+        
+        // 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);
+        
+        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();
+        
+        // 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);
         }
         
-        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();
     }
@@ -1553,15 +1448,15 @@ public class Controller
     protected void debugserver_start() {
         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();
@@ -1571,6 +1466,7 @@ public class Controller
      * 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");
@@ -1584,9 +1480,10 @@ public class Controller
             System.exit(1);
         }
 
-        Controller controller = new Controller(settings);
-        controller.init();
-        controller.startupComponents();
-        controller.run();
+        //Controller controller = new Controller(settings);
+        //controller.init();
+        //controller.startupComponents();
+        //controller.run();
     }
+    */
 }
diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java b/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java
index 443568280..9f8b30e14 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 6c9870c51..306d38eea 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 afdd7beb9..811699133 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;
@@ -273,7 +273,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 111dc2917..9b27ae1db 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
index 309a94bdf..4041cfdc1 100644
--- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java
@@ -1,10 +1,7 @@
 package net.floodlightcontroller.core.module;
 
-import java.util.ArrayList;
-import java.util.Collection;
+import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
 import net.floodlightcontroller.core.IFloodlightService;
 
 /**
@@ -13,51 +10,32 @@ import net.floodlightcontroller.core.IFloodlightService;
  */
 public class FloodlightModuleContext implements IFloodlightModuleContext {
 	protected Map<Class<? extends IFloodlightService>, IFloodlightService> serviceMap;
-	protected Collection<IFloodlightModule> modules;
 	
 	/**
 	 * Creates the ModuleContext for use with this IFloodlightProvider.
 	 * This will be used as a module registry for all IFloodlightModule(s).
 	 */
 	public FloodlightModuleContext() {
-		serviceMap = new ConcurrentHashMap<Class<? extends IFloodlightService>, IFloodlightService>();
-		modules = new ArrayList<IFloodlightModule>();
+		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
-	 * @param name The fully qualified name for the module that describes 
-	 * the service it provides, i.e. "deviceManager.floodlight"
-	 */
-	public void addService(IFloodlightService service) {
-		Class<? extends IFloodlightService> serviceClass = service.getClass();
-		serviceMap.put(serviceClass, service);
-	}
-	
-	/**
-	 * 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 IFloodlightService getService(Class<? extends IFloodlightService> service) {
-		return serviceMap.get(service);
+	public void addService(Class<? extends IFloodlightService> clazz, 
+	                       IFloodlightService service) {
+		serviceMap.put(clazz, service);
 	}
 	
-	/**
-	 * Add a module to the list of initialized modules
-	 * @param module
-	 */
-	public void addModule(IFloodlightModule module) {
-	    modules.add(module);
-	}
+	@SuppressWarnings("unchecked")
+    @Override
+	public <T extends IFloodlightService> T getServiceImpl(Class<T> service) {
+	    IFloodlightService s = serviceMap.get(service);
+		return (T)s;
+	}  
 
-	/**
-	 * Get the list of initialized modules.
-	 * @return the list of modules that have been initialized
-	 */
-	public Collection<IFloodlightModule> getModules() {
-	    return modules;
-	}
  }
diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
index 3681ef26a..7e8ef4946 100644
--- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
+++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java
@@ -3,8 +3,11 @@ package net.floodlightcontroller.core.module;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.ServiceLoader;
+import java.util.Set;
 
 import net.floodlightcontroller.core.IFloodlightService;
 
@@ -21,8 +24,11 @@ public class FloodlightModuleLoader {
             LoggerFactory.getLogger(FloodlightModuleLoader.class);
 
     protected FloodlightModuleContext floodlightModuleContext;
-	protected Map<Class<? extends IFloodlightService>,
-	              Collection<IFloodlightModule>> serviceMap;
+    protected Map<Class<? extends IFloodlightService>,
+                  Collection<IFloodlightModule>> serviceMap;
+    protected Map<IFloodlightModule,
+                  Collection<Class<? extends 
+                                   IFloodlightService>>> moduleServiceMap;
 	protected Map<String, IFloodlightModule> moduleNameMap;
 	
 	public FloodlightModuleLoader() {
@@ -30,17 +36,13 @@ public class FloodlightModuleLoader {
 		serviceMap = 
 		        new HashMap<Class<? extends IFloodlightService>,
                             Collection<IFloodlightModule>>();
+		moduleServiceMap = 
+		        new HashMap<IFloodlightModule,
+                            Collection<Class<? extends 
+                                       IFloodlightService>>>();
 		moduleNameMap = new HashMap<String, IFloodlightModule>();
 	}
 	
-	public IFloodlightModuleContext getModules() 
-	        throws FloodlightModuleException {
-	    findAllModules();
-	    
-	    
-	    return floodlightModuleContext;
-	}
-	
 	/**
 	 * Finds all IFloodlightModule(s) in the classpath.
 	 */
@@ -50,7 +52,9 @@ public class FloodlightModuleLoader {
             = ServiceLoader.load(IFloodlightModule.class);
 	    // Iterate for each module, iterate through and add it's services
 	    for (IFloodlightModule m : moduleLoader) {
-	        logger.debug("Found module " + m.getClass().getName());
+	        if (logger.isDebugEnabled()) {
+	            logger.debug("Found module " + m.getClass().getName());
+	        }
 
 	        // Set up moduleNameMap
 	        moduleNameMap.put(m.getClass().getCanonicalName(), m);
@@ -59,6 +63,7 @@ public class FloodlightModuleLoader {
 	        Collection<Class<? extends IFloodlightService>> servs =
 	                m.getServices();
 	        if (servs != null) {
+	            moduleServiceMap.put(m, servs);
 	            for (Class<? extends IFloodlightService> s : servs) {
 	                Collection<IFloodlightModule> mods = 
 	                        serviceMap.get(s);
@@ -72,76 +77,143 @@ public class FloodlightModuleLoader {
 	    }
 	}
 	
-	public void loadModulesFromConfig() throws FloodlightModuleException {
+	public IFloodlightModuleContext loadModulesFromConfig() 
+	        throws FloodlightModuleException {
+	    logger.debug("Starting module loader");
 	    findAllModules();
-	    initModule("net.floodlightcontroller.core.CoreModule");
-	    startupModules();
 	    
-	    /*
-	     * first read modules.json
-	     * go through modules 1 by 1
-	     *     take name of module
-	     *     call loadModules();
-	     *     call module.init();
-	     *      
-	     *  for each module:
-	     *     call module.startUp();
-	     * 
-	     */
+	    Set<IFloodlightModule> moduleSet = new HashSet<IFloodlightModule>();
+	    Map<Class<? extends IFloodlightService>, IFloodlightModule> moduleMap =
+                new HashMap<Class<? extends IFloodlightService>,
+                            IFloodlightModule>();
+	    
+	    calculateModuleDeps(moduleMap, moduleSet, "net.floodlightcontroller.core.CoreModule");
+	    calculateModuleDeps(moduleMap, moduleSet, "net.floodlightcontroller.forwarding.Forwarding");
+	    calculateModuleDeps(moduleMap, moduleSet, "net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher");
+	    calculateModuleDeps(moduleMap, moduleSet, "net.floodlightcontroller.core.OFMessageFilterManager");
+	    
+	    initModules(moduleSet);
+	    startupModules(moduleSet);
+	    
+	    return floodlightModuleContext;
 	}
 	
-	protected void startupModules() {
-	    for (IFloodlightModule m : floodlightModuleContext.getModules()) {
-	        m.startUp(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);
+        }
 	}
+	
+	/**
+	 * Add a module and all its transitive dependencies
+	 * @param moduleMap the module map
+	 * @param moduleSet the module set
+	 * @param moduleName the module name
+	 * @throws FloodlightModuleException
+	 */
+    protected void calculateModuleDeps(Map<Class<? extends IFloodlightService>, 
+                                           IFloodlightModule> moduleMap,
+                                       Set<IFloodlightModule> moduleSet,
+                                       String moduleName) throws FloodlightModuleException {
 
-    protected void initModule(String moduleName) throws FloodlightModuleException {
-	    IFloodlightModule module = moduleNameMap.get(moduleName);
-	    if (module == null) {
-	        throw new FloodlightModuleException("Module " + 
-	                                            moduleName + " not found");
-	    }
-	    Collection<? extends IFloodlightService> deps = 
-	            module.getDependencies();
-	    if (deps != null) {
-	        for (IFloodlightService dep : deps) {
-	            Class<? extends IFloodlightService> c = dep.getClass();
-	            IFloodlightService s = floodlightModuleContext.getService(c);
-	            if (s == null) {
-	                Collection<IFloodlightModule> mods = serviceMap.get(dep);
-	                // Make sure only one module is loaded
-	                if ((mods == null) || (mods.size() == 0)) {
-	                    throw new FloodlightModuleException("ERROR! Could not " + 
-	                            "find IFloodlightModule that provides service " +
-	                            dep.getClass().toString());
-	                } else if (mods.size() == 1) {
-	                    // Recursively load the module's dependencies recursively
-	                    initModule(mods.iterator().next().getClass().toString());
-	                } else {
-	                    throw new FloodlightModuleException("ERROR! Found more " + 
-	                            "than one IFloodlightModule that provides " + 
-	                            "service " + dep.getClass().toString() + 
-	                            ". Please resolve this in the config");
-	                }
-	            }
-	            // else it's already loaded
-	        }
-	    }
-	    
-	    // Get the module's service impls
-	    Collection<IFloodlightService> simpls =
-	            module.getServiceImpls();
+        IFloodlightModule module = moduleNameMap.get(moduleName);
+        if (module == null) {
+            throw new FloodlightModuleException("Module " + 
+                    moduleName + " not found");
+        }
+
+        addModule(moduleMap, moduleSet, module);
         
-	    // init the module
-        module.init(floodlightModuleContext);
+        Collection<Class<? extends IFloodlightService>> deps = 
+                module.getDependencies();
 
-        // add the module's services to the context
-        floodlightModuleContext.addModule(module);
-        if (simpls != null) {
-            for (IFloodlightService s : simpls) {
-                floodlightModuleContext.addService(s);
+        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)) {
+                        throw new FloodlightModuleException("ERROR! Could not " +
+                                "find an IFloodlightModule that provides service " +
+                                c.toString());
+                    } else if (mods.size() == 1) {
+                        IFloodlightModule mod = mods.iterator().next();
+                        calculateModuleDeps(moduleMap, moduleSet,
+                                            mod.getClass().getCanonicalName());
+                    } else {
+                        throw new FloodlightModuleException("ERROR! Found more " + 
+                                "than one IFloodlightModule that provides " + 
+                                "service " + c.toString() + 
+                                ". Please resolve this in the config");
+                    }
+                }
+            }
+        } 
+    }
+
+    /**
+     * Allocate service implementations and then init all the modules
+     * @param moduleMap
+     * @throws FloodlightModuleException
+     */
+    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
index ee307fc77..aede7bec9 100644
--- a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java
+++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java
@@ -1,6 +1,7 @@
 package net.floodlightcontroller.core.module;
 
 import java.util.Collection;
+import java.util.Map;
 
 import net.floodlightcontroller.core.IFloodlightService;
 
@@ -27,22 +28,32 @@ public interface IFloodlightModule {
 	
 	public Collection<Class<? extends IFloodlightService>> getServices();
 	
-	public Collection<IFloodlightService> getServiceImpls();
+	/**
+	 * 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
+	 * 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<? extends IFloodlightService> getDependencies();
+	public Collection<Class<? extends IFloodlightService>> getDependencies();
 	
 	/**
 	 * 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.
+	 * All module dependencies are resolved when this is called, but not every module 
+	 * is initialized.
 	 * 
 	 * @param context
 	 * @throws FloodlightModuleException
diff --git a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java
index 6be257a52..75bcfb112 100644
--- a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java
+++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java
@@ -3,11 +3,12 @@ package net.floodlightcontroller.core.module;
 import net.floodlightcontroller.core.IFloodlightService;
 	
 public interface IFloodlightModuleContext {	
-	//TODO FIX THIS COMMENT
-	/**
-	 * Retrieves a casted version of a module from the registry.
-	 * @return The module casted to the correct type
-	 */
-	public IFloodlightService getService(
-			Class<? extends IFloodlightService> service);
+    /**
+     * 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);
 }
diff --git a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java
index 2ef32f13d..0c880736b 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,7 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase {
             return model;
         }
         
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();        
+        IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication();        
         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 +167,7 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase {
         }
         
         public void run() {
-            IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();        
+            IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication();        
 
             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 b2d903a6e..026382a6c 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;
@@ -37,7 +37,7 @@ public class ControllerSwitchesResource extends ServerResource {
     public List<Map<String, String>> retrieve() {
         List<Map<String, String>> switchIds = new ArrayList<Map<String, String>>();        
 
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication();
         Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches();
 
         for (IOFSwitch s: switches.values()) {
diff --git a/src/main/java/net/floodlightcontroller/core/web/CounterResource.java b/src/main/java/net/floodlightcontroller/core/web/CounterResource.java
index 124cd5b16..fb680d7c9 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CounterResource.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CounterResource.java
@@ -23,7 +23,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 
 import net.floodlightcontroller.counter.CounterValue;
-import net.floodlightcontroller.counter.ICounterService;
+import net.floodlightcontroller.counter.ICounter;
 
 import org.restlet.resource.Get;
 
@@ -35,12 +35,12 @@ public class CounterResource extends CounterResourceBase {
         Map<String, Object> model = new HashMap<String,Object>();
         CounterValue v;
         if (counterTitle.equalsIgnoreCase("all")) {
-            Map<String, ICounterService> counters = this.counterStore.getAll();
+            Map<String, ICounter> counters = this.counterStore.getAll();
             if (counters != null) {
-                Iterator<Map.Entry<String, ICounterService>> it = 
+                Iterator<Map.Entry<String, ICounter>> it = 
                     counters.entrySet().iterator();
                 while (it.hasNext()) {
-                    Entry<String, ICounterService> entry = it.next();
+                    Entry<String, ICounter> entry = it.next();
                     String counterName = entry.getKey();
                     v = entry.getValue().getCounterValue();
 
@@ -52,7 +52,7 @@ public class CounterResource extends CounterResourceBase {
                 }   
             }   
         } else {
-            ICounterService counter = this.counterStore.getCounter(counterTitle);
+            ICounter counter = this.counterStore.getCounter(counterTitle);
             if (counter != null) {
                 v = counter.getCounterValue();
             } else {
diff --git a/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java
index e27b0ae31..f61cd079f 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java
@@ -17,18 +17,18 @@
 
 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("counterStore");
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java
index c3d8ae6ac..2b8166343 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,7 @@ 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)getApplication();
         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 dbce9f088..39d5db579 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,7 @@ 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)getApplication();
         HashMap<String,Object> model = new HashMap<String,Object>();
         
         String switchID = (String) getRequestAttributes().get("switchId");
@@ -69,7 +69,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 a371cd892..e9625fca3 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.counter.ICounterService;
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.counter.ICounter;
+import net.floodlightcontroller.counter.ICounterStoreService;
 
 /**
  * Get counters for a particular switch 
@@ -36,7 +36,7 @@ import net.floodlightcontroller.counter.ICounterService;
 public class SwitchCounterResource extends CounterResourceBase {
     @Get("json")
     public Map<String, Object> retrieve() {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication();
         HashMap<String,Object> model = new HashMap<String,Object>();
         
         String switchID = (String) getRequestAttributes().get("switchId");
@@ -63,12 +63,12 @@ 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
         }
 
-        ICounterService counter = this.counterStore.getCounter(fullCounterName);
+        ICounter counter = this.counterStore.getCounter(fullCounterName);
         Map<String, Long> sample = new HashMap<String, Long> ();
         if (counter != null) {
             sample.put(counter.getCounterDate().toString(), 
diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java
index 8c59a3407..3ac4e1e43 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,7 @@ public class SwitchResourceBase extends ServerResource {
     }
     
     protected List<OFStatistics> getSwitchStatistics(long switchId, OFStatisticsType statType) {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication();
         
         IOFSwitch sw = floodlightProvider.getSwitches().get(switchId);
         Future<List<OFStatistics>> future;
@@ -132,7 +132,7 @@ 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)getApplication();
 
         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 0f10c2538..42e5feafe 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,7 @@ public class SwitchStatisticsResource extends SwitchResourceBase {
 
     @Get("json")
     public Map<String, Object> retrieve() {
-        IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication();
+        IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication();
         
         HashMap<String,Object> result = new HashMap<String,Object>();
         List<OFStatistics> values = null;
diff --git a/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java b/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java
index 7a7443d0d..cdec1e0ed 100644
--- a/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java
+++ b/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java
@@ -53,7 +53,7 @@ import net.floodlightcontroller.counter.CounterValue.CounterType;
  * @author kyle
  *
  */
-public class ConcurrentCounter implements ICounterService {
+public class ConcurrentCounter implements ICounter {
 
   protected static final Map<DateSpan, Integer> MAX_HISTORY = new HashMap<DateSpan, Integer>();
   static {
@@ -110,7 +110,7 @@ public class ConcurrentCounter implements ICounterService {
    * @param startDate
    * @return
    */
-  public static ICounterService createCounter(Date startDate) {
+  public static ICounter createCounter(Date startDate) {
     ConcurrentCounter cc = new ConcurrentCounter(startDate);
     ConcurrentCounter.liveCounters.add(cc);
     return cc;
diff --git a/src/main/java/net/floodlightcontroller/counter/CountBuffer.java b/src/main/java/net/floodlightcontroller/counter/CountBuffer.java
index 7bd26a7c1..fa45862e8 100644
--- a/src/main/java/net/floodlightcontroller/counter/CountBuffer.java
+++ b/src/main/java/net/floodlightcontroller/counter/CountBuffer.java
@@ -19,7 +19,7 @@ package net.floodlightcontroller.counter;
 
 import java.util.Date;
 
-import net.floodlightcontroller.counter.ICounterService.DateSpan;
+import net.floodlightcontroller.counter.ICounter.DateSpan;
 
 
 /**
diff --git a/src/main/java/net/floodlightcontroller/counter/CountSeries.java b/src/main/java/net/floodlightcontroller/counter/CountSeries.java
index 0f06e8258..c94e5bc61 100644
--- a/src/main/java/net/floodlightcontroller/counter/CountSeries.java
+++ b/src/main/java/net/floodlightcontroller/counter/CountSeries.java
@@ -20,7 +20,7 @@ package net.floodlightcontroller.counter;
 import java.util.Arrays;
 import java.util.Date;
 
-import net.floodlightcontroller.counter.ICounterService.DateSpan;
+import net.floodlightcontroller.counter.ICounter.DateSpan;
 
 /**
  * Simple immutable class to store a series of historic counter values
diff --git a/src/main/java/net/floodlightcontroller/counter/CounterStore.java b/src/main/java/net/floodlightcontroller/counter/CounterStore.java
index a2c31e38b..585afc6a3 100644
--- a/src/main/java/net/floodlightcontroller/counter/CounterStore.java
+++ b/src/main/java/net/floodlightcontroller/counter/CounterStore.java
@@ -35,18 +35,13 @@ 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
     }
 
     protected class CounterEntry {
-        protected ICounterService counter;
+        protected ICounter counter;
         String title;
     }
 
@@ -56,8 +51,8 @@ public class CounterStore {
     protected Map<String, CounterEntry> nameToCEIndex = 
             new ConcurrentHashMap<String, CounterEntry>();
 
-    protected ICounterService heartbeatCounter;
-    protected ICounterService randomCounter;
+    protected ICounter heartbeatCounter;
+    protected ICounter randomCounter;
 
     /**
      * Counter Categories grouped by network layers
@@ -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,17 +127,10 @@ 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
-     */
-    public ICounterService createCounter(String key, CounterValue.CounterType type) {
+    @Override
+    public ICounter createCounter(String key, CounterValue.CounterType type) {
         CounterEntry ce;
-        ICounterService c;
+        ICounter c;
 
         if (!nameToCEIndex.containsKey(key)) {
             c = SimpleCounter.createCounter(new Date(), type);
@@ -175,10 +160,8 @@ public class CounterStore {
             }}, 100, 100, TimeUnit.MILLISECONDS);
     }
     
-    /**
-     * Retrieves a counter with the given title, or null if none can be found.
-     */
-    public ICounterService getCounter(String key) {
+    @Override
+    public ICounter getCounter(String key) {
         CounterEntry counter = nameToCEIndex.get(key);
         if (counter != null) {
             return counter.counter;
@@ -187,16 +170,15 @@ 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()
      */
-    public Map<String, ICounterService> getAll() {
-        Map<String, ICounterService> ret = new ConcurrentHashMap<String, ICounterService>();
+    @Override
+    public Map<String, ICounter> getAll() {
+        Map<String, ICounter> ret = new ConcurrentHashMap<String, ICounter>();
         for(Map.Entry<String, CounterEntry> counterEntry : this.nameToCEIndex.entrySet()) {
             String key = counterEntry.getKey();
-            ICounterService counter = counterEntry.getValue().counter;
+            ICounter counter = counterEntry.getValue().counter;
             ret.put(key, counter);
         }
         return ret;
diff --git a/src/main/java/net/floodlightcontroller/counter/ICounterService.java b/src/main/java/net/floodlightcontroller/counter/ICounter.java
similarity index 93%
rename from src/main/java/net/floodlightcontroller/counter/ICounterService.java
rename to src/main/java/net/floodlightcontroller/counter/ICounter.java
index 242273b54..625bebdc3 100644
--- a/src/main/java/net/floodlightcontroller/counter/ICounterService.java
+++ b/src/main/java/net/floodlightcontroller/counter/ICounter.java
@@ -23,13 +23,11 @@ package net.floodlightcontroller.counter;
 
 import java.util.Date;
 
-import net.floodlightcontroller.core.IFloodlightService;
-
 /**
  * @author kyle
  *
  */
-public interface ICounterService extends IFloodlightService {
+public interface ICounter {
   
   /**
    * Most commonly used method
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 000000000..3303198f7
--- /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.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/counter/SimpleCounter.java b/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java
index 34615ee09..d4aadaf83 100644
--- a/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java
+++ b/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java
@@ -32,7 +32,7 @@ import java.util.Date;
  * @author Kanzhe
  *
  */
-public class SimpleCounter implements ICounterService {
+public class SimpleCounter implements ICounter {
 
   protected CounterValue counter;
   protected Date samplingTime;
@@ -44,7 +44,7 @@ public class SimpleCounter implements ICounterService {
    * @param startDate
    * @return
    */
-  public static ICounterService createCounter(Date startDate, CounterValue.CounterType type) {
+  public static ICounter createCounter(Date startDate, CounterValue.CounterType type) {
     SimpleCounter cc = new SimpleCounter(startDate, type);
     return cc;
     
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java
index e7e6c6859..184a289a7 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java
@@ -67,4 +67,10 @@ public interface IDeviceManagerService extends IFloodlightService {
      * @return
      */
     public List<Device> getDevices();
+    
+    /**
+     * 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 88dc0ab7f..2ddc0772d 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -25,6 +25,7 @@ import java.util.Collections;
 import java.util.ConcurrentModificationException;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -39,10 +40,14 @@ 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.IFloodlightService;
 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.util.SingletonTask;
 import net.floodlightcontroller.devicemanager.Device;
 import net.floodlightcontroller.devicemanager.DeviceAttachmentPoint;
@@ -85,12 +90,7 @@ import org.slf4j.LoggerFactory;
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
 public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListener,
-        IOFSwitchListener, ITopologyListener {  
-    protected static Logger log = 
-        LoggerFactory.getLogger(DeviceManagerImpl.class);
-
-    protected IFloodlightProvider floodlightProvider;
-    
+        IOFSwitchListener, ITopologyListener, IFloodlightModule {      
     /**
      * Class to maintain all the device manager maps which consists of four
      * main maps. 
@@ -497,8 +497,10 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe
             // Now add this updated device to the maps, which will replace
             // the old copy
             updateMaps(dCopy);
-            log.debug("Device 1 {}", d);
-            log.debug("Device 2 {}", dCopy);
+            if (log.isDebugEnabled()) {
+                log.debug("Device 1 {}", d);
+                log.debug("Device 2 {}", dCopy);
+            }
             removeAttachmentPointFromStorage(d, dap);
             d = null; // to catch if anyone is using this reference
             return true;
@@ -540,12 +542,17 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe
         return devMgrMaps;
     }
 
+    protected static Logger log = 
+            LoggerFactory.getLogger(DeviceManagerImpl.class);
+
     protected Set<IDeviceManagerAware> deviceManagerAware;
+    protected LinkedList<Update> updates;
     protected ReentrantReadWriteLock lock;
     protected volatile boolean shuttingDown = false;
 
+    // Our dependencies
+    protected IFloodlightProviderService floodlightProvider;
     protected ITopologyService topology;
-    protected LinkedList<Update> updates;
     protected IStorageSourceService storageSource;
 
     protected Runnable deviceAgingTimer;
@@ -627,23 +634,6 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe
                 new EventHistory<OFMatch>("Pakcet-In");
     }
 
-    public void startUp() {
-        ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor();
-        deviceUpdateTask = new SingletonTask(ses, new DeviceUpdateWorker());
-
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-        floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this);
-        floodlightProvider.addOFSwitchListener(this);
-
-        /*
-         * Device and storage aging.
-         */
-        enableDeviceAgingTimer();
-
-        // Read all our device state (MACs, IPs, attachment points) from storage
-        readAllDeviceStateFromStorage();
-    }
-
     public void shutDown() {
         shuttingDown = true;
         floodlightProvider.removeOFMessageListener(OFType.PACKET_IN, this);
@@ -778,8 +768,8 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe
         Long dlAddr = Ethernet.toLong(match.getDataLayerSource());
         Short vlan = match.getDataLayerVirtualLan();
         if (vlan < 0) vlan = null;
-        Ethernet eth = IFloodlightProvider.bcStore.get(
-                                cntx, IFloodlightProvider.CONTEXT_PI_PAYLOAD);
+        Ethernet eth = IFloodlightProviderService.bcStore.get(
+                                cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
         int nwSrc = getSrcNwAddr(eth, dlAddr);
         Device device = devMgrMaps.getDeviceByDataLayerAddr(dlAddr);
         Date currentDate = new Date(); // TODO,
@@ -1068,7 +1058,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe
     /**
      * @param floodlightProvider the floodlightProvider to set
      */
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
+    public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
         this.floodlightProvider = floodlightProvider;
     }
 
@@ -1196,29 +1186,9 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe
     public void removedLink(IOFSwitch src, short srcPort, IOFSwitch dst, 
                                                                 short dstPort)
     {
+        // no-op
     }
-
-    /**
-     * @param deviceManagerAware the deviceManagerAware to set
-     */
-    public void setDeviceManagerAware(Set<IDeviceManagerAware> 
-                                                        deviceManagerAware) {
-        this.deviceManagerAware = deviceManagerAware;
-    }
-
-    public void setStorageSource(IStorageSourceService storageSource) {
-        this.storageSource = storageSource;
-        storageSource.createTable(DEVICE_TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(
-                        DEVICE_TABLE_NAME, MAC_COLUMN_NAME);
-        storageSource.createTable(DEVICE_ATTACHMENT_POINT_TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(
-                        DEVICE_ATTACHMENT_POINT_TABLE_NAME, ID_COLUMN_NAME);
-        storageSource.createTable(DEVICE_NETWORK_ADDRESS_TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(
-                        DEVICE_NETWORK_ADDRESS_TABLE_NAME, ID_COLUMN_NAME);
-    }
-
+    
     /**
      * Process device manager aware updates.  Call without any lock held
      */
@@ -1954,4 +1924,97 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe
     private void evHistPktIn(OFMatch packetIn) {
         evHistDevMgrPktIn.put(packetIn, EvAction.PKT_IN);
     }
+
+    // IFloodlightModule methods
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getServices() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IDeviceManagerService.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(IDeviceManagerService.class, this);
+        return m;
+    }
+
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getDependencies() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IFloodlightProviderService.class);
+        l.add(IStorageSourceService.class);
+        l.add(ITopologyService.class);
+        return l;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+            throws FloodlightModuleException {
+        // Wire up all our dependencies
+        floodlightProvider = 
+                context.getServiceImpl(IFloodlightProviderService.class);
+        topology =
+                context.getServiceImpl(ITopologyService.class);
+        storageSource =
+                context.getServiceImpl(IStorageSourceService.class);
+        
+        // We create this here because there is no ordering guarantee
+        this.deviceManagerAware = new HashSet<IDeviceManagerAware>();
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // This is our 'constructor'
+        
+        // Create our data structures
+        this.devMgrMaps = new DevMgrMaps();
+        this.lock = new ReentrantReadWriteLock();
+        this.updates = new LinkedList<Update>();
+        this.evHistDevMgrAttachPt = 
+                new EventHistory<EventHistoryAttachmentPoint>("Attachment-Point");
+        this.evHistDevMgrPktIn =
+                new EventHistory<OFMatch>("Pakcet-In");
+        
+        // Register to get updates from topology
+        topology.addListener(this);
+        
+        // Create our database tables
+        storageSource.createTable(DEVICE_TABLE_NAME, null);
+        storageSource.setTablePrimaryKeyName(
+                        DEVICE_TABLE_NAME, MAC_COLUMN_NAME);
+        storageSource.createTable(DEVICE_ATTACHMENT_POINT_TABLE_NAME, null);
+        storageSource.setTablePrimaryKeyName(
+                        DEVICE_ATTACHMENT_POINT_TABLE_NAME, ID_COLUMN_NAME);
+        storageSource.createTable(DEVICE_NETWORK_ADDRESS_TABLE_NAME, null);
+        storageSource.setTablePrimaryKeyName(
+                        DEVICE_NETWORK_ADDRESS_TABLE_NAME, ID_COLUMN_NAME);
+        
+        ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor();
+        deviceUpdateTask = new SingletonTask(ses, new DeviceUpdateWorker());
+        
+        // Register for the OpenFlow messages we want
+        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
+        floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this);
+        // Register for switch events
+        floodlightProvider.addOFSwitchListener(this);
+         // Device and storage aging.
+        enableDeviceAgingTimer();
+        // Read all our device state (MACs, IPs, attachment points) from storage
+        readAllDeviceStateFromStorage();
+    }
+
+    @Override
+    public void addListener(IDeviceManagerAware listener) {
+        deviceManagerAware.add(listener);
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
index 7fa76f2f9..76d165fd5 100644
--- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
+++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java
@@ -20,17 +20,27 @@ package net.floodlightcontroller.forwarding;
 
 import java.io.IOException;
 import java.util.ArrayList;
+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.IFloodlightService;
 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.counter.ICounterStoreService;
 import net.floodlightcontroller.devicemanager.Device;
 import net.floodlightcontroller.devicemanager.DeviceAttachmentPoint;
+import net.floodlightcontroller.devicemanager.IDeviceManagerService;
 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;
 
@@ -45,13 +55,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);
@@ -146,8 +156,8 @@ public class Forwarding extends ForwardingBase {
                         Route route = routingEngine.getRoute(srcSw.getId(), dstSw.getId());
                         if ((route != null) || validLocalHop(srcDap.getSwitchPort(), dstDap.getSwitchPort())) {
                             int bufferId = OFPacketOut.BUFFER_ID_NONE;
-                            if (log.isTraceEnabled()) {
-                                log.trace("pushRoute match={} route={} destination={}:{}",
+                            if (log.isDebugEnabled()) {
+                                log.debug("pushRoute match={} route={} destination={}:{}",
                                           new Object[] {match, route, dstDap.getSwitchPort().getSw(),
                                           dstDap.getSwitchPort().getPort()});
                             }
@@ -244,4 +254,49 @@ public class Forwarding extends ForwardingBase {
         return srcTuple.getSw().getId() == dstTuple.getSw().getId() &&
                srcTuple.getPort() != dstTuple.getPort();
     }
+
+    // IFloodlightModule methods
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getServices() {
+        // 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>> getDependencies() {
+        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 29b26f316..db20e43f0 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 a03c4df2b..f677a76f7 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.ICounterService;
+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;
     }
     
@@ -142,7 +143,7 @@ public class LearningSwitch implements IOFMessageListener {
             // flowmod is per switch. portid = -1
             String counterName = CounterStore.createCounterName(sw.getStringId(), -1, packetName);
             try {
-                ICounterService counter = counterStore.getCounter(counterName);
+                ICounter counter = counterStore.getCounter(counterName);
                 if (counter == null) {
                     counter = counterStore.createCounter(counterName, CounterValue.CounterType.LONG);
                 }
diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
index f59991ba4..b09705223 100644
--- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
+++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java
@@ -22,19 +22,20 @@ import java.util.ArrayList;
 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.core.util.AppCookie;
 import net.floodlightcontroller.counter.CounterStore;
 import net.floodlightcontroller.counter.CounterValue;
-import net.floodlightcontroller.counter.ICounterService;
+import net.floodlightcontroller.counter.ICounter;
+import net.floodlightcontroller.counter.ICounterStoreService;
 import net.floodlightcontroller.devicemanager.Device;
 import net.floodlightcontroller.devicemanager.DeviceNetworkAddress;
 import net.floodlightcontroller.devicemanager.IDeviceManagerService;
 import net.floodlightcontroller.devicemanager.IDeviceManagerAware;
 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;
@@ -60,24 +61,21 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
     
     public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT=5; // in seconds
 
-    protected IFloodlightProvider floodlightProvider;
+    protected IFloodlightProviderService floodlightProvider;
     protected IDeviceManagerService deviceManager;
-    protected IRoutingEngine routingEngine;
+    protected IRoutingEngineService routingEngine;
     protected ITopologyService topology;
-    protected CounterStore counterStore;
+    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 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";
@@ -117,7 +115,7 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
             // flowmod is per switch. portid = -1
             String counterName = CounterStore.createCounterName(sw.getStringId(), -1, packetName);
             try {
-                ICounterService counter = counterStore.getCounter(counterName);
+                ICounter counter = counterStore.getCounter(counterName);
                 if (counter == null) {
                     counter = counterStore.createCounter(counterName, CounterValue.CounterType.LONG);
                 }
@@ -291,7 +289,7 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
         }
     }
 
-    public static boolean blockHost(IFloodlightProvider floodlightProvider, 
+    public static boolean blockHost(IFloodlightProviderService floodlightProvider, 
             SwitchPortTuple sw_tup, long host_mac, 
             short hardTimeout) {
 
@@ -335,14 +333,14 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
     /**
      * @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
      */
-    public void setRoutingEngine(IRoutingEngine routingEngine) {
+    public void setRoutingEngine(IRoutingEngineService routingEngine) {
         this.routingEngine = routingEngine;
     }
 
@@ -360,11 +358,11 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag
         this.topology = topology;
     }
     
-    public CounterStore getCounterStore() {
+    public ICounterStoreService getCounterStore() {
         return counterStore;
     }
     
-    public void setCounterStore(CounterStore counterStore) {
+    public void setCounterStore(ICounterStoreService counterStore) {
         this.counterStore = counterStore;
     }
 
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 1a04ebbab..1b5e857f5 100644
--- a/src/main/java/net/floodlightcontroller/routing/IRoutingEngine.java
+++ b/src/main/java/net/floodlightcontroller/routing/IRoutingEngineService.java
@@ -17,6 +17,7 @@
 
 package net.floodlightcontroller.routing;
 
+import net.floodlightcontroller.core.IFloodlightService;
 import net.floodlightcontroller.core.IOFSwitch;
 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 d212e69f4..fcf2a463f 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;
 
@@ -29,20 +32,26 @@ import org.openflow.protocol.OFPhysicalPort.OFPortState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import net.floodlightcontroller.core.IFloodlightService;
 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.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.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, ITopologyListener {
+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;
@@ -54,17 +63,7 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener {
     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) {
@@ -120,7 +119,9 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener {
         }
 
         lock.readLock().unlock();
-        log.debug("getRoute: {} -> {}", id, result);
+        if (log.isDebugEnabled()) {
+            log.debug("getRoute: {} -> {}", id, result);
+        }
         return result;
     }
 
@@ -151,7 +152,9 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener {
 
         Route result = null;
         if (path != null) result = new Route(id, path);
-        log.debug("buildroute: {}", result);
+        if (log.isDebugEnabled()) {
+            log.debug("buildroute: {}", result);
+        }
         return result;
     }
 
@@ -312,10 +315,7 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener {
         BroadcastTree ret = new BroadcastTree(nexthoplinks, nexthopnodes);
         return ret;
     }
-
-    public void startUp() {}
-    public void shutDown() {}
-
+    
     @Override
     public void clusterMerged() {
         // no-op
@@ -326,4 +326,54 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener {
         // Ignored by RoutingImpl
     }
 
+    // IFloodlightModule
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getServices() {
+        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>> getDependencies() {
+        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);
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // Our 'constructor'
+        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);
+        
+        // Register to get updates from topology
+        topology.addListener(this);
+        
+        log.info("Initialized Dijkstra RouterImpl");
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
index f25c06fd8..e24c7b9cc 100644
--- a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
+++ b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
@@ -20,6 +20,7 @@ package net.floodlightcontroller.staticflowentry;
 import java.util.HashMap;
 import java.util.List;
 
+import net.floodlightcontroller.core.IFloodlightService;
 import net.floodlightcontroller.core.IOFSwitch;
 import org.openflow.protocol.OFFlowMod;
 
@@ -27,7 +28,7 @@ import org.openflow.protocol.OFFlowMod;
  * Represents the parts of the staticflowentry that are exposed as a service to other floodlight apps
  *
  */
-public interface IStaticFlowEntryPusherService {
+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 e280e7b55..32a4f0178 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.IFloodlightService;
 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 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 IStaticFlowEntryPusherService, IOFSwitchListener {
+public class StaticFlowEntryPusher 
+    implements IStaticFlowEntryPusherService, IOFSwitchListener, IFloodlightModule {
 
     // Utility data structure
     private class FlowModFields {
@@ -63,32 +70,18 @@ public class StaticFlowEntryPusher implements IStaticFlowEntryPusherService, IOF
     }
 
     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 = 25; // seconds
     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 IStaticFlowEntryPusherService, IOF
         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>> getServices() {
+        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>> getDependencies() {
+        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
@@ -622,21 +676,4 @@ public class StaticFlowEntryPusher implements IStaticFlowEntryPusherService, IOF
         // Initially push entries in 1 second
         floodlightProvider.getScheduledExecutor().schedule(pushEntriesTimer, 1, TimeUnit.SECONDS);
     }
-
-    /**
-     * 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 cdf1ac238..b07f105d4 100644
--- a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
@@ -27,10 +27,15 @@ import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public abstract class AbstractStorageSource implements IStorageSourceService {
+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.
@@ -83,12 +88,6 @@ public abstract class AbstractStorageSource implements IStorageSourceService {
         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;
@@ -330,4 +329,9 @@ public abstract class AbstractStorageSource implements IStorageSourceService {
             notifyListeners(notification);
     }
     
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // TODO Auto-generated method stub
+        
+    }
 }
diff --git a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
index d4c1ca417..ae0ae9e7a 100644
--- a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
@@ -17,8 +17,12 @@
 
 package net.floodlightcontroller.storage.memory;
 
+import net.floodlightcontroller.core.IFloodlightService;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
 import net.floodlightcontroller.perfmon.PktinProcessingTime;
 import net.floodlightcontroller.storage.nosql.NoSqlStorageSource;
+import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.SynchronousExecutorService;
 
 import java.util.ArrayList;
@@ -33,13 +37,8 @@ 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);
-    }
-    
     synchronized private MemoryTable getTable(String tableName, boolean create) {
         MemoryTable table = tableMap.get(tableName);
         if (table == null) {
@@ -177,4 +176,42 @@ public class MemoryStorageSource extends NoSqlStorageSource {
             PktinProcessingTime pktinProcessingTime) {
         this.pktinProcessingTime = pktinProcessingTime;
     }
+
+    // IFloodlightModule methods
+    
+    @Override
+    public Collection<Class<? extends IFloodlightService>> getServices() {
+        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>> getDependencies() {
+        // we don't have any depedencies
+        return null;
+    }
+
+    @Override
+    public void init(FloodlightModuleContext context)
+            throws FloodlightModuleException {
+        // no-op
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext 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 c3a691a4e..284354ec9 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) {
         if (indexedColumns == null) return;
diff --git a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
index c8dd10e8e..1ac0faa68 100644
--- a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
+++ b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java
@@ -86,6 +86,9 @@ public interface ITopologyService extends IFloodlightService {
      */
     public Map<IOFSwitch, Set<LinkTuple>> getSwitchLinks();
     
-    // gets called in startup method
-    public void addTopologyListener(ITopologyListener listener);
+    /**
+     * 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 19c1015a2..49fa69cee 100644
--- a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java
+++ b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java
@@ -20,6 +20,7 @@ package net.floodlightcontroller.topology.internal;
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -34,17 +35,21 @@ 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.IFloodlightService;
 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.util.SingletonTask;
 import net.floodlightcontroller.packet.BPDU;
 import net.floodlightcontroller.packet.Ethernet;
 import net.floodlightcontroller.packet.LLDP;
 import net.floodlightcontroller.packet.LLDPTLV;
 import net.floodlightcontroller.routing.BroadcastTree;
-import net.floodlightcontroller.routing.IRoutingEngine;
+import net.floodlightcontroller.routing.IRoutingEngineService;
 import net.floodlightcontroller.storage.IResultSet;
 import net.floodlightcontroller.storage.IStorageSourceService;
 import net.floodlightcontroller.storage.IStorageSourceListener;
@@ -97,8 +102,10 @@ import org.slf4j.LoggerFactory;
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, 
-                                            IStorageSourceListener, ITopologyService {
+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
@@ -115,9 +122,9 @@ 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 IFloodlightProvider floodlightProvider;
+    protected IFloodlightProviderService floodlightProvider;
     protected IStorageSourceService storageSource;
-    protected IRoutingEngine routingEngine;
+    protected IRoutingEngineService routingEngine;
 
     /**
      * Map from link to the most recent time it was verified functioning
@@ -213,15 +220,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
         }
     }
 
-    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.switchLinks = new HashMap<IOFSwitch, Set<LinkTuple>>();
-
-    }
-
     private void doUpdatesThread() throws InterruptedException {
         do {
             Update update = updates.take();
@@ -263,88 +261,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
@@ -527,7 +443,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
         }
     }
 
-    // TODO get rid of this
     @Override
     public String getName() {
         return "topology";
@@ -612,8 +527,8 @@ 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);
+            IFloodlightProviderService.bcStore.get(cntx, 
+                                        IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
 
         if (eth.getPayload() instanceof LLDP)
             return handleLldp((LLDP) eth.getPayload(), sw, pi);
@@ -929,14 +844,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
         return true;
     }
 
-    /**
-     * Sets the IFloodlightProvider for this TopologyImpl.
-     * @param floodlightProvider the floodlightProvider to set
-     */
-    public void setFloodlightProvider(IFloodlightProvider floodlightProvider) {
-        this.floodlightProvider = floodlightProvider;
-    }
-
     /**
      * Checks to see if a SwitchPortTuple is internal. A SwitchPortTuple is
      * defined as internal if the switch is a core switch if only switches that
@@ -1366,39 +1273,9 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener,
         storageSource.deleteRowAsync(LINK_TABLE_NAME, id);
     }
     
-    /**
-     * @param topologyAware the topologyAware to set
-     */
-    public void setTopologyAware(Set<ITopologyListener> topologyAware) {
-        // TODO make this a copy on write set or lock it somehow
-        this.topologyAware = topologyAware;
-    }
-
-    /**
-     * Sets the IStorageSource to use for ITology
-     * @param storageSource the storage source to use
-     */
-    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 IStorageSourceService getStorageSource() {
-        return storageSource;
-    }
-
-    /**
-     * @param storageSource the storage source to use for persisting link info
-     */
-    public void setRoutingEngine(IRoutingEngine routingEngine) {
-        this.routingEngine = routingEngine;
-        storageSource.createTable(LINK_TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID);
+    @Override
+    public void addListener(ITopologyListener listener) {
+        topologyAware.add(listener);
     }
     
     @Override
@@ -1467,9 +1344,138 @@ 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 void addTopologyListener(ITopologyListener listener) {
-        // TODO Auto-generated method stub
+    public Collection<Class<? extends IFloodlightService>> getServices() {
+        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>> getDependencies() {
+        Collection<Class<? extends IFloodlightService>> l = 
+                new ArrayList<Class<? extends IFloodlightService>>();
+        l.add(IFloodlightProviderService.class);
+        l.add(IStorageSourceService.class);
+        l.add(IRoutingEngineService.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);
+        
+        // We create this here because there is no ordering guarantee
+        this.topologyAware = new HashSet<ITopologyListener>();
+    }
+
+    @Override
+    public void startUp(FloodlightModuleContext context) {
+        // Our 'constructor'
+        
+        // Setup our data structures
+        this.lock = new ReentrantReadWriteLock();
+        this.updates = new LinkedBlockingQueue<Update>();
+        this.links = new HashMap<LinkTuple, LinkInfo>();
+        this.portLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>();
+        this.switchLinks = new HashMap<IOFSwitch, Set<LinkTuple>>();
+        
+        // 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);
     }
 }
diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
index 17993d3ad..2ca28981f 100644
--- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
+++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java
@@ -30,7 +30,7 @@ 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.IOFMessageListener.Command;
 import net.floodlightcontroller.core.IOFSwitch;
@@ -354,7 +354,7 @@ 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.
diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
index 9758c6a08..2c6e86c43 100644
--- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
+++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java
@@ -26,7 +26,7 @@ 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;
@@ -43,7 +43,7 @@ import org.openflow.protocol.factory.BasicFactory;
  *
  * @author David Erickson (daviderickson@cs.stanford.edu)
  */
-public class MockFloodlightProvider implements IFloodlightProvider {
+public class MockFloodlightProvider implements IFloodlightProviderService {
     protected Map<OFType, List<IOFMessageListener>> listeners;
     protected List<IOFSwitchListener> switchListeners;
     protected Map<Long, IOFSwitch> switches;
@@ -123,8 +123,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)) {
diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
index c4d98c2aa..f8aacabe0 100644
--- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
+++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java
@@ -68,7 +68,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase {
         deviceManager = new DeviceManagerImpl();
         deviceManager.setFloodlightProvider(mockFloodlightProvider);
         deviceManager.setStorageSource(new MemoryStorageSource());
-        deviceManager.startUp();
+        //deviceManager.startUp();
         
         // Build our test packet
         this.testPacket = new Ethernet()
diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
index d657e1035..28dcbe70b 100644
--- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
+++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java
@@ -32,7 +32,7 @@ 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.Device;
@@ -42,7 +42,7 @@ 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;
@@ -68,7 +68,7 @@ public class ForwardingTest extends FloodlightTestCase {
     protected MockFloodlightProvider mockFloodlightProvider;
     protected FloodlightContext cntx;
     protected IDeviceManagerService deviceManager;
-    protected IRoutingEngine routingEngine;
+    protected IRoutingEngineService routingEngine;
     protected Forwarding forwarding;
     protected ITopologyService topology;
     protected IOFSwitch sw1, sw2;
@@ -89,7 +89,7 @@ public class ForwardingTest extends FloodlightTestCase {
         mockFloodlightProvider = getMockFloodlightProvider();
         forwarding = getForwarding();
         deviceManager = createMock(IDeviceManagerService.class);
-        routingEngine = createMock(IRoutingEngine.class);
+        routingEngine = createMock(IRoutingEngineService.class);
         topology = createMock(ITopologyService.class);
         forwarding.setFloodlightProvider(mockFloodlightProvider);
         forwarding.setDeviceManager(deviceManager);
@@ -183,7 +183,7 @@ public class ForwardingTest extends FloodlightTestCase {
         expected_wildcards &= ~OFMatch.OFPFW_NW_SRC_MASK & ~OFMatch.OFPFW_NW_DST_MASK;
 
         // Add the packet to the context store
-        IFloodlightProvider.bcStore.put(cntx, IFloodlightProvider.CONTEXT_PI_PAYLOAD, (Ethernet)testPacket);
+        IFloodlightProviderService.bcStore.put(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD, (Ethernet)testPacket);
     }
 
     private Forwarding getForwarding() {
diff --git a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java
index 944443884..addc9e555 100644
--- a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java
+++ b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java
@@ -66,9 +66,9 @@ public class StaticFlowEntryPusherTest extends FloodlightTestCase {
         Map<Long, IOFSwitch> switchMap = new HashMap<Long, IOFSwitch>();
         switchMap.put(dpid, mockSwitch);
         mockFloodlightProvider.setSwitches(switchMap);
-        staticFlowEntryPusher.setFloodlightProvider(mockFloodlightProvider);
+        //staticFlowEntryPusher.setFloodlightProvider(mockFloodlightProvider);
         long timeSfpStart = System.currentTimeMillis();
-        staticFlowEntryPusher.startUp();
+        //staticFlowEntryPusher.startUp();
         
         // if someone calls getId(), return this dpid instead
         expect(mockSwitch.getId()).andReturn(dpid).anyTimes();
diff --git a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java
index 46a0ede97..23d649a93 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;
 
@@ -56,8 +56,8 @@ 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;
-- 
GitLab