class AuthenticationServiceV1 {

    @Post
    public Response authenticate(@Contextual Context context, @Contextual Request httpRequest) {

        if (!isSupportedMediaType(httpRequest)) {
            if (DEBUG.errorEnabled()) {
                DEBUG.error("AuthenticationService :: Unable to handle media type request : " + ContentTypeHeader.valueOf(httpRequest).getType());
            }
            return handleErrorResponse(httpRequest, Status.UNSUPPORTED_MEDIA_TYPE, null);
        }

        final HttpServletResponse response = getHttpServletResponse(context);

        Form urlQueryString = getUrlQueryString(httpRequest);
        final String sessionUpgradeSSOTokenId = urlQueryString.getFirst("sessionUpgradeSSOTokenId");

        try {

            // We check the session upgrade token first
            if (!StringUtils.isEmpty(sessionUpgradeSSOTokenId)) {
                // Return Bad Request if not a valid upgrade token
                SSOTokenManager.getInstance().createSSOToken(sessionUpgradeSSOTokenId);
            }
            JsonValue jsonContent;
            try {
                jsonContent = getJsonContent(httpRequest);
            } catch (IOException e) {
                DEBUG.message("AuthenticationService.authenticate() :: JSON parsing error", e);
                return handleErrorResponse(httpRequest, Status.BAD_REQUEST, e);
            }
            final HttpServletRequest request = getHttpServletRequest(context, jsonContent);
            JsonValue jsonResponse;

            if (jsonContent != null && jsonContent.size() > 0) {
                // submit requirements
                jsonResponse = restAuthenticationHandler.continueAuthentication(request, response, jsonContent,
                        sessionUpgradeSSOTokenId);
            } else {
                // initiate
                final String authIndexType = urlQueryString.getFirst("authIndexType");
                final String authIndexValue = urlQueryString.getFirst("authIndexValue");
                jsonResponse = restAuthenticationHandler.initiateAuthentication(request, response, authIndexType,
                        authIndexValue, sessionUpgradeSSOTokenId);
            }

            return createResponse(jsonResponse);

        } catch (RestAuthResponseException e) {
            DEBUG.message("AuthenticationService.authenticate() :: Exception from CallbackHandler", e);
            return handleErrorResponse(httpRequest, Status.valueOf(e.getStatusCode()), e);
        } catch (RestAuthException e) {
            DEBUG.message("AuthenticationService.authenticate() :: Rest Authentication Exception", e);
            return handleErrorResponse(httpRequest, Status.valueOf(e.getStatusCode()), e);
        } catch (SSOException e) {
            return handleErrorResponse(httpRequest, Status.BAD_REQUEST, e);
        } catch (IOException e) {
            DEBUG.error("AuthenticationService.authenticate() :: Internal Error", e);
            return handleErrorResponse(httpRequest, Status.INTERNAL_SERVER_ERROR, e);
        }
    }

    @Inject public  AuthenticationServiceV1(RestAuthenticationHandler restAuthenticationHandler);

}