@GET
  @Path("token")
  public Response getAccessToken(
      @Context UriInfo ui,
      @HeaderParam("Authorization") String authorization,
      @QueryParam("grant_type") String grant_type,
      @QueryParam("username") String username,
      @QueryParam("password") String password,
      @QueryParam("pin") String pin,
      @QueryParam("client_id") String client_id,
      @QueryParam("client_secret") String client_secret,
      @QueryParam("code") String code,
      @QueryParam("ttl") long ttl,
      @QueryParam("redirect_uri") String redirect_uri,
      @QueryParam("callback") @DefaultValue("") String callback)
      throws Exception {

    logger.debug("ApplicationResource.getAccessToken");

    User user = null;

    try {

      if (authorization != null) {
        String type = stringOrSubstringBeforeFirst(authorization, ' ').toUpperCase();
        if ("BASIC".equals(type)) {
          String token = stringOrSubstringAfterFirst(authorization, ' ');
          String[] values = Base64.decodeToString(token).split(":");
          if (values.length >= 2) {
            client_id = values[0].toLowerCase();
            client_secret = values[1];
          }
        }
      }

      // do checking for different grant types
      String errorDescription = "invalid username or password";
      if (GrantType.PASSWORD.toString().equals(grant_type)) {
        try {
          user =
              management.verifyAppUserPasswordCredentials(
                  services.getApplicationId(), username, password);
        } catch (UnactivatedAppUserException uaue) {
          errorDescription = "user not activated";
        } catch (DisabledAppUserException daue) {
          errorDescription = "user disabled";
        } catch (Exception e1) {
        }
      } else if ("pin".equals(grant_type)) {
        try {
          user = management.verifyAppUserPinCredentials(services.getApplicationId(), username, pin);
        } catch (Exception e1) {
        }
      } else if ("client_credentials".equals(grant_type)) {
        try {
          AccessInfo access_info = management.authorizeClient(client_id, client_secret, ttl);
          if (access_info != null) {
            return Response.status(SC_OK)
                .type(jsonMediaType(callback))
                .entity(wrapWithCallback(access_info, callback))
                .build();
          }
        } catch (Exception e1) {
        }
      } else if ("authorization_code".equals(grant_type)) {
        AccessInfo access_info = new AccessInfo();
        access_info.setAccessToken(code);
        return Response.status(SC_OK)
            .type(jsonMediaType(callback))
            .entity(wrapWithCallback(access_info, callback))
            .build();
      }

      if (user == null) {
        OAuthResponse response =
            OAuthResponse.errorResponse(SC_BAD_REQUEST)
                .setError(OAuthError.TokenResponse.INVALID_GRANT)
                .setErrorDescription(errorDescription)
                .buildJSONMessage();
        return Response.status(response.getResponseStatus())
            .type(jsonMediaType(callback))
            .entity(wrapWithCallback(response.getBody(), callback))
            .build();
      }

      String token =
          management.getAccessTokenForAppUser(services.getApplicationId(), user.getUuid(), ttl);

      AccessInfo access_info =
          new AccessInfo()
              .withExpiresIn(tokens.getMaxTokenAge(token) / 1000)
              .withAccessToken(token)
              .withProperty("user", user);

      return Response.status(SC_OK)
          .type(jsonMediaType(callback))
          .entity(wrapWithCallback(access_info, callback))
          .build();

    } catch (OAuthProblemException e) {
      logger.error("OAuth Error", e);
      OAuthResponse res = OAuthResponse.errorResponse(SC_BAD_REQUEST).error(e).buildJSONMessage();
      return Response.status(res.getResponseStatus())
          .type(jsonMediaType(callback))
          .entity(wrapWithCallback(res.getBody(), callback))
          .build();
    }
  }