class DeviceCodeResource extends ServerResource {

    @Post
    public Representation issueCode(Representation body) throws OAuth2RestletException {
        final Request restletRequest = getRequest();
        OAuth2Request request = requestFactory.create(restletRequest);

        String state = request.getParameter(STATE);
        // Client ID, Response Type and Scope are required, all other parameters are optional
        String clientId = request.getParameter(CLIENT_ID);
        String scope = request.getParameter(SCOPE);
        String responseType = request.getParameter(RESPONSE_TYPE);
        try {
            if (isEmpty(clientId) || isEmpty(scope) || isEmpty(responseType)) {
                throw new OAuth2RestletException(400, "bad_request",
                        "client_id, scope and response_type are required parameters", state);
            } else {
                // check client_id exists
                clientRegistrationStore.get(clientId, request);
            }

            if (scope == null) {
                scope = "";
            }
            final String maxAge = request.getParameter(MAX_AGE);
            DeviceCode code = tokenStore.createDeviceCode(
                    oAuth2Utils.split(scope, " "),
                    null,
                    clientId,
                    request.<String>getParameter(NONCE),
                    request.<String>getParameter(RESPONSE_TYPE),
                    request.<String>getParameter(STATE),
                    request.<String>getParameter(ACR_VALUES),
                    request.<String>getParameter(PROMPT),
                    request.<String>getParameter(UI_LOCALES),
                    request.<String>getParameter(LOGIN_HINT),
                    maxAge == null ? null : Integer.valueOf(maxAge),
                    request.<String>getParameter(CLAIMS),
                    request,
                    request.<String>getParameter(CODE_CHALLENGE),
                    request.<String>getParameter(CODE_CHALLENGE_METHOD));

            Map<String, Object> result = new HashMap<>();
            OAuth2ProviderSettings providerSettings = providerSettingsFactory.get(request);

            result.put(DEVICE_CODE, code.getDeviceCode());
            result.put(USER_CODE, code.getUserCode());
            result.put(EXPIRES_IN, providerSettings.getDeviceCodeLifetime());
            result.put(INTERVAL, providerSettings.getDeviceCodePollInterval());

            String verificationUrl = providerSettings.getVerificationUrl();
            if (StringUtils.isBlank(verificationUrl)) {
                final HttpServletRequest servletRequest = ServletUtils.getRequest(restletRequest);
                final String realm = request.getParameter(OAuth2Constants.Custom.REALM);
                verificationUrl = baseURLProviderFactory.get(realm).getRootURL(servletRequest) + "/oauth2/device/user";
            }
            result.put(VERIFICATION_URL, verificationUrl);

            return jacksonRepresentationFactory.create(result);
        } catch (OAuth2Exception e) {
            throw new OAuth2RestletException(e.getStatusCode(), e.getError(), e.getMessage(), state);
        }
    }

    @Inject public  DeviceCodeResource(TokenStore tokenStore, OAuth2RequestFactory<?, Request> requestFactory,
            ClientRegistrationStore clientRegistrationStore, OAuth2ProviderSettingsFactory providerSettingsFactory,
            BaseURLProviderFactory baseURLProviderFactory, ExceptionHandler exceptionHandler,
            JacksonRepresentationFactory jacksonRepresentationFactory, OAuth2Utils oAuth2Utils);

}