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 4f6c310..1363c19 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/bgproute/BgpRoute.java
@@ -3,6 +3,7 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
@@ -33,20 +34,36 @@
 import net.floodlightcontroller.topology.ITopologyService;
 import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.ofcontroller.bgproute.RibUpdate.Operation;
+import net.onrc.onos.ofcontroller.core.IDeviceStorage;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.IDeviceObject;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyObjects.ISwitchObject;
 import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoLinkService;
+import net.onrc.onos.ofcontroller.core.INetMapTopologyService.ITopoSwitchService;
 import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
+import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
 import net.onrc.onos.ofcontroller.core.internal.TopoLinkServiceImpl;
+import net.onrc.onos.ofcontroller.core.internal.TopoSwitchServiceImpl;
+import net.onrc.onos.ofcontroller.flowmanager.IFlowService;
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery;
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscovery.LDUpdate;
 import net.onrc.onos.ofcontroller.linkdiscovery.ILinkDiscoveryService;
-import net.onrc.onos.ofcontroller.proxyarp.BgpProxyArpManager;
 import net.onrc.onos.ofcontroller.proxyarp.IArpRequester;
+import net.onrc.onos.ofcontroller.proxyarp.IProxyArpService;
 import net.onrc.onos.ofcontroller.topology.ITopologyNetService;
 import net.onrc.onos.ofcontroller.topology.Topology;
 import net.onrc.onos.ofcontroller.topology.TopologyManager;
+import net.onrc.onos.ofcontroller.util.CallerId;
 import net.onrc.onos.ofcontroller.util.DataPath;
 import net.onrc.onos.ofcontroller.util.Dpid;
-import net.onrc.onos.ofcontroller.util.FlowEntry;
+import net.onrc.onos.ofcontroller.util.FlowEntryAction;
+import net.onrc.onos.ofcontroller.util.FlowEntryActions;
+import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
+import net.onrc.onos.ofcontroller.util.FlowId;
+import net.onrc.onos.ofcontroller.util.FlowPath;
+import net.onrc.onos.ofcontroller.util.FlowPathFlags;
+import net.onrc.onos.ofcontroller.util.FlowPathType;
+import net.onrc.onos.ofcontroller.util.FlowPathUserState;
+import net.onrc.onos.ofcontroller.util.IPv4Net;
 import net.onrc.onos.ofcontroller.util.Port;
 import net.onrc.onos.ofcontroller.util.SwitchPort;
 import net.sf.json.JSONArray;
@@ -60,9 +77,7 @@
 import org.openflow.protocol.OFMatch;
 import org.openflow.protocol.OFPacketOut;
 import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
 import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionDataLayerDestination;
 import org.openflow.protocol.action.OFActionOutput;
 import org.openflow.util.HexString;
 import org.slf4j.Logger;
@@ -86,8 +101,10 @@
 	private ITopologyNetService topologyNetService;
 	private ILinkDiscoveryService linkDiscoveryService;
 	private IRestApiService restApi;
-	
-	private BgpProxyArpManager proxyArp;
+	private IProxyArpService proxyArp;
+	protected volatile IFlowService flowManagerService;
+	private IDeviceStorage deviceStorage;
+	private ITopoSwitchService topoSwitchService;
 	
 	private IPatriciaTrie<RibEntry> ptree;
 	private IPatriciaTrie<Interface> interfacePtrie;
@@ -139,12 +156,13 @@
 	
 	private Map<InetAddress, Path> pushedPaths;
 	private Map<Prefix, Path> prefixToPath;
-	private Multimap<Prefix, PushedFlowMod> pushedFlows;
+//	private Multimap<Prefix, PushedFlowMod> pushedFlows;
+	private Multimap<Prefix, FlowId> pushedFlowIds;
 	
 	private FlowCache flowCache;
 	
 	private volatile Topology topology = null;
-		
+	
 	private class TopologyChangeDetector implements Runnable {
 		@Override
 		public void run() {
@@ -232,7 +250,7 @@
 		l.add(IConfigInfoService.class);
 		return l;
 	}
-
+	
 	@Override
 	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
 		Map<Class<? extends IFloodlightService>, IFloodlightService> m 
@@ -255,38 +273,38 @@
 	@Override
 	public void init(FloodlightModuleContext context)
 			throws FloodlightModuleException {
-	    
+		
 		ptree = new PatriciaTrie<RibEntry>(32);
 		interfacePtrie = new PatriciaTrie<Interface>(32);
-	    
-	    ribUpdates = new LinkedBlockingQueue<RibUpdate>();
-	    	
+		
+		ribUpdates = new LinkedBlockingQueue<RibUpdate>();
+		
 		// Register floodlight provider and REST handler.
 		floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
 		topologyService = context.getServiceImpl(ITopologyService.class);
 		linkDiscoveryService = context.getServiceImpl(ILinkDiscoveryService.class);
 		restApi = context.getServiceImpl(IRestApiService.class);
-		
-		//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 BgpProxyArpManager();
-		proxyArp.init(floodlightProvider, topologyService, this, restApi);
-		//proxyArp = context.getServiceImpl(IProxyArpService.class);
-		
+		flowManagerService = context.getServiceImpl(IFlowService.class);
+		proxyArp = context.getServiceImpl(IProxyArpService.class);
+
+		deviceStorage = new DeviceStorageImpl();
+		deviceStorage.init("", "");
+
 		linkUpdates = new ArrayList<LDUpdate>();
 		ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
 		topologyChangeDetectorTask = new SingletonTask(executor, new TopologyChangeDetector());
 
 		topologyNetService = new TopologyManager(context);
-		
+		topoSwitchService = new TopoSwitchServiceImpl();
+
 		pathsWaitingOnArp = new HashMap<InetAddress, Path>();
 		prefixesWaitingOnArp = Multimaps.synchronizedSetMultimap(
 				HashMultimap.<InetAddress, RibUpdate>create());
 		
 		pushedPaths = new HashMap<InetAddress, Path>();
 		prefixToPath = new HashMap<Prefix, Path>();
-		pushedFlows = HashMultimap.<Prefix, PushedFlowMod>create();
+//		pushedFlows = HashMultimap.<Prefix, PushedFlowMod>create();
+		pushedFlowIds = HashMultimap.<Prefix, FlowId>create();
 		
 		flowCache = new FlowCache(floodlightProvider);
 		
@@ -311,7 +329,7 @@
 		else {
 			log.info("RouterId set to {}", routerId);
 		}
-		
+
 		String configFilenameParameter = context.getConfigParams(this).get("configfile");
 		if (configFilenameParameter != null){
 			configFilename = configFilenameParameter;
@@ -326,11 +344,7 @@
 		restApi.addRestletRoutable(new BgpRouteWebRoutable());
 		topologyService.addListener(this);
 		floodlightProvider.addOFSwitchListener(this);
-		
-		proxyArp.startUp();
-		
-		//floodlightProvider.addOFMessageListener(OFType.PACKET_IN, proxyArp);
-		
+
 		//Retrieve the RIB from BGPd during startup
 		retrieveRib();
 	}
@@ -390,7 +404,7 @@
 			}
 			
 			RibEntry rib = new RibEntry(router_id, nexthop);
-
+			
 			try {
 				ribUpdates.put(new RibUpdate(Operation.UPDATE, p, rib));
 			} catch (InterruptedException e) {
@@ -439,11 +453,24 @@
 		RibEntry rib = update.getRibEntry();
 		
 		InetAddress dstIpAddress = rib.getNextHop();
+		MACAddress nextHopMacAddress;
+
+		// See if we know the MAC address of the next hop
+		// TODO if we do not treat the next hop as a device in the future, we need to update this
+		IDeviceObject nextHopDevice =
+				deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(dstIpAddress));
 		
-		//See if we know the MAC address of the next hop
-		MACAddress nextHopMacAddress = proxyArp.getMacAddress(rib.getNextHop());
+		if (nextHopDevice == null){
+			log.debug("NextHopDevice for IP: {} is null", dstIpAddress);
+			prefixesWaitingOnArp.put(dstIpAddress,
+					new RibUpdate(Operation.UPDATE, prefix, rib));
+			proxyArp.sendArpRequest(dstIpAddress, this, true);
+			return;
+
+		}
+		nextHopMacAddress = MACAddress.valueOf(nextHopDevice.getMACAddress());
 		
-		//Find the attachment point (egress interface) of the next hop
+		// Find the attachment point (egress interface) of the next hop
 		Interface egressInterface = null;
 		if (bgpPeers.containsKey(dstIpAddress)) {
 			//Route to a peer
@@ -488,11 +515,34 @@
 		}
 	}
 	
-	private void addPrefixFlows(Prefix prefix, Interface egressInterface, MACAddress nextHopMacAddress) {		
+	/**
+	 * Add a flow to match dst-IP prefix and rewrite MAC for one IP prefix
+	 * to all other border switches
+	 */
+	private void addPrefixFlows(Prefix prefix, Interface egressInterface,
+			MACAddress nextHopMacAddress) {
 		log.debug("Adding flows for prefix {}, next hop mac {}",
 				prefix, nextHopMacAddress);
 		
-		//We only need one flow mod per switch, so pick one interface on each switch
+		FlowPath flowPath = new FlowPath();
+		flowPath.setInstallerId(new CallerId("SDNIP"));
+		
+		// Set flowPath FlowPathType and FlowPathUserState
+		flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
+		flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
+
+		// Insert dst-ip prefix based forwarding and MAC rewrite flow entry
+		// only to the first-host switches
+		FlowPathFlags flowPathFlags = new FlowPathFlags();
+		flowPathFlags.setFlags(FlowPathFlags.KEEP_ONLY_FIRST_HOP_ENTRY);
+		flowPath.setFlowPathFlags(flowPathFlags);
+
+		// Create the DataPath object: dstSwitchPort
+		SwitchPort dstPort = new SwitchPort();
+		dstPort.setDpid(new Dpid(egressInterface.getDpid()));
+		dstPort.setPort(new Port(egressInterface.getPort()));
+
+		// We only need one flow mod per switch, so pick one interface on each switch
 		Map<Long, Interface> srcInterfaces = new HashMap<Long, Interface>();
 		for (Interface intf : interfaces.values()) {
 			if (!srcInterfaces.containsKey(intf.getDpid()) 
@@ -500,77 +550,56 @@
 				srcInterfaces.put(intf.getDpid(), intf);
 			}
 		}
-		
-		//Add a flow to rewrite mac for this prefix to all other border switches
 		for (Interface srcInterface : srcInterfaces.values()) {
-			DataPath shortestPath; 
-			if (topology == null) {
-				shortestPath = topologyNetService.getDatabaseShortestPath(
-						srcInterface.getSwitchPort(),
-						egressInterface.getSwitchPort());
+
+			if (egressInterface.equals(srcInterface)){
+				continue;
 			}
-			else {
-				shortestPath = topologyNetService.getTopologyShortestPath(
-						topology, srcInterface.getSwitchPort(),
-						egressInterface.getSwitchPort());
-			}
-			
-			if (shortestPath == null){
-				log.debug("Shortest path between {} and {} not found",
-						srcInterface.getSwitchPort(),
-						egressInterface.getSwitchPort());
-				return; // just quit here?
-			}
-			
-			//Set up the flow mod
-			OFFlowMod fm = (OFFlowMod) floodlightProvider.getOFMessageFactory()
-					.getMessage(OFType.FLOW_MOD);
-			
-	        fm.setIdleTimeout((short)0)
-	        .setHardTimeout((short)0)
-	        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-	        .setCookie(MAC_RW_COOKIE)
-	        .setCommand(OFFlowMod.OFPFC_ADD)
-	        .setPriority(SDNIP_PRIORITY)
-	        .setLengthU(OFFlowMod.MINIMUM_LENGTH
-	        		+ OFActionDataLayerDestination.MINIMUM_LENGTH
-	        		+ OFActionOutput.MINIMUM_LENGTH);
-	        
-	        OFMatch match = new OFMatch();
-	        match.setDataLayerType(Ethernet.TYPE_IPv4);
-	        match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_TYPE);
-	        
-	        match.setFromCIDR(prefix.toString(), OFMatch.STR_NW_DST);
-	        fm.setMatch(match);
-	        
-	        //Set up MAC rewrite action
-	        OFActionDataLayerDestination macRewriteAction = new OFActionDataLayerDestination();
-	        macRewriteAction.setDataLayerAddress(nextHopMacAddress.toBytes());
-	        
-	        //Set up output action
-	        OFActionOutput outputAction = new OFActionOutput();
-	        outputAction.setMaxLength((short)0xffff);
-	        Port outputPort = shortestPath.flowEntries().get(0).outPort();
-	        outputAction.setPort(outputPort.value());
-	        
-	        List<OFAction> actions = new ArrayList<OFAction>();
-	        actions.add(macRewriteAction);
-	        actions.add(outputAction);
-	        fm.setActions(actions);
-	        
-	        pushedFlows.put(prefix, new PushedFlowMod(srcInterface.getDpid(), fm));
-	        flowCache.write(srcInterface.getDpid(), fm);
+
+			// Create flowPath FlowId
+			//FlowId returnByRefFlowId = new FlowId(flowManagerService.getNextFlowEntryId());
+			//flowPath.setFlowId(returnByRefFlowId);
+			flowPath.setFlowId(new FlowId());
+
+			// Create DataPath object: srcSwitchPort
+			SwitchPort srcPort = new SwitchPort();
+			srcPort.setDpid(new Dpid(srcInterface.getDpid()));
+			srcPort.setPort(new Port(srcInterface.getPort()));
+
+			DataPath dataPath = new DataPath();
+			dataPath.setSrcPort(srcPort);
+			dataPath.setDstPort(dstPort);
+			flowPath.setDataPath(dataPath);
+
+			// Create flow path matching condition(s): IPv4 Prefix
+			FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
+			flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
+			IPv4Net dstIPv4Net= new IPv4Net(prefix.toString());
+			flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
+			flowPath.setFlowEntryMatch(flowEntryMatch);
 
 			/*
-			 * XXX Rate limit hack!
-			 * This should be solved properly by adding a rate limiting
-			 * layer on top of the switches if we know they need it.
+			 * Create the Flow Entry Action(s): dst-MAC rewrite action
 			 */
-	        try {
-				Thread.sleep(1);
-			} catch (InterruptedException e) {
-				// TODO handle this properly
-				log.error("Interrupted", e);
+			FlowEntryActions flowEntryActions = new FlowEntryActions();
+			FlowEntryAction flowEntryAction1 = new FlowEntryAction();
+			flowEntryAction1.setActionSetEthernetDstAddr(nextHopMacAddress);
+			// flowEntryAction1.actionSetEthernetDstAddr(nextHopMacAddress);
+			flowEntryActions.addAction(flowEntryAction1);
+			flowPath.setFlowEntryActions(flowEntryActions);
+
+			// Flow Path installation, only to first hop switches
+			if (flowManagerService.addFlow(flowPath) == null) {
+				log.error("Failed to install flow path to the first hop for " +
+						"prefix: {}, nextHopMacAddress: {}", prefix.getAddress(),
+						nextHopMacAddress);
+			}
+			else {
+				log.debug("Successfully installed flow path to the first hop " +
+						"for prefix: {}, nextHopMacAddress: {}", prefix.getAddress(),
+						nextHopMacAddress);
+
+				pushedFlowIds.put(prefix, flowPath.flowId());
 			}
 		}
 	}
@@ -600,7 +629,7 @@
 			if (path != null) {
 				//path could be null if we added to the Ptree but didn't push
 				//flows yet because we were waiting to resolve ARP
-			
+				
 				path.decrementUsers();
 				if (path.getUsers() <= 0 && !path.isPermanent()) {
 					deletePath(path);
@@ -610,51 +639,53 @@
 		}
 	}
 	
+	// TODO have not tested this module
 	private void deletePrefixFlows(Prefix prefix) {
 		log.debug("Deleting flows for prefix {}", prefix);
 		
-		Collection<PushedFlowMod> pushedFlowMods 
-				= pushedFlows.removeAll(prefix);
-		
-		for (PushedFlowMod pfm : pushedFlowMods) {
+		Collection<FlowId> flowIds = pushedFlowIds.removeAll(prefix);
+		for (FlowId flowId : flowIds) {
 			if (log.isTraceEnabled()) {
-				log.trace("Pushing a DELETE flow mod to {}, matches prefix {} with mac-rewrite {}",
-						new Object[] {HexString.toHexString(pfm.getDpid()),
-						pfm.getFlowMod().getMatch().getNetworkDestination() + 
-						pfm.getFlowMod().getMatch().getNetworkDestinationMaskLen(),
-						HexString.toHexString(((OFActionDataLayerDestination)pfm.getFlowMod().getActions().get(0))
-								.getDataLayerAddress())});
+				//Trace the flow status by flowPath in the switch before deleting it
+				log.trace("Pushing a DELETE flow mod to flowPath : {}",
+						flowManagerService.getFlow(flowId).toString());
 			}
 			
-			sendDeleteFlowMod(pfm.getFlowMod(), pfm.getDpid());
+			if( flowManagerService.deleteFlow(flowId))
+			{
+				log.debug("Successfully deleted FlowId: {}",flowId);
+			}
+			else
+			{
+				log.debug("Failed to delete FlowId: {}",flowId);
+			}
 		}
 	}
 	
+	// TODO need to record the path and then delete here
 	private void deletePath(Path path) {
 		log.debug("Deleting flows for path to {}", 
 				path.getDstIpAddress().getHostAddress());
 		
-		for (PushedFlowMod pfm : path.getFlowMods()) {
+		// TODO need update
+		/*for (PushedFlowMod pfm : path.getFlowMods()) {
 			if (log.isTraceEnabled()) {
 				log.trace("Pushing a DELETE flow mod to {}, dst MAC {}",
 						new Object[] {HexString.toHexString(pfm.getDpid()),
 						HexString.toHexString(pfm.getFlowMod().getMatch().getDataLayerDestination())
 				});
 			}
-			
+
 			sendDeleteFlowMod(pfm.getFlowMod(), pfm.getDpid());
-		}
+		}*/
 	}
 	
-	private void sendDeleteFlowMod(OFFlowMod addFlowMod, long dpid) {
-		flowCache.delete(dpid, addFlowMod);
-	}
 	
 	//TODO test next-hop changes
 	//TODO check delete/add synchronization
-	
-	/*
-	 * On startup we need to calculate a full mesh of paths between all gateway
+
+	/**
+	 * On startup, we need to calculate a full mesh of paths between all gateway
 	 * switches
 	 */
 	private void setupFullMesh(){
@@ -674,12 +705,24 @@
 			
 			//See if we know the MAC address of the peer. If not we can't
 			//do anything until we learn it
-			MACAddress macAddress = proxyArp.getMacAddress(peer.getIpAddress());
+			MACAddress macAddress;
+			IDeviceObject nextHopDevice =
+					deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(peer.getIpAddress()));
+
+			if(nextHopDevice == null){
+				log.debug("There is no DeviceObject for {}", peer.getIpAddress().getHostAddress());
+				//Put in the pending paths list first
+				pathsWaitingOnArp.put(peer.getIpAddress(), path);
+				proxyArp.sendArpRequest(peer.getIpAddress(), this, true);
+				continue;
+			}
+			
+			macAddress = MACAddress.valueOf(nextHopDevice.getMACAddress());
+
 			if (macAddress == null) {
 				log.debug("Don't know MAC for {}", peer.getIpAddress().getHostAddress());
 				//Put in the pending paths list first
 				pathsWaitingOnArp.put(peer.getIpAddress(), path);
-				
 				proxyArp.sendArpRequest(peer.getIpAddress(), this, true);
 				continue;
 			}
@@ -688,225 +731,271 @@
 			calculateAndPushPath(path, macAddress);
 		}
 	}
-	
+		
 	private void calculateAndPushPath(Path path, MACAddress dstMacAddress) {
 		Interface dstInterface = path.getDstInterface();
 		
 		log.debug("Setting up path to {}, {}", path.getDstIpAddress().getHostAddress(),
 				dstMacAddress);
-		
-		List<PushedFlowMod> pushedFlows = new ArrayList<PushedFlowMod>();
-		
+
+		FlowPath flowPath = new FlowPath();
+
+		flowPath.setInstallerId(new CallerId("SDNIP"));
+
+		// Set flowPath FlowPathType and FlowPathUserState
+		flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
+		flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
+
+		// Insert the dest-mac based forwarding flow entry to the non-first-hop switches
+		FlowPathFlags flowPathFlags = new FlowPathFlags();
+		flowPathFlags.setFlags(FlowPathFlags.DISCARD_FIRST_HOP_ENTRY);
+		flowPath.setFlowPathFlags(flowPathFlags);
+
+		// Create the DataPath object: dstSwitchPort
+		SwitchPort dstPort = new SwitchPort();
+		dstPort.setDpid(new Dpid(dstInterface.getDpid()));
+		dstPort.setPort(new Port(dstInterface.getPort()));
+
 		for (Interface srcInterface : interfaces.values()) {
+
 			if (dstInterface.equals(srcInterface)){
 				continue;
 			}
-			
-			DataPath shortestPath;
-			if (topology == null) {
-				shortestPath = topologyNetService.getDatabaseShortestPath(
-						srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
+
+			// Create flowPath FlowId
+			//FlowId returnByRefFlowId = new FlowId(flowManagerService.getNextFlowEntryId());
+			//flowPath.setFlowId(returnByRefFlowId);
+			flowPath.setFlowId(new FlowId());
+
+			// Create the DataPath object: srcSwitchPort
+			SwitchPort srcPort = new SwitchPort();
+			srcPort.setDpid(new Dpid(srcInterface.getDpid()));
+			srcPort.setPort(new Port(srcInterface.getPort()));
+
+			DataPath dataPath = new DataPath();
+			dataPath.setSrcPort(srcPort);
+			dataPath.setDstPort(dstPort);
+			flowPath.setDataPath(dataPath);
+
+			// Create the Flow Path Match condition(s)
+			FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
+			flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
+			flowEntryMatch.enableDstMac(dstMacAddress);
+			flowPath.setFlowEntryMatch(flowEntryMatch);
+
+			// NOTE: No need to add ACTION_OUTPUT. It is implied when creating
+			// Shortest Path Flow, and is always the last action for the Flow Entries
+			log.debug("FlowPath of MAC based forwarding: {}", flowPath.toString());
+			if (flowManagerService.addFlow(flowPath) == null) {
+				log.error("Failed to set up MAC based forwarding path to {}, {}",
+						path.getDstIpAddress().getHostAddress(),dstMacAddress);
 			}
 			else {
-				shortestPath = topologyNetService.getTopologyShortestPath(topology, 
-						srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
+				log.debug("Successfully set up MAC based forwarding path to {}, {}",
+						path.getDstIpAddress().getHostAddress(),dstMacAddress);
 			}
-			
-			if (shortestPath == null){
-				log.warn("Shortest path between {} and {} not found",
-						srcInterface.getSwitchPort(), dstInterface.getSwitchPort());
-				return;
-			}
-			
-			List<PushedFlowMod> pushedFlowMods = installPath(shortestPath.flowEntries(), dstMacAddress);
-			pushedFlows.addAll(pushedFlowMods);
 		}
-		
-		path.setFlowMods(pushedFlows);
 	}
-	
-	private List<PushedFlowMod> installPath(List<FlowEntry> flowEntries, MACAddress dstMacAddress){
-		List<PushedFlowMod> flowMods = new ArrayList<PushedFlowMod>();
-		
-		//Set up the flow mod
-		OFFlowMod fm =
-                (OFFlowMod) floodlightProvider.getOFMessageFactory()
-                                              .getMessage(OFType.FLOW_MOD);
-		
-        OFActionOutput action = new OFActionOutput();
-        action.setMaxLength((short)0xffff);
-        List<OFAction> actions = new ArrayList<OFAction>();
-        actions.add(action);
-        
-        fm.setIdleTimeout((short)0)
-        .setHardTimeout((short)0)
-        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-        .setCookie(L2_FWD_COOKIE)
-        .setCommand(OFFlowMod.OFPFC_ADD)
-        .setPriority(SDNIP_PRIORITY)
-        .setActions(actions)
-        .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-        
-        //Don't push the first flow entry. We need to push entries in the
-		//first switch based on IP prefix which we don't know yet.
-        for (int i = 1; i < flowEntries.size(); i++){        	
-        	FlowEntry flowEntry = flowEntries.get(i);
-           
-            OFMatch match = new OFMatch();
-            match.setDataLayerDestination(dstMacAddress.toBytes());
-            match.setWildcards(match.getWildcards() & ~OFMatch.OFPFW_DL_DST);
-            ((OFActionOutput) fm.getActions().get(0)).setPort(flowEntry.outPort().value());
-            
-            fm.setMatch(match);
-            
-            flowMods.add(new PushedFlowMod(flowEntry.dpid().value(), fm));
-            
-            flowCache.write(flowEntry.dpid().value(), fm);
-                        
-            try {
-                fm = fm.clone();
-            } catch (CloneNotSupportedException e1) {
-                log.error("Failure cloning flow mod", e1);
-            }
-		}
-        
-        return flowMods;
-	}
-	
-	private void setupBgpPaths(){
-		for (BgpPeer bgpPeer : bgpPeers.values()){
-			Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
-			
-			DataPath path = topologyNetService.getDatabaseShortestPath(
-					peerInterface.getSwitchPort(), bgpdAttachmentPoint);
-			
-			if (path == null){
-				log.debug("Unable to compute path for BGP traffic for {}",
-							bgpPeer.getIpAddress());
-				continue;
-			}
-			
-			//Set up the flow mod
-			OFFlowMod fm =
-	                (OFFlowMod) floodlightProvider.getOFMessageFactory()
-	                                              .getMessage(OFType.FLOW_MOD);
-			
-	        OFActionOutput action = new OFActionOutput();
-	        action.setMaxLength((short)0xffff);
-	        List<OFAction> actions = new ArrayList<OFAction>();
-	        actions.add(action);
-	        
-	        fm.setIdleTimeout((short)0)
-	        .setHardTimeout((short)0)
-	        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-	        .setCookie(BGP_COOKIE)
-	        .setCommand(OFFlowMod.OFPFC_ADD)
-	        .setPriority(SDNIP_PRIORITY)
-	        .setActions(actions)
-	        .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
 
-	        //Forward = gateway -> bgpd, reverse = bgpd -> gateway
-	        OFMatch forwardMatchSrc = new OFMatch();
-	        
-	        String interfaceCidrAddress = peerInterface.getIpAddress().getHostAddress() 
-	        					+ "/32";
-	        String peerCidrAddress = bgpPeer.getIpAddress().getHostAddress()
-	        					+ "/32";
-	        
-	        //Common match fields
-	        forwardMatchSrc.setDataLayerType(Ethernet.TYPE_IPv4);
-	        forwardMatchSrc.setNetworkProtocol(IPv4.PROTOCOL_TCP);
-	        //forwardMatchSrc.setTransportDestination(BGP_PORT);
-	        forwardMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_IN_PORT
-	        				& ~OFMatch.OFPFW_DL_TYPE & ~OFMatch.OFPFW_NW_PROTO);
-	        
-	        
-	        OFMatch reverseMatchSrc = forwardMatchSrc.clone();
-	        
-	        forwardMatchSrc.setFromCIDR(peerCidrAddress, OFMatch.STR_NW_SRC);
-	        forwardMatchSrc.setFromCIDR(interfaceCidrAddress, OFMatch.STR_NW_DST);
-	        
-	        OFMatch forwardMatchDst = forwardMatchSrc.clone();
-	        
-	        forwardMatchSrc.setTransportSource(BGP_PORT);
-	        forwardMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
-	        forwardMatchDst.setTransportDestination(BGP_PORT);
-	        forwardMatchDst.setWildcards(forwardMatchDst.getWildcards() & ~OFMatch.OFPFW_TP_DST);
-	        
-	        reverseMatchSrc.setFromCIDR(interfaceCidrAddress, OFMatch.STR_NW_SRC);
-	        reverseMatchSrc.setFromCIDR(peerCidrAddress, OFMatch.STR_NW_DST);
-	        
-	        OFMatch reverseMatchDst = reverseMatchSrc.clone();
-	        
-	        reverseMatchSrc.setTransportSource(BGP_PORT);
-	        reverseMatchSrc.setWildcards(forwardMatchSrc.getWildcards() & ~OFMatch.OFPFW_TP_SRC);
-	        reverseMatchDst.setTransportDestination(BGP_PORT);
-	        reverseMatchDst.setWildcards(forwardMatchDst.getWildcards() & ~OFMatch.OFPFW_TP_DST);
-	        
-	        fm.setMatch(forwardMatchSrc);
-	        
-	        OFMatch forwardIcmpMatch = new OFMatch();
-	        forwardIcmpMatch.setDataLayerType(Ethernet.TYPE_IPv4);
-	        forwardIcmpMatch.setNetworkProtocol(IPv4.PROTOCOL_ICMP);
-	        forwardIcmpMatch.setWildcards(forwardIcmpMatch.getWildcards() &
-	        		~OFMatch.OFPFW_DL_TYPE & ~OFMatch.OFPFW_NW_PROTO);
-	        
-	        OFMatch reverseIcmpMatch = forwardIcmpMatch.clone();
-	        forwardIcmpMatch.setFromCIDR(interfaceCidrAddress, OFMatch.STR_NW_DST);
-	        reverseIcmpMatch.setFromCIDR(interfaceCidrAddress, OFMatch.STR_NW_SRC);
-	        
-			for (FlowEntry flowEntry : path.flowEntries()){
-				OFFlowMod forwardFlowModSrc, forwardFlowModDst;
-				OFFlowMod reverseFlowModSrc, reverseFlowModDst;
-				OFFlowMod forwardIcmp, reverseIcmp;
-				try {
-					forwardFlowModSrc = fm.clone();
-					forwardFlowModDst = fm.clone();
-					reverseFlowModSrc = fm.clone();
-					reverseFlowModDst = fm.clone();
-					forwardIcmp = fm.clone();
-					reverseIcmp = fm.clone();
-				} catch (CloneNotSupportedException e) {
-					log.warn("Clone failed", e);
-					continue;
-				}
-				
-				forwardMatchSrc.setInputPort(flowEntry.inPort().value());
-				forwardFlowModSrc.setMatch(forwardMatchSrc);
-				((OFActionOutput)forwardFlowModSrc.getActions().get(0))
-						.setPort(flowEntry.outPort().value());
-				
-				forwardMatchDst.setInputPort(flowEntry.inPort().value());
-				forwardFlowModDst.setMatch(forwardMatchDst);
-				((OFActionOutput)forwardFlowModDst.getActions().get(0))
-						.setPort(flowEntry.outPort().value());
-				
-				reverseMatchSrc.setInputPort(flowEntry.outPort().value());
-				reverseFlowModSrc.setMatch(reverseMatchSrc);
-				((OFActionOutput)reverseFlowModSrc.getActions().get(0))
-						.setPort(flowEntry.inPort().value());
-				
-				reverseMatchDst.setInputPort(flowEntry.outPort().value());
-				reverseFlowModDst.setMatch(reverseMatchDst);
-				((OFActionOutput)reverseFlowModDst.getActions().get(0))
-						.setPort(flowEntry.inPort().value());
-				
-				((OFActionOutput)forwardIcmp.getActions().get(0))
-						.setPort(flowEntry.outPort().value());
-				forwardIcmp.setMatch(forwardIcmpMatch);
-				
-				((OFActionOutput)reverseIcmp.getActions().get(0))
-						.setPort(flowEntry.inPort().value());
-				reverseIcmp.setMatch(reverseIcmpMatch);
-				
-				List<OFFlowMod> flowModList = new ArrayList<OFFlowMod>(6);
-				flowModList.add(forwardFlowModSrc);
-				flowModList.add(forwardFlowModDst);
-				flowModList.add(reverseFlowModSrc);
-				flowModList.add(reverseFlowModDst);
-				flowModList.add(forwardIcmp);
-				flowModList.add(reverseIcmp);
-				flowCache.write(flowEntry.dpid().value(), flowModList);
+	/**
+	 *  Pre-actively install all BGP traffic paths from BGP host attachment point
+	 *  in SDN network to all the virtual gateways to BGP peers in other networks
+	 */
+	private void setupBgpPaths(){
+
+		for (BgpPeer bgpPeer : bgpPeers.values()){
+
+			FlowPath flowPath = new FlowPath();
+			flowPath.setInstallerId(new CallerId("SDNIP"));
+
+			// Set flowPath FlowPathType and FlowPathUserState
+			flowPath.setFlowPathType(FlowPathType.FP_TYPE_SHORTEST_PATH);
+			flowPath.setFlowPathUserState(FlowPathUserState.FP_USER_ADD);
+
+			// Install flow paths between BGPd and its peers
+			// There is no need to set the FlowPathFlags
+			flowPath.setFlowPathFlags(new FlowPathFlags(0));
+
+			Interface peerInterface = interfaces.get(bgpPeer.getInterfaceName());
+
+			// set flowPath FlowId
+			//FlowId returnByRefFlowId = new FlowId(flowManagerService.getNextFlowEntryId());
+			//flowPath.setFlowId(returnByRefFlowId);
+
+
+			// Create the Flow Path Match condition(s)
+			FlowEntryMatch flowEntryMatch = new FlowEntryMatch();
+			flowEntryMatch.enableEthernetFrameType(Ethernet.TYPE_IPv4);
+
+			// Match both source address and dest address
+			IPv4Net dstIPv4Net= new IPv4Net(bgpPeer.getIpAddress().getHostAddress()+"/32");
+			flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
+
+			IPv4Net srcIPv4Net= new IPv4Net(peerInterface.getIpAddress().getHostAddress()+"/32");
+			flowEntryMatch.enableSrcIPv4Net(srcIPv4Net);
+
+			// Match TCP protocol
+			flowEntryMatch.enableIpProto(IPv4.PROTOCOL_TCP);
+
+			// Match destination TCP port
+			flowEntryMatch.enableDstTcpUdpPort(BGP_PORT);
+			flowPath.setFlowEntryMatch(flowEntryMatch);
+
+			/**
+			 * Create the DataPath: BGP -> BGP peer
+			 */
+			// Flow path for src-TCP-port
+			DataPath dataPath = new DataPath();
+
+			SwitchPort srcPort = new SwitchPort();
+			srcPort.setDpid(bgpdAttachmentPoint.dpid());
+			srcPort.setPort(bgpdAttachmentPoint.port());
+			dataPath.setSrcPort(srcPort);
+
+			SwitchPort dstPort = new SwitchPort();
+			dstPort.setDpid(new Dpid(peerInterface.getDpid()));
+			dstPort.setPort(new Port(peerInterface.getSwitchPort().port()));
+			dataPath.setDstPort(dstPort);
+
+			flowPath.setDataPath(dataPath);
+
+			if (flowManagerService.addFlow(flowPath) == null) {
+				log.error("Failed to set up path BGP -> peer {}"+"; dst-TCP-port:179",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+			else {
+				log.debug("Successfully set up path BGP -> peer {}"+"; dst-TCP-port:179",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+
+			// Disable dst-TCP-port, and set src-TCP-port
+			flowEntryMatch.disableDstTcpUdpPort();
+			flowEntryMatch.enableSrcTcpUdpPort(BGP_PORT);
+			flowPath.setFlowEntryMatch(flowEntryMatch);
+
+			// Create a new FlowId
+			//FlowId returnByRefFlowId2 = new FlowId(flowManagerService.getNextFlowEntryId());
+			//flowPath.setFlowId(returnByRefFlowId2);
+			flowPath.setFlowId(new FlowId());
+
+			if (flowManagerService.addFlow(flowPath) == null) {
+				log.error("Failed to set up path BGP -> Peer {}" + "; src-TCP-port:179",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+			else {
+				log.debug("Successfully set up path BGP -> Peer {}" + "; src-TCP-port:179",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+
+			/**
+			 * Create the DataPath: BGP <-BGP peer
+			 */
+			// Reversed BGP flow path for src-TCP-port
+			//FlowId returnByRefFlowId3 = new FlowId(flowManagerService.getNextFlowEntryId());
+			//flowPath.setFlowId(returnByRefFlowId3);
+			flowPath.setFlowId(new FlowId());
+
+			DataPath reverse_dataPath = new DataPath();
+
+			SwitchPort reverse_dstPort = new SwitchPort();
+			reverse_dstPort.setDpid(bgpdAttachmentPoint.dpid());
+			reverse_dstPort.setPort(bgpdAttachmentPoint.port());
+			reverse_dataPath.setDstPort(reverse_dstPort);
+
+			SwitchPort reverse_srcPort = new SwitchPort();
+			reverse_srcPort.setDpid(new Dpid(peerInterface.getDpid()));
+			reverse_srcPort.setPort(new Port(peerInterface.getSwitchPort().port()));
+			reverse_dataPath.setSrcPort(reverse_srcPort);
+			flowPath.setDataPath(reverse_dataPath);
+
+			// reverse the dst IP and src IP addresses
+			flowEntryMatch.enableDstIPv4Net(srcIPv4Net);
+			flowEntryMatch.enableSrcIPv4Net(dstIPv4Net);
+			flowPath.setFlowEntryMatch(flowEntryMatch);
+
+			log.debug("Reversed BGP FlowPath: {}", flowPath.toString());
+
+			if (flowManagerService.addFlow(flowPath) == null) {
+
+				log.error("Failed to set up path BGP <- Peer {}" + "; src-TCP-port:179",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+			else {
+				log.debug("Successfully set up path BGP <- Peer {}" + "; src-TCP-port:179",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+
+			// Reversed BGP flow path for dst-TCP-port
+			//FlowId returnByRefFlowId4 = new FlowId(flowManagerService.getNextFlowEntryId());
+			//flowPath.setFlowId(returnByRefFlowId4);
+			flowPath.setFlowId(new FlowId());
+
+			// Disable src-TCP-port, and set the dst-TCP-port
+			flowEntryMatch.disableSrcTcpUdpPort();
+			flowEntryMatch.enableDstTcpUdpPort(BGP_PORT);
+			flowPath.setFlowEntryMatch(flowEntryMatch);
+
+			log.debug("Reversed BGP FlowPath: {}", flowPath.toString());
+			
+			if (flowManagerService.addFlow(flowPath) == null) {
+				log.error("Failed to setting up path BGP <- Peer {}" + "; dst-TCP-port:179",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+			else {
+				log.debug("Successfully setting up path BGP <- Peer {}" + "; dst-TCP-port:179",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+
+			/**
+			 * ICMP paths between BGPd and its peers
+			 */
+			//match ICMP protocol BGP <- Peer
+			//FlowId returnByRefFlowId5 = new FlowId(flowManagerService.getNextFlowEntryId());
+			//flowPath.setFlowId(returnByRefFlowId5);
+			flowPath.setFlowId(new FlowId());
+
+			flowEntryMatch.enableIpProto(IPv4.PROTOCOL_ICMP);
+			flowEntryMatch.disableSrcTcpUdpPort();
+			flowEntryMatch.disableDstTcpUdpPort();
+
+			flowPath.setFlowEntryMatch(flowEntryMatch);
+
+			flowPath.setDataPath(reverse_dataPath);
+
+			log.debug("Reversed ICMP FlowPath: {}", flowPath.toString());
+
+			if (flowManagerService.addFlow(flowPath) == null) {
+
+				log.error("Failed to set up ICMP path BGP <- Peer {}",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+			else {
+				log.debug("Successfully set up ICMP path BGP <- Peer {}",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+
+			//match ICMP protocol BGP -> Peer
+			//FlowId returnByRefFlowId6 = new FlowId(flowManagerService.getNextFlowEntryId());
+			//flowPath.setFlowId(returnByRefFlowId6);
+			flowPath.setFlowId(new FlowId());
+
+			flowEntryMatch.enableDstIPv4Net(dstIPv4Net);
+			flowEntryMatch.enableSrcIPv4Net(srcIPv4Net);
+			flowPath.setFlowEntryMatch(flowEntryMatch);
+
+			flowPath.setDataPath(dataPath);
+
+			log.debug("ICMP flowPath: {}", flowPath.toString());
+
+
+			if (flowManagerService.addFlow(flowPath) == null) {
+
+				log.error("Failed to set up ICMP path BGP -> Peer {}",
+						bgpPeer.getIpAddress().getHostAddress());
+			}
+			else {
+				log.debug("Successfully set up ICMP path BGP -> Peer {}",
+						bgpPeer.getIpAddress().getHostAddress());
 			}
 		}
 	}
@@ -965,6 +1054,7 @@
 		}
 	}
 	
+	//TODO wait the priority module of the flow Manager
 	private void setupArpFlows() {
 		OFMatch match = new OFMatch();
 		match.setDataLayerType(Ethernet.TYPE_ARP);
@@ -981,36 +1071,36 @@
 		fm.setActions(actions);
 		
 		fm.setIdleTimeout((short)0)
-        .setHardTimeout((short)0)
-        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-        .setCookie(0)
-        .setCommand(OFFlowMod.OFPFC_ADD)
-        .setPriority(ARP_PRIORITY)
+		.setHardTimeout((short)0)
+		.setBufferId(OFPacketOut.BUFFER_ID_NONE)
+		.setCookie(0)
+		.setCommand(OFFlowMod.OFPFC_ADD)
+		.setPriority(ARP_PRIORITY)
 		.setLengthU(OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH);
 		
 		for (String strdpid : switches){
 			flowCache.write(HexString.toLong(strdpid), fm);
 		}
 	}
-	
+	//TODO need update, waiting for the priority feature from flow Manager
 	private void setupDefaultDropFlows() {
 		OFFlowMod fm = new OFFlowMod();
 		fm.setMatch(new OFMatch());
 		fm.setActions(new ArrayList<OFAction>()); //No action means drop
 		
 		fm.setIdleTimeout((short)0)
-        .setHardTimeout((short)0)
-        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-        .setCookie(0)
-        .setCommand(OFFlowMod.OFPFC_ADD)
-        .setPriority((short)0)
+		.setHardTimeout((short)0)
+		.setBufferId(OFPacketOut.BUFFER_ID_NONE)
+		.setCookie(0)
+		.setCommand(OFFlowMod.OFPFC_ADD)
+		.setPriority((short)0)
 		.setLengthU(OFFlowMod.MINIMUM_LENGTH);
 		
 		OFFlowMod fmLLDP;
 		OFFlowMod fmBDDP;
 		try {
-			 fmLLDP = fm.clone();
-			 fmBDDP = fm.clone();
+			fmLLDP = fm.clone();
+			fmBDDP = fm.clone();
 		} catch (CloneNotSupportedException e1) {
 			log.error("Error cloning flow mod", e1);
 			return;
@@ -1054,8 +1144,9 @@
 		log.debug("Topology is now ready, beginning routing function");
 		topology = topologyNetService.newDatabaseTopology();
 		
-		setupArpFlows();
-		setupDefaultDropFlows();
+		// Wait Pavlin's API. We need the following functions.
+		/*setupArpFlows();
+		setupDefaultDropFlows();*/
 		
 		setupBgpPaths();
 		setupFullMesh();
@@ -1073,11 +1164,22 @@
 		});
 	}
 	
+	// Before inserting the paths for BGP traffic, we should check
+	// whether all the switches in the configure file are discovered by onos.
 	private void checkSwitchesConnected(){
 		for (String dpid : switches){
-			if (floodlightProvider.getSwitches().get(HexString.toLong(dpid)) == null){
-				log.debug("Not all switches are here yet");
-				return;
+			Iterator<ISwitchObject> activeSwitches = topoSwitchService.
+					getActiveSwitches().iterator();
+			while(activeSwitches.hasNext())
+			{
+				ISwitchObject switchObject = activeSwitches.next();
+				if (switchObject.getDPID().equals(dpid)) {
+					break;
+				}
+				if(activeSwitches.hasNext() == false) {
+					log.debug("Not all switches are here yet");
+					return;
+				}
 			}
 		}
 		switchesConnected = true;
diff --git a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java
deleted file mode 100644
index 3dba4f8..0000000
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/BgpProxyArpManager.java
+++ /dev/null
@@ -1,637 +0,0 @@
-package net.onrc.onos.ofcontroller.proxyarp;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Timer;
-import java.util.TimerTask;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.packet.ARP;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.bgproute.Interface;
-import net.onrc.onos.ofcontroller.core.IDeviceStorage;
-import net.onrc.onos.ofcontroller.core.config.IConfigInfoService;
-import net.onrc.onos.ofcontroller.core.internal.DeviceStorageImpl;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.Multimaps;
-import com.google.common.collect.SetMultimap;
-
-public class BgpProxyArpManager implements IProxyArpService, IOFMessageListener {
-	private final static Logger log = LoggerFactory.getLogger(BgpProxyArpManager.class);
-	
-	private final long ARP_TIMER_PERIOD = 60000; //ms (== 1 min) 
-	
-	private static final int ARP_REQUEST_TIMEOUT = 2000; //ms
-			
-	private IFloodlightProviderService floodlightProvider;
-	private ITopologyService topology;
-	//private IDeviceService deviceService;
-	private IConfigInfoService configService;
-	private IRestApiService restApi;
-	
-	private IDeviceStorage deviceStorage;
-	
-	private short vlan;
-	private static final short NO_VLAN = 0;
-	
-	private ArpCache arpCache;
-
-	private SetMultimap<InetAddress, ArpRequest> arpRequests;
-	
-	private static class ArpRequest {
-		private final IArpRequester requester;
-		private final boolean retry;
-		private long requestTime;
-		
-		public ArpRequest(IArpRequester requester, boolean retry){
-			this.requester = requester;
-			this.retry = retry;
-			this.requestTime = System.currentTimeMillis();
-		}
-		
-		public ArpRequest(ArpRequest old) {
-			this.requester = old.requester;
-			this.retry = old.retry;
-			this.requestTime = System.currentTimeMillis();
-		}
-		
-		public boolean isExpired() {
-			return (System.currentTimeMillis() - requestTime) > ARP_REQUEST_TIMEOUT;
-		}
-		
-		public boolean shouldRetry() {
-			return retry;
-		}
-		
-		public void dispatchReply(InetAddress ipAddress, MACAddress replyMacAddress) {
-			requester.arpResponse(ipAddress, replyMacAddress);
-		}
-	}
-	
-	private class HostArpRequester implements IArpRequester {
-		private final ARP arpRequest;
-		private final long dpid;
-		private final short port;
-		
-		public HostArpRequester(ARP arpRequest, long dpid, short port) {
-			this.arpRequest = arpRequest;
-			this.dpid = dpid;
-			this.port = port;
-		}
-
-		@Override
-		public void arpResponse(InetAddress ipAddress, MACAddress macAddress) {
-			BgpProxyArpManager.this.sendArpReply(arpRequest, dpid, port, macAddress);
-		}
-	}
-	
-	/*
-	public ProxyArpManager(IFloodlightProviderService floodlightProvider,
-				ITopologyService topology, IConfigInfoService configService,
-				IRestApiService restApi){
-
-	}
-	*/
-	
-	public void init(IFloodlightProviderService floodlightProvider,
-			ITopologyService topology,
-			IConfigInfoService config, IRestApiService restApi){
-		this.floodlightProvider = floodlightProvider;
-		this.topology = topology;
-		//this.deviceService = deviceService;
-		this.configService = config;
-		this.restApi = restApi;
-		
-		arpCache = new ArpCache();
-
-		arpRequests = Multimaps.synchronizedSetMultimap(
-				HashMultimap.<InetAddress, ArpRequest>create());
-	}
-	
-	public void startUp() {
-		this.vlan = configService.getVlan();
-		log.info("vlan set to {}", this.vlan);
-		
-		restApi.addRestletRoutable(new ArpWebRoutable());
-		floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-		
-		deviceStorage = new DeviceStorageImpl();
-		deviceStorage.init("","");
-		
-		Timer arpTimer = new Timer("arp-processing");
-		arpTimer.scheduleAtFixedRate(new TimerTask() {
-			@Override
-			public void run() {
-				doPeriodicArpProcessing();
-			}
-		}, 0, ARP_TIMER_PERIOD);
-	}
-	
-	/*
-	 * Function that runs periodically to manage the asynchronous request mechanism.
-	 * It basically cleans up old ARP requests if we don't get a response for them.
-	 * The caller can designate that a request should be retried indefinitely, and
-	 * this task will handle that as well.
-	 */
-	private void doPeriodicArpProcessing() {
-		SetMultimap<InetAddress, ArpRequest> retryList 
-				= HashMultimap.<InetAddress, ArpRequest>create();
-
-		//Have to synchronize externally on the Multimap while using an iterator,
-		//even though it's a synchronizedMultimap
-		synchronized (arpRequests) {
-			log.debug("Current have {} outstanding requests", 
-					arpRequests.size());
-			
-			Iterator<Map.Entry<InetAddress, ArpRequest>> it 
-				= arpRequests.entries().iterator();
-			
-			while (it.hasNext()) {
-				Map.Entry<InetAddress, ArpRequest> entry
-						= it.next();
-				ArpRequest request = entry.getValue();
-				if (request.isExpired()) {
-					log.debug("Cleaning expired ARP request for {}", 
-							entry.getKey().getHostAddress());
-		
-					it.remove();
-					
-					if (request.shouldRetry()) {
-						retryList.put(entry.getKey(), request);
-					}
-				}
-			}
-		}
-		
-		for (Map.Entry<InetAddress, Collection<ArpRequest>> entry 
-				: retryList.asMap().entrySet()) {
-			
-			InetAddress address = entry.getKey();
-			
-			log.debug("Resending ARP request for {}", address.getHostAddress());
-			
-			sendArpRequestForAddress(address);
-			
-			for (ArpRequest request : entry.getValue()) {
-				arpRequests.put(address, new ArpRequest(request));
-			}
-		}
-	}
-	
-	@Override
-	public String getName() {
-		return "proxyarpmanager";
-	}
-
-	@Override
-	public boolean isCallbackOrderingPrereq(OFType type, String name) {
-		if (type == OFType.PACKET_IN) {
-			return "devicemanager".equals(name);
-		}
-		else {
-			return false;
-		}
-	}
-
-	@Override
-	public boolean isCallbackOrderingPostreq(OFType type, String name) {
-		return false;
-	}
-
-	@Override
-	public Command receive(
-			IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-		
-		if (msg.getType() != OFType.PACKET_IN){
-			return Command.CONTINUE;
-		}
-		
-		OFPacketIn pi = (OFPacketIn) msg;
-		
-		Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, 
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-		
-		if (eth.getEtherType() == Ethernet.TYPE_ARP){
-			ARP arp = (ARP) eth.getPayload();
-			
-			if (arp.getOpCode() == ARP.OP_REQUEST) {
-				//TODO check what the DeviceManager does about propagating
-				//or swallowing ARPs. We want to go after DeviceManager in the
-				//chain but we really need it to CONTINUE ARP packets so we can
-				//get them.
-				handleArpRequest(sw, pi, arp);
-			}
-			else if (arp.getOpCode() == ARP.OP_REPLY) {
-				handleArpReply(sw, pi, arp);
-			}
-		}
-		
-		//TODO should we propagate ARP or swallow it?
-		//Always propagate for now so DeviceManager can learn the host location
-		return Command.CONTINUE;
-	}
-	
-	private void handleArpRequest(IOFSwitch sw, OFPacketIn pi, ARP arp) {
-		if (log.isTraceEnabled()) {
-			log.trace("ARP request received for {}", 
-					inetAddressToString(arp.getTargetProtocolAddress()));
-		}
-
-		InetAddress target;
-		try {
-			 target = InetAddress.getByAddress(arp.getTargetProtocolAddress());
-		} catch (UnknownHostException e) {
-			log.debug("Invalid address in ARP request", e);
-			return;
-		}
-
-		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 (configService.isInterfaceAddress(target)) {
-				log.trace("ARP request for our interface. Sending reply {} => {}",
-						target.getHostAddress(), configService.getRouterMacAddress());
-				
-				sendArpReply(arp, sw.getId(), pi.getInPort(), 
-						configService.getRouterMacAddress());
-			}
-			
-			return;
-		}
-		
-		MACAddress macAddress = arpCache.lookup(target);
-		
-		//IDevice dstDevice = deviceService.fcStore.get(cntx, IDeviceService.CONTEXT_DST_DEVICE);
-		//Iterator<? extends IDevice> it = deviceService.queryDevices(
-				//null, null, InetAddresses.coerceToInteger(target), null, null);
-		
-		//IDevice targetDevice = null;
-		//if (it.hasNext()) {
-			//targetDevice = it.next();
-		//}
-		/*IDeviceObject targetDevice = 
-				deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(target));
-		
-		if (targetDevice != null) {
-			//We have the device in our database, so send a reply
-			MACAddress macAddress = MACAddress.valueOf(targetDevice.getMACAddress());
-			
-			if (log.isTraceEnabled()) {
-				log.trace("Sending reply: {} => {} to host at {}/{}", new Object [] {
-						inetAddressToString(arp.getTargetProtocolAddress()),
-						macAddress.toString(),
-						HexString.toHexString(sw.getId()), pi.getInPort()});
-			}
-			
-			sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
-		}*/
-		
-		if (macAddress == null){
-			//MAC address is not in our ARP cache.
-			
-			//Record where the request came from so we know where to send the reply
-			arpRequests.put(target, new ArpRequest(
-					new HostArpRequester(arp, sw.getId(), pi.getInPort()), false));
-						
-			//Flood the request out edge ports
-			sendArpRequestToSwitches(target, pi.getPacketData(), sw.getId(), pi.getInPort());
-		}
-		else {
-			//We know the address, so send a reply
-			if (log.isTraceEnabled()) {
-				log.trace("Sending reply: {} => {} to host at {}/{}", new Object [] {
-						inetAddressToString(arp.getTargetProtocolAddress()),
-						macAddress.toString(),
-						HexString.toHexString(sw.getId()), pi.getInPort()});
-			}
-			
-			sendArpReply(arp, sw.getId(), pi.getInPort(), macAddress);
-		}
-	}
-	
-	private void handleArpReply(IOFSwitch sw, OFPacketIn pi, ARP arp){
-		if (log.isTraceEnabled()) {
-			log.trace("ARP reply recieved: {} => {}, on {}/{}", new Object[] { 
-					inetAddressToString(arp.getSenderProtocolAddress()),
-					HexString.toHexString(arp.getSenderHardwareAddress()),
-					HexString.toHexString(sw.getId()), pi.getInPort()});
-		}
-		
-		InetAddress senderIpAddress;
-		try {
-			senderIpAddress = InetAddress.getByAddress(arp.getSenderProtocolAddress());
-		} catch (UnknownHostException e) {
-			log.debug("Invalid address in ARP reply", e);
-			return;
-		}
-		
-		MACAddress senderMacAddress = MACAddress.valueOf(arp.getSenderHardwareAddress());
-		
-		arpCache.update(senderIpAddress, senderMacAddress);
-		
-		//See if anyone's waiting for this ARP reply
-		Set<ArpRequest> requests = arpRequests.get(senderIpAddress);
-		
-		//Synchronize on the Multimap while using an iterator for one of the sets
-		List<ArpRequest> requestsToSend = new ArrayList<ArpRequest>(requests.size());
-		synchronized (arpRequests) {
-			Iterator<ArpRequest> it = requests.iterator();
-			while (it.hasNext()) {
-				ArpRequest request = it.next();
-				it.remove();
-				requestsToSend.add(request);
-			}
-		}
-		
-		//Don't hold an ARP lock while dispatching requests
-		for (ArpRequest request : requestsToSend) {
-			request.dispatchReply(senderIpAddress, senderMacAddress);
-		}
-	}
-	
-	private void sendArpRequestForAddress(InetAddress ipAddress) {
-		//TODO what should the sender IP address and MAC address be if no
-		//IP addresses are configured? Will there ever be a need to send
-		//ARP requests from the controller in that case?
-		//All-zero MAC address doesn't seem to work - hosts don't respond to it
-		
-		byte[] zeroIpv4 = {0x0, 0x0, 0x0, 0x0};
-		byte[] zeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-		byte[] genericNonZeroMac = {0x0, 0x0, 0x0, 0x0, 0x0, 0x01};
-		byte[] broadcastMac = {(byte)0xff, (byte)0xff, (byte)0xff, 
-				(byte)0xff, (byte)0xff, (byte)0xff};
-		
-		ARP arpRequest = new ARP();
-		
-		arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
-			.setProtocolType(ARP.PROTO_TYPE_IP)
-			.setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
-			.setProtocolAddressLength((byte)IPv4.ADDRESS_LENGTH)
-			.setOpCode(ARP.OP_REQUEST)
-			.setTargetHardwareAddress(zeroMac)
-			.setTargetProtocolAddress(ipAddress.getAddress());
-
-		MACAddress routerMacAddress = configService.getRouterMacAddress();
-		//TODO hack for now as it's unclear what the MAC address should be
-		byte[] senderMacAddress = genericNonZeroMac;
-		if (routerMacAddress != null) {
-			senderMacAddress = routerMacAddress.toBytes();
-		}
-		arpRequest.setSenderHardwareAddress(senderMacAddress);
-		
-		byte[] senderIPAddress = zeroIpv4;
-		Interface intf = configService.getOutgoingInterface(ipAddress);
-		if (intf != null) {
-			senderIPAddress = intf.getIpAddress().getAddress();
-		}
-		
-		arpRequest.setSenderProtocolAddress(senderIPAddress);
-		
-		Ethernet eth = new Ethernet();
-		eth.setSourceMACAddress(senderMacAddress)
-			.setDestinationMACAddress(broadcastMac)
-			.setEtherType(Ethernet.TYPE_ARP)
-			.setPayload(arpRequest);
-		
-		if (vlan != NO_VLAN) {
-			eth.setVlanID(vlan)
-			   .setPriorityCode((byte)0);
-		}
-		
-		sendArpRequestToSwitches(ipAddress, eth.serialize());
-	}
-	
-	private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest) {
-		sendArpRequestToSwitches(dstAddress, arpRequest, 
-				0, OFPort.OFPP_NONE.getValue());
-	}
-	
-	private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest,
-			long inSwitch, short inPort) {
-
-		if (configService.hasLayer3Configuration()) {
-			Interface intf = configService.getOutgoingInterface(dstAddress);
-			if (intf != null) {
-				sendArpRequestOutPort(arpRequest, intf.getDpid(), intf.getPort());
-			}
-			else {
-				//TODO here it should be broadcast out all non-interface edge ports.
-				//I think we can assume that if it's not a request for an external 
-				//network, it's an ARP for a host in our own network. So we want to 
-				//send it out all edge ports that don't have an interface configured
-				//to ensure it reaches all hosts in our network.
-				log.debug("No interface found to send ARP request for {}",
-						dstAddress.getHostAddress());
-			}
-		}
-		else {
-			broadcastArpRequestOutEdge(arpRequest, inSwitch, inPort);
-		}
-	}
-	
-	private void broadcastArpRequestOutEdge(byte[] arpRequest, long inSwitch, short inPort) {
-		for (IOFSwitch sw : floodlightProvider.getSwitches().values()){
-			Collection<Short> enabledPorts = sw.getEnabledPortNumbers();
-			Set<Short> linkPorts = topology.getPortsWithLinks(sw.getId());
-			
-			if (linkPorts == null){
-				//I think this means the switch doesn't have any links.
-				//continue;
-				linkPorts = new HashSet<Short>();
-			}
-			
-			
-			OFPacketOut po = new OFPacketOut();
-			po.setInPort(OFPort.OFPP_NONE)
-				.setBufferId(-1)
-				.setPacketData(arpRequest);
-				
-			List<OFAction> actions = new ArrayList<OFAction>();
-			
-			for (short portNum : enabledPorts){
-				if (linkPorts.contains(portNum) || 
-						(sw.getId() == inSwitch && portNum == inPort)){
-					//If this port isn't an edge port or is the ingress port
-					//for the ARP, don't broadcast out it
-					continue;
-				}
-				
-				actions.add(new OFActionOutput(portNum));
-			}
-			
-			po.setActions(actions);
-			short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
-			po.setActionsLength(actionsLength);
-			po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength 
-					+ arpRequest.length);
-			
-			List<OFMessage> msgList = new ArrayList<OFMessage>();
-			msgList.add(po);
-			
-			try {
-				sw.write(msgList, null);
-				sw.flush();
-			} catch (IOException e) {
-				log.error("Failure writing packet out to switch", e);
-			}
-		}
-	}
-	
-	private void sendArpRequestOutPort(byte[] arpRequest, long dpid, short port) {
-		if (log.isTraceEnabled()) {
-			log.trace("Sending ARP request out {}/{}", 
-					HexString.toHexString(dpid), port);
-		}
-		
-		OFPacketOut po = new OFPacketOut();
-		po.setInPort(OFPort.OFPP_NONE)
-			.setBufferId(-1)
-			.setPacketData(arpRequest);
-			
-		List<OFAction> actions = new ArrayList<OFAction>();
-		actions.add(new OFActionOutput(port));
-		po.setActions(actions);
-		short actionsLength = (short) (actions.size() * OFActionOutput.MINIMUM_LENGTH);
-		po.setActionsLength(actionsLength);
-		po.setLengthU(OFPacketOut.MINIMUM_LENGTH + actionsLength 
-				+ arpRequest.length);
-		
-		IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
-		
-		if (sw == null) {
-			log.warn("Switch not found when sending ARP request");
-			return;
-		}
-		
-		try {
-			sw.write(po, null);
-			sw.flush();
-		} catch (IOException e) {
-			log.error("Failure writing packet out to switch", e);
-		}
-	}
-	
-	private void sendArpReply(ARP arpRequest, long dpid, short port, MACAddress targetMac) {
-		if (log.isTraceEnabled()) {
-			log.trace("Sending reply {} => {} to {}", new Object[] {
-					inetAddressToString(arpRequest.getTargetProtocolAddress()),
-					targetMac,
-					inetAddressToString(arpRequest.getSenderProtocolAddress())});
-		}
-		
-		ARP arpReply = new ARP();
-		arpReply.setHardwareType(ARP.HW_TYPE_ETHERNET)
-			.setProtocolType(ARP.PROTO_TYPE_IP)
-			.setHardwareAddressLength((byte)Ethernet.DATALAYER_ADDRESS_LENGTH)
-			.setProtocolAddressLength((byte)IPv4.ADDRESS_LENGTH)
-			.setOpCode(ARP.OP_REPLY)
-			.setSenderHardwareAddress(targetMac.toBytes())
-			.setSenderProtocolAddress(arpRequest.getTargetProtocolAddress())
-			.setTargetHardwareAddress(arpRequest.getSenderHardwareAddress())
-			.setTargetProtocolAddress(arpRequest.getSenderProtocolAddress());
-		
-
-		
-		Ethernet eth = new Ethernet();
-		eth.setDestinationMACAddress(arpRequest.getSenderHardwareAddress())
-			.setSourceMACAddress(targetMac.toBytes())
-			.setEtherType(Ethernet.TYPE_ARP)
-			.setPayload(arpReply);
-		
-		if (vlan != NO_VLAN) {
-			eth.setVlanID(vlan)
-			   .setPriorityCode((byte)0);
-		}
-		
-		List<OFAction> actions = new ArrayList<OFAction>();
-		actions.add(new OFActionOutput(port));
-		
-		OFPacketOut po = new OFPacketOut();
-		po.setInPort(OFPort.OFPP_NONE)
-			.setBufferId(-1)
-			.setPacketData(eth.serialize())
-			.setActions(actions)
-			.setActionsLength((short)OFActionOutput.MINIMUM_LENGTH)
-			.setLengthU(OFPacketOut.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH
-					+ po.getPacketData().length);
-		
-		List<OFMessage> msgList = new ArrayList<OFMessage>();
-		msgList.add(po);
-
-		IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
-		
-		if (sw == null) {
-			log.warn("Switch {} not found when sending ARP reply", 
-					HexString.toHexString(dpid));
-			return;
-		}
-		
-		try {
-			sw.write(msgList, null);
-			sw.flush();
-		} catch (IOException e) {
-			log.error("Failure writing packet out to switch", e);
-		}
-	}
-	
-	private String inetAddressToString(byte[] bytes) {
-		try {
-			return InetAddress.getByAddress(bytes).getHostAddress();
-		} catch (UnknownHostException e) {
-			log.debug("Invalid IP address", e);
-			return "";
-		}
-	}
-	
-	/*
-	 * IProxyArpService methods
-	 */
-
-	@Override
-	public MACAddress getMacAddress(InetAddress ipAddress) {
-		return arpCache.lookup(ipAddress);
-	}
-
-	@Override
-	public void sendArpRequest(InetAddress ipAddress, IArpRequester requester,
-			boolean retry) {
-		arpRequests.put(ipAddress, new ArpRequest(requester, retry));
-		
-		//Sanity check to make sure we don't send a request for our own address
-		if (!configService.isInterfaceAddress(ipAddress)) {
-			sendArpRequestForAddress(ipAddress);
-		}
-	}
-	
-	@Override
-	public List<String> getMappings() {
-		return arpCache.getMappings();
-	}
-}
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 f5fee45..c7d495c 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/proxyarp/ProxyArpManager.java
@@ -229,7 +229,6 @@
 					// TODO check whether this is OK from this thread
 					IDeviceObject targetDevice = 
 							deviceStorage.getDeviceByIP(InetAddresses.coerceToInteger(entry.getKey()));
-					
 					if (targetDevice != null) {
 						deviceStorage.removeDevice(targetDevice);
 						if (log.isDebugEnabled()) {
@@ -253,6 +252,8 @@
 			
 			log.debug("Resending ARP request for {}", address.getHostAddress());
 			
+			// Only ARP requests sent by the controller will have the retry flag
+			// set, so for now we can just send a new ARP request for that address.
 			sendArpRequestForAddress(address);
 			
 			for (ArpRequest request : entry.getValue()) {
@@ -433,8 +434,6 @@
 		
 		MACAddress senderMacAddress = MACAddress.valueOf(arp.getSenderHardwareAddress());
 		
-		//arpCache.update(senderIpAddress, senderMacAddress);
-		
 		//See if anyone's waiting for this ARP reply
 		Set<ArpRequest> requests = arpRequests.get(senderIpAddress);
 		
@@ -504,7 +503,8 @@
 			   .setPriorityCode((byte)0);
 		}
 		
-		sendArpRequestToSwitches(ipAddress, eth.serialize());
+		//sendArpRequestToSwitches(ipAddress, eth.serialize());
+		datagrid.sendPacketOutNotification(new SinglePacketOutNotification(eth.serialize(),intf.getDpid(),intf.getPort()));
 	}
 	
 	private void sendArpRequestToSwitches(InetAddress dstAddress, byte[] arpRequest) {
@@ -531,7 +531,8 @@
 			}
 		}
 		else {
-			broadcastArpRequestOutEdge(arpRequest, inSwitch, inPort);
+			//broadcastArpRequestOutEdge(arpRequest, inSwitch, inPort);
+			broadcastArpRequestOutMyEdge(arpRequest, inSwitch, inPort);
 		}
 	}
 	
diff --git a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java
index 595eb5f..3c6ffc4 100644
--- a/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java
+++ b/src/main/java/net/onrc/onos/ofcontroller/util/FlowPathFlags.java
@@ -9,10 +9,10 @@
     private long flags;
 
     // Discard the first-hop Flow Entry
-    private static final long DISCARD_FIRST_HOP_ENTRY   = (1 << 0);
+    public static final long DISCARD_FIRST_HOP_ENTRY   = (1 << 0);
 
     // Keep only the first-hop Flow Entry
-    private static final long KEEP_ONLY_FIRST_HOP_ENTRY = (1 << 1);
+    public static final long KEEP_ONLY_FIRST_HOP_ENTRY = (1 << 1);
 
     /**
      * Default constructor.
@@ -125,4 +125,5 @@
 
 	return ret;
     }
+
 }
