Began moving the ARP module out of SDNIP exclusivity and sketched out a module framework we can use to load ONOS modules without having them be Floodlight modules
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
index d84d30d..5e2cb05 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -40,7 +40,6 @@
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
 import net.onrc.onos.ofcontroller.proxyarp.IArpRequester;
 import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
-import net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager;
 import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
 import net.onrc.onos.ofcontroller.topology.Topology;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
@@ -77,7 +76,7 @@
 
 public class BgpRoute implements IFloodlightModule, IBgpRouteService, 
 									ITopologyListener, IArpRequester,
-									IOFSwitchListener, ILayer3InfoService,
+									IOFSwitchListener, IConfigInfoService,
 									IProxyArpService {
 	
 	private final static Logger log = LoggerFactory.getLogger(BgpRoute.class);
@@ -88,7 +87,7 @@
 	private ILinkDiscoveryService linkDiscoveryService;
 	private IRestApiService restApi;
 	
-	private ProxyArpManager proxyArp;
+	private IProxyArpService proxyArp;
 	
 	private IPatriciaTrie<RibEntry> ptree;
 	private IPatriciaTrie<Interface> interfacePtrie;
@@ -230,6 +229,7 @@
 		Collection<Class<? extends IFloodlightService>> l 
 			= new ArrayList<Class<? extends IFloodlightService>>();
 		l.add(IBgpRouteService.class);
+		l.add(IConfigInfoService.class);
 		return l;
 	}
 
@@ -238,7 +238,7 @@
 		Map<Class<? extends IFloodlightService>, IFloodlightService> m 
 			= new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
 		m.put(IBgpRouteService.class, this);
-		m.put(IProxyArpService.class, this);
+		m.put(IConfigInfoService.class, this);
 		return m;
 	}
 
@@ -269,7 +269,9 @@
 		
 		//TODO We'll initialise this here for now, but it should really be done as
 		//part of the controller core
-		proxyArp = new ProxyArpManager(floodlightProvider, topologyService, this, restApi);
+		//proxyArp = new ProxyArpManager(floodlightProvider, topologyService, this, restApi);
+		//proxyArp = new ProxyArpManager();
+		proxyArp = context.getServiceImpl(IProxyArpService.class);
 		
 		linkUpdates = new ArrayList<LDUpdate>();
 		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
@@ -324,9 +326,9 @@
 		topologyService.addListener(this);
 		floodlightProvider.addOFSwitchListener(this);
 		
-		proxyArp.startUp(vlan);
+		//proxyArp.startUp(vlan);
 		
-		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, proxyArp);
+		//floodlightProvider.addOFMessageListener(OFType.PACKET_IN, proxyArp);
 		
 		//Retrieve the RIB from BGPd during startup
 		retrieveRib();
@@ -1238,7 +1240,7 @@
 	}
 	
 	/*
-	 * ILayer3InfoService methods
+	 * IConfigInfoService methods
 	 */
 	
 	@Override
@@ -1277,6 +1279,11 @@
 	public MACAddress getRouterMacAddress() {
 		return bgpdMacAddress;
 	}
+	
+	@Override
+	public short getVlan() {
+		return vlan;
+	}
 
 	/*
 	 * TODO This is a hack to get the REST API to work for ProxyArpManager.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java b/src/main/java/net/onrc/onos/ofcontroller/bgproute/IConfigInfoService.java
similarity index 72%
rename from src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java
rename to src/main/java/net/onrc/onos/ofcontroller/bgproute/IConfigInfoService.java
index 00ddd68..4d80894 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/ILayer3InfoService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/IConfigInfoService.java
@@ -3,13 +3,14 @@
 import java.net.InetAddress;
 
 import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.core.module.IOnosService;
 
 /**
  * Provides information about the layer 3 properties of the network.
  * This is based on IP addresses configured on ports in the network.
  *
  */
-public interface ILayer3InfoService {
+public interface IConfigInfoService extends IOnosService {
 	public boolean isInterfaceAddress(InetAddress address);
 	public boolean inConnectedNetwork(InetAddress address);
 	public boolean fromExternalNetwork(long inDpid, short inPort);
@@ -32,4 +33,15 @@
 	public boolean hasLayer3Configuration();
 	
 	public MACAddress getRouterMacAddress();
+	
+	/**
+	* We currently have basic vlan support for the situation when the contr
+	* is running within a single vlan. In this case, packets sent from the 
+	* controller (e.g. ARP) need to be tagged with that vlan.
+	* @return The vlan id configured in the config file, 
+	* or 0 if no vlan is configured.
+	*/
+	public short getVlan();
+
+
 }
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/module/IOnosService.java b/src/main/java/net/onrc/onos/ofcontroller/core/module/IOnosService.java
new file mode 100644
index 0000000..5828366
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/module/IOnosService.java
@@ -0,0 +1,7 @@
+package net.onrc.onos.ofcontroller.core.module;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+
+public interface IOnosService extends IFloodlightService {
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/core/module/ONOSModuleLoader.java b/src/main/java/net/onrc/onos/ofcontroller/core/module/ONOSModuleLoader.java
new file mode 100644
index 0000000..6526827
--- /dev/null
+++ b/src/main/java/net/onrc/onos/ofcontroller/core/module/ONOSModuleLoader.java
@@ -0,0 +1,78 @@
+package net.onrc.onos.ofcontroller.core.module;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import net.floodlightcontroller.core.IFloodlightProviderService;
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.floodlightcontroller.restserver.IRestApiService;
+import net.floodlightcontroller.topology.ITopologyService;
+import net.onrc.onos.ofcontroller.bgproute.IConfigInfoService;
+import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
+import net.onrc.onos.ofcontroller.proxyarp.ProxyArpManager;
+
+public class ONOSModuleLoader implements IFloodlightModule {
+	private IFloodlightProviderService floodlightProvider;
+	private ITopologyService topology;
+	private IConfigInfoService config;
+	private IRestApiService restApi;
+
+	private ProxyArpManager arpManager;
+	
+	public ONOSModuleLoader() {
+		arpManager = new ProxyArpManager();
+	}
+	
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+		List<Class<? extends IFloodlightService>> services = 
+				new ArrayList<Class<? extends IFloodlightService>>();
+		services.add(IProxyArpService.class);
+		return services;
+	}
+
+	@Override
+	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+		Map<Class<? extends IFloodlightService>, IFloodlightService> impls = 
+				new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
+		impls.put(IProxyArpService.class, arpManager);
+		return impls;
+	}
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+		List<Class<? extends IFloodlightService>> dependencies = 
+				new ArrayList<Class<? extends IFloodlightService>>();
+		dependencies.add(IFloodlightProviderService.class);
+		dependencies.add(ITopologyService.class);
+		//dependencies.add(IConfigInfoService.class);
+		dependencies.add(IRestApiService.class);
+		return dependencies;
+	}
+
+	@Override
+	public void init(FloodlightModuleContext context)
+			throws FloodlightModuleException {
+		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
+		topology = context.getServiceImpl(ITopologyService.class);
+		restApi = context.getServiceImpl(IRestApiService.class);
+		
+		//This could be null because it's not mandatory to have an
+		//IConfigInfoService loaded.
+		config = context.getServiceImpl(IConfigInfoService.class);
+
+		arpManager.init(floodlightProvider, topology, config, restApi);
+	}
+
+	@Override
+	public void startUp(FloodlightModuleContext context) {
+		arpManager.startUp();
+	}
+
+}
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
index 97844d3..71546a1 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/IProxyArpService.java
@@ -3,11 +3,11 @@
 import java.net.InetAddress;
 import java.util.List;
 
-import net.floodlightcontroller.core.module.IFloodlightService;
 import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.ofcontroller.core.module.IOnosService;
 
 //Extends IFloodlightService so we can access it from REST API resources
-public interface IProxyArpService extends IFloodlightService{
+public interface IProxyArpService extends IOnosService{
 	/**
 	 * Returns the MAC address if there is a valid entry in the cache.
 	 * Otherwise returns null.
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
index 0151212..5e5742d 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -22,7 +22,7 @@
 import net.floodlightcontroller.restserver.IRestApiService;
 import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.bgproute.ILayer3InfoService;
+import net.onrc.onos.ofcontroller.bgproute.IConfigInfoService;
 import net.onrc.onos.ofcontroller.bgproute.Interface;
 
 import org.openflow.protocol.OFMessage;
@@ -47,17 +47,17 @@
 	
 	private static final int ARP_REQUEST_TIMEOUT = 2000; //ms
 			
-	private final IFloodlightProviderService floodlightProvider;
-	private final ITopologyService topology;
-	private final ILayer3InfoService layer3;
-	private final IRestApiService restApi;
+	private IFloodlightProviderService floodlightProvider;
+	private ITopologyService topology;
+	private IConfigInfoService configService;
+	private IRestApiService restApi;
 	
 	private short vlan;
 	private static final short NO_VLAN = 0;
 	
-	private final ArpCache arpCache;
+	private ArpCache arpCache;
 
-	private final SetMultimap<InetAddress, ArpRequest> arpRequests;
+	private SetMultimap<InetAddress, ArpRequest> arpRequests;
 	
 	private static class ArpRequest {
 		private final IArpRequester requester;
@@ -106,12 +106,20 @@
 		}
 	}
 	
+	/*
 	public ProxyArpManager(IFloodlightProviderService floodlightProvider,
-				ITopologyService topology, ILayer3InfoService layer3,
+				ITopologyService topology, IConfigInfoService configService,
 				IRestApiService restApi){
+
+	}
+	*/
+	
+	public void init(IFloodlightProviderService floodlightProvider,
+			ITopologyService topology, IConfigInfoService config,
+			IRestApiService restApi){
 		this.floodlightProvider = floodlightProvider;
 		this.topology = topology;
-		this.layer3 = layer3;
+		this.configService = config;
 		this.restApi = restApi;
 		
 		arpCache = new ArpCache();
@@ -120,11 +128,12 @@
 				HashMultimap.<InetAddress, ArpRequest>create());
 	}
 	
-	public void startUp(short vlan) {
-		this.vlan = vlan;
+	public void startUp() {
+		this.vlan = configService.getVlan();
 		log.info("vlan set to {}", this.vlan);
 		
 		restApi.addRestletRoutable(new ArpWebRoutable());
+		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
 		
 		Timer arpTimer = new Timer("arp-processing");
 		arpTimer.scheduleAtFixedRate(new TimerTask() {
@@ -244,15 +253,15 @@
 			return;
 		}
 
-		if (layer3.fromExternalNetwork(sw.getId(), pi.getInPort())) {
+		if (configService.fromExternalNetwork(sw.getId(), pi.getInPort())) {
 			//If the request came from outside our network, we only care if
 			//it was a request for one of our interfaces.
-			if (layer3.isInterfaceAddress(target)) {
+			if (configService.isInterfaceAddress(target)) {
 				log.trace("ARP request for our interface. Sending reply {} => {}",
-						target.getHostAddress(), layer3.getRouterMacAddress());
+						target.getHostAddress(), configService.getRouterMacAddress());
 				
 				sendArpReply(arp, sw.getId(), pi.getInPort(), 
-						layer3.getRouterMacAddress());
+						configService.getRouterMacAddress());
 			}
 			
 			return;
@@ -345,7 +354,7 @@
 			.setTargetHardwareAddress(zeroMac)
 			.setTargetProtocolAddress(ipAddress.getAddress());
 
-		MACAddress routerMacAddress = layer3.getRouterMacAddress();
+		MACAddress routerMacAddress = configService.getRouterMacAddress();
 		//TODO hack for now as it's unclear what the MAC address should be
 		byte[] senderMacAddress = genericNonZeroMac;
 		if (routerMacAddress != null) {
@@ -354,7 +363,7 @@
 		arpRequest.setSenderHardwareAddress(senderMacAddress);
 		
 		byte[] senderIPAddress = zeroIpv4;
-		Interface intf = layer3.getOutgoingInterface(ipAddress);
+		Interface intf = configService.getOutgoingInterface(ipAddress);
 		if (intf != null) {
 			senderIPAddress = intf.getIpAddress().getAddress();
 		}
@@ -383,8 +392,8 @@
 	private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest,
 			long inSwitch, short inPort) {
 
-		if (layer3.hasLayer3Configuration()) {
-			Interface intf = layer3.getOutgoingInterface(dstAddress);
+		if (configService.hasLayer3Configuration()) {
+			Interface intf = configService.getOutgoingInterface(dstAddress);
 			if (intf != null) {
 				sendArpRequestOutPort(arpRequest, intf.getDpid(), intf.getPort());
 			}
@@ -571,7 +580,7 @@
 		arpRequests.put(ipAddress, new ArpRequest(requester, retry));
 		
 		//Sanity check to make sure we don't send a request for our own address
-		if (!layer3.isInterfaceAddress(ipAddress)) {
+		if (!configService.isInterfaceAddress(ipAddress)) {
 			sendArpRequestForAddress(ipAddress);
 		}
 	}
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index 99ded31..8cea5dc 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -24,3 +24,4 @@
 net.onrc.onos.ofcontroller.bgproute.BgpRoute
 net.onrc.onos.registry.controller.ZookeeperRegistry
 net.onrc.onos.registry.controller.StandaloneRegistry
+net.onrc.onos.ofcontroller.core.module.ONOSModuleLoader
\ No newline at end of file