diff --git a/src/main/java/org/onosproject/aaa/AaaManager.java b/src/main/java/org/onosproject/aaa/AaaManager.java
new file mode 100644
index 0000000..dd324ee
--- /dev/null
+++ b/src/main/java/org/onosproject/aaa/AaaManager.java
@@ -0,0 +1,562 @@
+/*
+ * Copyright 2015 AT&T Foundry
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.aaa;
+
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
+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.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.EAP;
+import org.onlab.packet.EAPOL;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.RADIUS;
+import org.onlab.packet.RADIUSAttribute;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.packet.DefaultOutboundPacket;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.onosproject.xosintegration.VoltTenantService;
+import org.slf4j.Logger;
+
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
+import static org.onosproject.net.packet.PacketPriority.CONTROL;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * AAA application for ONOS.
+ */
+@Component(immediate = true)
+public class AaaManager {
+
+    // for verbose output
+    private final Logger log = getLogger(getClass());
+
+    // a list of our dependencies :
+    // to register with ONOS as an application - described next
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    // to receive Packet-in events that we'll respond to
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected PacketService packetService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected VoltTenantService voltTenantService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigRegistry netCfgService;
+
+    // Parsed RADIUS server addresses
+    protected InetAddress radiusIpAddress;
+    protected String radiusMacAddress;
+
+    // NAS IP address
+    protected InetAddress nasIpAddress;
+    protected String nasMacAddress;
+
+    // RADIUS server secret
+    protected String radiusSecret;
+
+    // ID of RADIUS switch
+    protected String radiusSwitch;
+
+    // RADIUS port number
+    protected long radiusPort;
+
+    // RADIUS server TCP port number
+    protected short radiusServerPort;
+
+    // our application-specific event handler
+    private ReactivePacketProcessor processor = new ReactivePacketProcessor();
+
+    // our unique identifier
+    private ApplicationId appId;
+
+    // Socket used for UDP communications with RADIUS server
+    private DatagramSocket radiusSocket;
+
+    // Executor for RADIUS communication thread
+    private ExecutorService executor;
+
+    // Configuration properties factory
+    private final ConfigFactory factory =
+            new ConfigFactory<ApplicationId, AaaConfig>(APP_SUBJECT_FACTORY,
+                                                         AaaConfig.class,
+                                                         "AAA") {
+                @Override
+                public AaaConfig createConfig() {
+                    return new AaaConfig();
+                }
+            };
+
+    // Listener for config changes
+    private final InternalConfigListener cfgListener = new InternalConfigListener();
+
+    /**
+     * Builds an EAPOL packet based on the given parameters.
+     *
+     * @param dstMac    destination MAC address
+     * @param srcMac    source MAC address
+     * @param vlan      vlan identifier
+     * @param eapolType EAPOL type
+     * @param eap       EAP payload
+     * @return Ethernet frame
+     */
+    private static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
+                                               short vlan, byte eapolType, EAP eap) {
+
+        Ethernet eth = new Ethernet();
+        eth.setDestinationMACAddress(dstMac.toBytes());
+        eth.setSourceMACAddress(srcMac.toBytes());
+        eth.setEtherType(EthType.EtherType.EAPOL.ethType().toShort());
+        if (vlan != Ethernet.VLAN_UNTAGGED) {
+            eth.setVlanID(vlan);
+        }
+        //eapol header
+        EAPOL eapol = new EAPOL();
+        eapol.setEapolType(eapolType);
+        eapol.setPacketLength(eap.getLength());
+
+        //eap part
+        eapol.setPayload(eap);
+
+        eth.setPayload(eapol);
+        eth.setPad(true);
+        return eth;
+    }
+
+    @Activate
+    public void activate() {
+        netCfgService.addListener(cfgListener);
+        netCfgService.registerConfigFactory(factory);
+
+        // "org.onosproject.aaa" is the FQDN of our app
+        appId = coreService.registerApplication("org.onosproject.aaa");
+
+        cfgListener.reconfigureNetwork(netCfgService.getConfig(appId, AaaConfig.class));
+
+        // register our event handler
+        packetService.addProcessor(processor, PacketProcessor.director(2));
+        requestIntercepts();
+
+        StateMachine.initializeMaps();
+
+        try {
+            radiusSocket = new DatagramSocket(radiusServerPort);
+        } catch (Exception ex) {
+            log.error("Can't open RADIUS socket", ex);
+        }
+
+        executor = Executors.newSingleThreadExecutor(
+                new ThreadFactoryBuilder()
+                        .setNameFormat("AAA-radius-%d").build());
+        executor.execute(radiusListener);
+    }
+
+    @Deactivate
+    public void deactivate() {
+        appId = coreService.registerApplication("org.onosproject.aaa");
+        withdrawIntercepts();
+        // de-register and null our handler
+        packetService.removeProcessor(processor);
+        processor = null;
+        StateMachine.destroyMaps();
+        radiusSocket.close();
+        executor.shutdownNow();
+    }
+
+    protected void sendRadiusPacket(RADIUS radiusPacket) {
+
+        try {
+            final byte[] data = radiusPacket.serialize();
+            final DatagramSocket socket = radiusSocket;
+
+            DatagramPacket packet =
+                    new DatagramPacket(data, data.length,
+                                       radiusIpAddress, radiusServerPort);
+
+            socket.send(packet);
+        } catch (IOException e) {
+            log.info("Cannot send packet to RADIUS server", e);
+        }
+    }
+
+    /**
+     * Request packet in via PacketService.
+     */
+    private void requestIntercepts() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort());
+        packetService.requestPackets(selector.build(),
+                                     CONTROL, appId);
+    }
+
+    /**
+     * Cancel request for packet in via PacketService.
+     */
+    private void withdrawIntercepts() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        selector.matchEthType(EthType.EtherType.EAPOL.ethType().toShort());
+        packetService.cancelPackets(selector.build(), CONTROL, appId);
+    }
+
+    /**
+     * Send the ethernet packet to the supplicant.
+     *
+     * @param ethernetPkt  the ethernet packet
+     * @param connectPoint the connect point to send out
+     */
+    private void sendPacketToSupplicant(Ethernet ethernetPkt, ConnectPoint connectPoint) {
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(connectPoint.port()).build();
+        OutboundPacket packet = new DefaultOutboundPacket(connectPoint.deviceId(),
+                                                          treatment, ByteBuffer.wrap(ethernetPkt.serialize()));
+        packetService.emit(packet);
+    }
+
+    // our handler defined as a private inner class
+
+    /**
+     * Packet processor responsible for forwarding packets along their paths.
+     */
+    private class ReactivePacketProcessor implements PacketProcessor {
+        @Override
+        public void process(PacketContext context) {
+
+            // Extract the original Ethernet frame from the packet information
+            InboundPacket pkt = context.inPacket();
+            Ethernet ethPkt = pkt.parsed();
+            if (ethPkt == null) {
+                return;
+            }
+            try {
+                // identify if incoming packet comes from supplicant (EAP) or RADIUS
+                switch (EthType.EtherType.lookup(ethPkt.getEtherType())) {
+                    case EAPOL:
+                        handleSupplicantPacket(context.inPacket());
+                        break;
+                    default:
+                        log.trace("Skipping Ethernet packet type {}",
+                                  EthType.EtherType.lookup(ethPkt.getEtherType()));
+                }
+            } catch (StateMachineException e) {
+                log.warn("Unable to process RADIUS packet:", e);
+            }
+        }
+
+        /**
+         * Creates and initializes common fields of a RADIUS packet.
+         *
+         * @param stateMachine state machine for the request
+         * @param eapPacket  EAP packet
+         * @return RADIUS packet
+         */
+        private RADIUS getRadiusPayload(StateMachine stateMachine, byte identifier, EAP eapPacket) {
+            RADIUS radiusPayload =
+                    new RADIUS(RADIUS.RADIUS_CODE_ACCESS_REQUEST,
+                               eapPacket.getIdentifier());
+
+            // set Request Authenticator in StateMachine
+            stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
+
+            radiusPayload.setIdentifier(identifier);
+            radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_USERNAME,
+                                       stateMachine.username());
+
+            radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_NAS_IP,
+                    AaaManager.this.nasIpAddress.getAddress());
+
+            radiusPayload.encapsulateMessage(eapPacket);
+
+            return radiusPayload;
+        }
+
+        /**
+         * Handles PAE packets (supplicant).
+         *
+         * @param inPacket Ethernet packet coming from the supplicant
+         */
+        private void handleSupplicantPacket(InboundPacket inPacket) throws StateMachineException {
+            Ethernet ethPkt = inPacket.parsed();
+            // Where does it come from?
+            MacAddress srcMac = ethPkt.getSourceMAC();
+
+            DeviceId deviceId = inPacket.receivedFrom().deviceId();
+            PortNumber portNumber = inPacket.receivedFrom().port();
+            String sessionId = deviceId.toString() + portNumber.toString();
+            StateMachine stateMachine = StateMachine.lookupStateMachineBySessionId(sessionId);
+            if (stateMachine == null) {
+                stateMachine = new StateMachine(sessionId, voltTenantService);
+            }
+
+
+            EAPOL eapol = (EAPOL) ethPkt.getPayload();
+
+            switch (eapol.getEapolType()) {
+                case EAPOL.EAPOL_START:
+                    stateMachine.start();
+                    stateMachine.setSupplicantConnectpoint(inPacket.receivedFrom());
+
+                    //send an EAP Request/Identify to the supplicant
+                    EAP eapPayload = new EAP(EAP.REQUEST, stateMachine.identifier(), EAP.ATTR_IDENTITY, null);
+                    Ethernet eth = buildEapolResponse(srcMac, MacAddress.valueOf(nasMacAddress),
+                                                      ethPkt.getVlanID(), EAPOL.EAPOL_PACKET,
+                                                      eapPayload);
+                    stateMachine.setSupplicantAddress(srcMac);
+                    stateMachine.setVlanId(ethPkt.getVlanID());
+
+                    sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+
+                    break;
+                case EAPOL.EAPOL_PACKET:
+                    RADIUS radiusPayload;
+                    // check if this is a Response/Identify or  a Response/TLS
+                    EAP eapPacket = (EAP) eapol.getPayload();
+
+                    byte dataType = eapPacket.getDataType();
+                    switch (dataType) {
+
+                        case EAP.ATTR_IDENTITY:
+                            // request id access to RADIUS
+                            stateMachine.setUsername(eapPacket.getData());
+
+                            radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket);
+                            radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
+
+                            sendRadiusPacket(radiusPayload);
+
+                            // change the state to "PENDING"
+                            stateMachine.requestAccess();
+                            break;
+                        case EAP.ATTR_MD5:
+                            // verify if the EAP identifier corresponds to the
+                            // challenge identifier from the client state
+                            // machine.
+                            if (eapPacket.getIdentifier() == stateMachine.challengeIdentifier()) {
+                                //send the RADIUS challenge response
+                                radiusPayload =
+                                        getRadiusPayload(stateMachine,
+                                                         stateMachine.identifier(),
+                                                         eapPacket);
+
+                                radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
+                                                           stateMachine.challengeState());
+                                radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
+                                sendRadiusPacket(radiusPayload);
+                            }
+                            break;
+                        case EAP.ATTR_TLS:
+                            // request id access to RADIUS
+                            radiusPayload = getRadiusPayload(stateMachine, stateMachine.identifier(), eapPacket);
+
+                            radiusPayload.setAttribute(RADIUSAttribute.RADIUS_ATTR_STATE,
+                                    stateMachine.challengeState());
+                            stateMachine.setRequestAuthenticator(radiusPayload.generateAuthCode());
+
+                            radiusPayload.addMessageAuthenticator(AaaManager.this.radiusSecret);
+                            sendRadiusPacket(radiusPayload);
+
+                            if (stateMachine.state() != StateMachine.STATE_PENDING) {
+                                stateMachine.requestAccess();
+                            }
+
+                            break;
+                        default:
+                            return;
+                    }
+                    break;
+                default:
+                    log.trace("Skipping EAPOL message {}", eapol.getEapolType());
+            }
+
+        }
+    }
+
+    class RadiusListener implements Runnable {
+
+        /**
+         * Handles RADIUS packets.
+         *
+         * @param radiusPacket RADIUS packet coming from the RADIUS server.
+         * @throws StateMachineException if an illegal state transition is triggered
+         */
+        protected void handleRadiusPacket(RADIUS radiusPacket) throws StateMachineException {
+            StateMachine stateMachine = StateMachine.lookupStateMachineById(radiusPacket.getIdentifier());
+            if (stateMachine == null) {
+                log.error("Invalid session identifier, exiting...");
+                return;
+            }
+
+            EAP eapPayload;
+            Ethernet eth;
+            switch (radiusPacket.getCode()) {
+                case RADIUS.RADIUS_CODE_ACCESS_CHALLENGE:
+                    byte[] challengeState =
+                            radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_STATE).getValue();
+                    eapPayload = radiusPacket.decapsulateMessage();
+                    stateMachine.setChallengeInfo(eapPayload.getIdentifier(), challengeState);
+                    eth = buildEapolResponse(stateMachine.supplicantAddress(),
+                                             MacAddress.valueOf(nasMacAddress),
+                                             stateMachine.vlanId(),
+                                             EAPOL.EAPOL_PACKET,
+                                             eapPayload);
+                    sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+                    break;
+                case RADIUS.RADIUS_CODE_ACCESS_ACCEPT:
+                    //send an EAPOL - Success to the supplicant.
+                    byte[] eapMessage =
+                            radiusPacket.getAttribute(RADIUSAttribute.RADIUS_ATTR_EAP_MESSAGE).getValue();
+                    eapPayload = new EAP();
+                    eapPayload = (EAP) eapPayload.deserialize(eapMessage, 0, eapMessage.length);
+                    eth = buildEapolResponse(stateMachine.supplicantAddress(),
+                                             MacAddress.valueOf(nasMacAddress),
+                                             stateMachine.vlanId(),
+                                             EAPOL.EAPOL_PACKET,
+                                             eapPayload);
+                    sendPacketToSupplicant(eth, stateMachine.supplicantConnectpoint());
+
+                    stateMachine.authorizeAccess();
+                    break;
+                case RADIUS.RADIUS_CODE_ACCESS_REJECT:
+                    stateMachine.denyAccess();
+                    break;
+                default:
+                    log.warn("Unknown RADIUS message received with code: {}", radiusPacket.getCode());
+            }
+        }
+
+
+        @Override
+        public void run() {
+            boolean done = false;
+            int packetNumber = 1;
+
+            log.info("UDP listener thread starting up");
+            RADIUS inboundRadiusPacket;
+            while (!done) {
+                try {
+                    byte[] packetBuffer = new byte[RADIUS.RADIUS_MAX_LENGTH];
+                    DatagramPacket inboundBasePacket =
+                            new DatagramPacket(packetBuffer, packetBuffer.length);
+                    DatagramSocket socket = radiusSocket;
+                    socket.receive(inboundBasePacket);
+                    log.info("Packet #{} received", packetNumber++);
+                    try {
+                        inboundRadiusPacket =
+                                RADIUS.deserializer()
+                                        .deserialize(inboundBasePacket.getData(),
+                                                     0,
+                                                     inboundBasePacket.getLength());
+                        handleRadiusPacket(inboundRadiusPacket);
+                    } catch (DeserializationException dex) {
+                        log.error("Cannot deserialize packet", dex);
+                    } catch (StateMachineException sme) {
+                        log.error("Illegal state machine operation", sme);
+                    }
+
+                } catch (IOException e) {
+                    log.info("Socket was closed, exiting listener thread");
+                    done = true;
+                }
+            }
+        }
+    }
+
+    RadiusListener radiusListener = new RadiusListener();
+
+    private class InternalConfigListener implements NetworkConfigListener {
+
+        /**
+         * Reconfigures the DHCP Server according to the configuration parameters passed.
+         *
+         * @param cfg configuration object
+         */
+        private void reconfigureNetwork(AaaConfig cfg) {
+            AaaConfig newCfg;
+            if (cfg == null) {
+                newCfg = new AaaConfig();
+            } else {
+                newCfg = cfg;
+            }
+            if (newCfg.nasIp() != null) {
+                nasIpAddress = newCfg.nasIp();
+            }
+            if (newCfg.radiusIp() != null) {
+                radiusIpAddress = newCfg.radiusIp();
+            }
+            if (newCfg.radiusMac() != null) {
+                radiusMacAddress = newCfg.radiusMac();
+            }
+            if (newCfg.nasMac() != null) {
+                nasMacAddress = newCfg.nasMac();
+            }
+            if (newCfg.radiusSecret() != null) {
+                radiusSecret = newCfg.radiusSecret();
+            }
+            if (newCfg.radiusSwitch() != null) {
+                radiusSwitch = newCfg.radiusSwitch();
+            }
+            if (newCfg.radiusPort() != -1) {
+                radiusPort = newCfg.radiusPort();
+            }
+            if (newCfg.radiusServerUdpPort() != -1) {
+                radiusServerPort = newCfg.radiusServerUdpPort();
+            }
+        }
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+
+            if ((event.type() == NetworkConfigEvent.Type.CONFIG_ADDED ||
+                    event.type() == NetworkConfigEvent.Type.CONFIG_UPDATED) &&
+                    event.configClass().equals(AaaConfig.class)) {
+
+                AaaConfig cfg = netCfgService.getConfig(appId, AaaConfig.class);
+                reconfigureNetwork(cfg);
+                log.info("Reconfigured");
+            }
+        }
+    }
+
+
+}
