link discovery and providers are implemented
diff --git a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
index 2b1d1da..2a27ba9 100644
--- a/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
+++ b/of/ctl/src/main/java/org/onlab/onos/of/controller/impl/OpenFlowControllerImpl.java
@@ -1,9 +1,18 @@
 package org.onlab.onos.of.controller.impl;
 
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.of.controller.DefaultPacketContext;
 import org.onlab.onos.of.controller.Dpid;
 import org.onlab.onos.of.controller.OpenFlowController;
 import org.onlab.onos.of.controller.OpenFlowSwitch;
@@ -12,18 +21,11 @@
 import org.onlab.onos.of.controller.RoleState;
 import org.onlab.onos.of.controller.driver.OpenFlowAgent;
 import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPacketIn;
 import org.projectfloodlight.openflow.protocol.OFPortStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
 @Component(immediate = true)
 @Service
 public class OpenFlowControllerImpl implements OpenFlowController {
@@ -42,238 +44,244 @@
     protected Set<OpenFlowSwitchListener> ofEventListener =
             new HashSet<>();
 
-    protected List<PacketListener> ofPacketListener =
-            new ArrayList<>();
+            protected List<PacketListener> ofPacketListener =
+                    new ArrayList<>();
 
-    private final Controller ctrl = new Controller();
+                    private final Controller ctrl = new Controller();
 
-    @Activate
-    public void activate() {
-        ctrl.start(agent);
-    }
+                    @Activate
+                    public void activate() {
+                        ctrl.start(agent);
+                    }
 
-    @Deactivate
-    public void deactivate() {
-        ctrl.stop();
-    }
+                    @Deactivate
+                    public void deactivate() {
+                        ctrl.stop();
+                    }
 
-    @Override
-    public Iterable<OpenFlowSwitch> getSwitches() {
-        return connectedSwitches.values();
-    }
+                    @Override
+                    public Iterable<OpenFlowSwitch> getSwitches() {
+                        return connectedSwitches.values();
+                    }
 
-    @Override
-    public Iterable<OpenFlowSwitch> getMasterSwitches() {
-        return activeMasterSwitches.values();
-    }
+                    @Override
+                    public Iterable<OpenFlowSwitch> getMasterSwitches() {
+                        return activeMasterSwitches.values();
+                    }
 
-    @Override
-    public Iterable<OpenFlowSwitch> getEqualSwitches() {
-        return activeEqualSwitches.values();
-    }
+                    @Override
+                    public Iterable<OpenFlowSwitch> getEqualSwitches() {
+                        return activeEqualSwitches.values();
+                    }
 
-    @Override
-    public OpenFlowSwitch getSwitch(Dpid dpid) {
-        return connectedSwitches.get(dpid);
-    }
+                    @Override
+                    public OpenFlowSwitch getSwitch(Dpid dpid) {
+                        return connectedSwitches.get(dpid);
+                    }
 
-    @Override
-    public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
-        return activeMasterSwitches.get(dpid);
-    }
+                    @Override
+                    public OpenFlowSwitch getMasterSwitch(Dpid dpid) {
+                        return activeMasterSwitches.get(dpid);
+                    }
 
-    @Override
-    public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
-        return activeEqualSwitches.get(dpid);
-    }
+                    @Override
+                    public OpenFlowSwitch getEqualSwitch(Dpid dpid) {
+                        return activeEqualSwitches.get(dpid);
+                    }
 
-    @Override
-    public void addListener(OpenFlowSwitchListener listener) {
-        if (!ofEventListener.contains(listener)) {
-            this.ofEventListener.add(listener);
-        }
-    }
+                    @Override
+                    public void addListener(OpenFlowSwitchListener listener) {
+                        if (!ofEventListener.contains(listener)) {
+                            this.ofEventListener.add(listener);
+                        }
+                    }
 
-    @Override
-    public void removeListener(OpenFlowSwitchListener listener) {
-        this.ofEventListener.remove(listener);
-    }
+                    @Override
+                    public void removeListener(OpenFlowSwitchListener listener) {
+                        this.ofEventListener.remove(listener);
+                    }
 
-    @Override
-    public void addPacketListener(int priority, PacketListener listener) {
-        ofPacketListener.add(priority, listener);
-    }
+                    @Override
+                    public void addPacketListener(int priority, PacketListener listener) {
+                        ofPacketListener.add(priority, listener);
+                    }
 
-    @Override
-    public void removePacketListener(PacketListener listener) {
-        ofPacketListener.remove(listener);
-    }
+                    @Override
+                    public void removePacketListener(PacketListener listener) {
+                        ofPacketListener.remove(listener);
+                    }
 
-    @Override
-    public void write(Dpid dpid, OFMessage msg) {
-        this.getSwitch(dpid).sendMsg(msg);
-    }
+                    @Override
+                    public void write(Dpid dpid, OFMessage msg) {
+                        this.getSwitch(dpid).sendMsg(msg);
+                    }
 
-    @Override
-    public void processPacket(Dpid dpid, OFMessage msg) {
-        switch (msg.getType()) {
-            case PORT_STATUS:
-                for (OpenFlowSwitchListener l : ofEventListener) {
-                    l.portChanged(dpid, (OFPortStatus) msg);
-                }
-                break;
-            case PACKET_IN:
-                for (PacketListener p : ofPacketListener) {
-                    //TODO fix me!
-                    p.handlePacket(null);
-                }
-                break;
-            default:
-                log.warn("Handling message type {} not yet implemented", msg.getType());
-        }
-    }
+                    @Override
+                    public void processPacket(Dpid dpid, OFMessage msg) {
+                        switch (msg.getType()) {
+                        case PORT_STATUS:
+                            for (OpenFlowSwitchListener l : ofEventListener) {
+                                l.portChanged(dpid, (OFPortStatus) msg);
+                            }
+                            break;
+                        case PACKET_IN:
+                            for (PacketListener p : ofPacketListener) {
+                                //TODO fix me!
+                                p.handlePacket(DefaultPacketContext
+                                        .packetContextFromPacketIn(this.getSwitch(dpid),
+                                                (OFPacketIn) msg));
+                            }
+                            break;
+                        default:
+                            log.warn("Handling message type {} not yet implemented {}",
+                                    msg.getType(), msg);
+                        }
+                    }
 
-    @Override
-    public void setRole(Dpid dpid, RoleState role) {
-        getSwitch(dpid).setRole(role);
-    }
+                    @Override
+                    public void setRole(Dpid dpid, RoleState role) {
+                        getSwitch(dpid).setRole(role);
+                    }
 
-    /**
-     * Implementation of an OpenFlow Agent which is responsible for
-     * keeping track of connected switches and the state in which
-     * they are.
-     */
-    public class OpenFlowSwitchAgent implements OpenFlowAgent {
+                    /**
+                     * Implementation of an OpenFlow Agent which is responsible for
+                     * keeping track of connected switches and the state in which
+                     * they are.
+                     */
+                    public class OpenFlowSwitchAgent implements OpenFlowAgent {
 
-        private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
-        private final Lock switchLock = new ReentrantLock();
+                        private final Logger log = LoggerFactory.getLogger(OpenFlowSwitchAgent.class);
+                        private final Lock switchLock = new ReentrantLock();
 
-        @Override
-        public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
-            if (connectedSwitches.get(dpid) != null) {
-                log.error("Trying to add connectedSwitch but found a previous "
-                                  + "value for dpid: {}", dpid);
-                return false;
-            } else {
-                log.error("Added switch {}", dpid);
-                connectedSwitches.put(dpid, sw);
-                for (OpenFlowSwitchListener l : ofEventListener) {
-                    l.switchAdded(dpid);
-                }
-                return true;
-            }
-        }
+                        @Override
+                        public boolean addConnectedSwitch(Dpid dpid, OpenFlowSwitch sw) {
+                            if (connectedSwitches.get(dpid) != null) {
+                                log.error("Trying to add connectedSwitch but found a previous "
+                                        + "value for dpid: {}", dpid);
+                                return false;
+                            } else {
+                                log.error("Added switch {}", dpid);
+                                connectedSwitches.put(dpid, sw);
+                                for (OpenFlowSwitchListener l : ofEventListener) {
+                                    l.switchAdded(dpid);
+                                }
+                                return true;
+                            }
+                        }
 
-        @Override
-        public boolean validActivation(Dpid dpid) {
-            if (connectedSwitches.get(dpid) == null) {
-                log.error("Trying to activate switch but is not in "
-                                  + "connected switches: dpid {}. Aborting ..",
-                          dpid);
-                return false;
-            }
-            if (activeMasterSwitches.get(dpid) != null ||
-                    activeEqualSwitches.get(dpid) != null) {
-                log.error("Trying to activate switch but it is already "
-                                  + "activated: dpid {}. Found in activeMaster: {} "
-                                  + "Found in activeEqual: {}. Aborting ..", new Object[]{
-                        dpid,
-                        (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
-                        (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
-                return false;
-            }
-            return true;
-        }
+                        @Override
+                        public boolean validActivation(Dpid dpid) {
+                            if (connectedSwitches.get(dpid) == null) {
+                                log.error("Trying to activate switch but is not in "
+                                        + "connected switches: dpid {}. Aborting ..",
+                                        dpid);
+                                return false;
+                            }
+                            if (activeMasterSwitches.get(dpid) != null ||
+                                    activeEqualSwitches.get(dpid) != null) {
+                                log.error("Trying to activate switch but it is already "
+                                        + "activated: dpid {}. Found in activeMaster: {} "
+                                        + "Found in activeEqual: {}. Aborting ..", new Object[]{
+                                                dpid,
+                                                (activeMasterSwitches.get(dpid) == null) ? 'N' : 'Y',
+                                                        (activeEqualSwitches.get(dpid) == null) ? 'N' : 'Y'});
+                                return false;
+                            }
+                            return true;
+                        }
 
 
-        @Override
-        public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) {
-            switchLock.lock();
-            try {
-                if (!validActivation(dpid)) {
-                    return false;
-                }
-                activeMasterSwitches.put(dpid, sw);
-                return true;
-            } finally {
-                switchLock.unlock();
-            }
-        }
+                        @Override
+                        public boolean addActivatedMasterSwitch(Dpid dpid, OpenFlowSwitch sw) {
+                            switchLock.lock();
+                            try {
+                                if (!validActivation(dpid)) {
+                                    return false;
+                                }
+                                activeMasterSwitches.put(dpid, sw);
+                                return true;
+                            } finally {
+                                switchLock.unlock();
+                            }
+                        }
 
-        @Override
-        public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) {
-            switchLock.lock();
-            try {
-                if (!validActivation(dpid)) {
-                    return false;
-                }
-                activeEqualSwitches.put(dpid, sw);
-                log.info("Added Activated EQUAL Switch {}", dpid);
-                return true;
-            } finally {
-                switchLock.unlock();
-            }
-        }
+                        @Override
+                        public boolean addActivatedEqualSwitch(Dpid dpid, OpenFlowSwitch sw) {
+                            switchLock.lock();
+                            try {
+                                if (!validActivation(dpid)) {
+                                    return false;
+                                }
+                                activeEqualSwitches.put(dpid, sw);
+                                log.info("Added Activated EQUAL Switch {}", dpid);
+                                return true;
+                            } finally {
+                                switchLock.unlock();
+                            }
+                        }
 
-        @Override
-        public void transitionToMasterSwitch(Dpid dpid) {
-            switchLock.lock();
-            try {
-                if (activeMasterSwitches.containsKey(dpid)) {
-                    return;
-                }
-                OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
-                if (sw == null) {
-                    log.error("Transition to master called on sw {}, but switch "
-                                      + "was not found in controller-cache", dpid);
-                    return;
-                }
-                log.info("Transitioned switch {} to MASTER", dpid);
-                activeMasterSwitches.put(dpid, sw);
-            } finally {
-                switchLock.unlock();
-            }
-        }
+                        @Override
+                        public void transitionToMasterSwitch(Dpid dpid) {
+                            switchLock.lock();
+                            try {
+                                if (activeMasterSwitches.containsKey(dpid)) {
+                                    return;
+                                }
+                                OpenFlowSwitch sw = activeEqualSwitches.remove(dpid);
+                                if (sw == null) {
+                                    sw = getSwitch(dpid);
+                                    if (sw == null) {
+                                        log.error("Transition to master called on sw {}, but switch "
+                                                + "was not found in controller-cache", dpid);
+                                        return;
+                                    }
+                                }
+                                log.info("Transitioned switch {} to MASTER", dpid);
+                                activeMasterSwitches.put(dpid, sw);
+                            } finally {
+                                switchLock.unlock();
+                            }
+                        }
 
 
-        @Override
-        public void transitionToEqualSwitch(Dpid dpid) {
-            switchLock.lock();
-            try {
-                if (activeEqualSwitches.containsKey(dpid)) {
-                    return;
-                }
-                OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
-                if (sw == null) {
-                    log.error("Transition to equal called on sw {}, but switch "
-                                      + "was not found in controller-cache", dpid);
-                    return;
-                }
-                log.info("Transitioned switch {} to EQUAL", dpid);
-                activeEqualSwitches.put(dpid, sw);
-            } finally {
-                switchLock.unlock();
-            }
+                        @Override
+                        public void transitionToEqualSwitch(Dpid dpid) {
+                            switchLock.lock();
+                            try {
+                                if (activeEqualSwitches.containsKey(dpid)) {
+                                    return;
+                                }
+                                OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
+                                if (sw == null) {
+                                    log.error("Transition to equal called on sw {}, but switch "
+                                            + "was not found in controller-cache", dpid);
+                                    return;
+                                }
+                                log.info("Transitioned switch {} to EQUAL", dpid);
+                                activeEqualSwitches.put(dpid, sw);
+                            } finally {
+                                switchLock.unlock();
+                            }
 
-        }
+                        }
 
-        @Override
-        public void removeConnectedSwitch(Dpid dpid) {
-            connectedSwitches.remove(dpid);
-            OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
-            if (sw == null) {
-                sw = activeEqualSwitches.remove(dpid);
-            }
-            for (OpenFlowSwitchListener l : ofEventListener) {
-                l.switchRemoved(dpid);
-            }
-        }
+                        @Override
+                        public void removeConnectedSwitch(Dpid dpid) {
+                            connectedSwitches.remove(dpid);
+                            OpenFlowSwitch sw = activeMasterSwitches.remove(dpid);
+                            if (sw == null) {
+                                sw = activeEqualSwitches.remove(dpid);
+                            }
+                            for (OpenFlowSwitchListener l : ofEventListener) {
+                                l.switchRemoved(dpid);
+                            }
+                        }
 
-        @Override
-        public void processMessage(Dpid dpid, OFMessage m) {
-            processPacket(dpid, m);
-        }
-    }
+                        @Override
+                        public void processMessage(Dpid dpid, OFMessage m) {
+                            processPacket(dpid, m);
+                        }
+                    }
 
 
 }