class RadiusRequestHandler implements Runnable {

    @Override
    public void run() {
        try {
            LOG.message("Entering RadiusRequestHandler.run();");
            final Packet requestPacket = getValidPacket(buffer);
            if (requestPacket == null) {
                LOG.message("Leaving RadiusRequestHandler.run(); no requestPacket");
                return;
            }

            // grab the items from the request that we'll need in the RadiusResponseHandler at send time
            requestContext.setRequestId(requestPacket.getIdentifier());
            requestContext.setRequestAuthenticator(requestPacket.getAuthenticator());

            final AccessRequest accessRequest = createAccessRequest(requestPacket);
            if (accessRequest == null) {
                LOG.message("Leaving RadiusRequestHandler.run(); Packet received was not an AccessRequest packet.");
                return;
            }

            // Instantiate an instance of the AccessRequestHandler class specified in the configuration for this
            // client.
            final AccessRequestHandler accessRequestHandler = accessRequestHandlerFactory
                    .getAccessRequestHandler(requestContext);
            if (accessRequestHandler == null) {
                LOG.message("Leaving RadiusRequestHandler.run(); Could not obtain Access Request Handler.");
                return;
            }

            final RadiusRequest request = new RadiusRequest(accessRequest);
            final RadiusResponse response = new RadiusResponse();

            try {
                // The handler will form the response.
                accessRequestHandler.handle(request, response, requestContext);
                postHandledEvent(request, response, requestContext);
                // Send the response to the client.
                Packet responsePacket = response.getResponsePacket();
                requestContext.send(responsePacket);
                eventBus.post(new PacketProcessedEvent());
            } catch (final RadiusProcessingException rre) {
                // So the processing of the request failed.
                handleResponseException(rre, requestContext);
            }

        } catch (final Exception t) {
            final StringBuilder sb = new StringBuilder(
                    "Exception occured while handling radius request for RADIUS client '").append(getClientName())
                    .append("'. Rejecting access.");
            LOG.error(sb.toString(), t);

            this.sendAccessReject(requestContext);
            return;
        }
    }

    public  RadiusRequestHandler(AccessRequestHandlerFactory accessRequestHandlerFactory,
            final RadiusRequestContext reqCtx, final ByteBuffer buffer,
            final EventBus eventBus);

}