private Request createChallengeResponse(Response resourceNeedsAuth) {
    ChallengeResponse cResponse = null;

    for (ChallengeRequest challengeRequest : resourceNeedsAuth.getChallengeRequests()) {
      ChallengeScheme cs = challengeRequest.getScheme();

      if (ChallengeScheme.HTTP_BASIC.equals(cs)) {
        if (log.isLoggable(Level.INFO)) {
          log.info("Received 401 Error -> retrying request with HTTP_BASIC AUTH now!");
        }
        cResponse = new ChallengeResponse(ChallengeScheme.HTTP_BASIC, getUsername(), getPassword());
        break;
      }
    }

    if (cResponse != null) {
      Request authenticatedRequest = resourceNeedsAuth.getRequest();
      authenticatedRequest.setChallengeResponse(cResponse);
      return authenticatedRequest;
    }

    throw new IllegalStateException(
        new AuthenticationException("Unable to determine required authentication scheme!"));
  }
  /**
   * Handles the {@link Post} request.
   *
   * @param input HTML form formated token request per oauth-v2 spec.
   * @return JSON response with token or error.
   */
  @Post("form:json")
  public Representation represent(Representation input) {
    getLogger().fine("Method = " + getMethod().getName());
    getLogger().fine("In request : " + getOriginalRef().toString());

    Form params = new Form(input);
    String typeString = params.getFirstValue(GRANT_TYPE);
    getLogger().fine("Token Service - In service type = " + typeString);

    String clientId = params.getFirstValue(CLIENT_ID);
    String clientSecret = params.getFirstValue(CLIENT_SECRET);

    if ((clientSecret == null) || (clientSecret.length() == 0)) {
      // Check for a basic HTTP auth
      ChallengeResponse cr = getChallengeResponse();

      if (ChallengeScheme.HTTP_BASIC.equals(cr.getScheme())) {
        String basic = new String(Base64.decode(cr.getRawValue()));
        int colon = basic.indexOf(':');

        if (colon > -1) {
          clientSecret = basic.substring(colon + 1);
          getLogger().fine("Found secret in BASIC Authentication : " + clientSecret);

          // Also allow for client ID to be transfered in user part
          if (colon > 0) { // There is a user part
            clientId = basic.substring(0, colon);
            getLogger().fine("Found id in BASIC Authentication : " + clientId);
          }
        }
      }
    }

    Representation toRet = null;
    if ((clientId == null) || (clientId.length() == 0)) {
      setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
      return sendError(
          OAuthError.invalid_request, "Mandatory parameter client_id is missing", null);

      // return new EmptyRepresentation();
    }

    if ((clientSecret == null) || (clientSecret.length() == 0)) {
      setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
      return sendError(
          OAuthError.invalid_request, "Mandatory parameter client_secret is missing", null);
      // return new EmptyRepresentation();
    }

    try {
      GrantType type = Enum.valueOf(GrantType.class, typeString);
      getLogger().fine("Found flow - " + type);

      try {
        switch (type) {
          case authorization_code:
            toRet = doAuthCodeFlow(clientId, clientSecret, params);
            break;
          case password:
            toRet = doPasswordFlow(clientId, clientSecret, params);
            break;
          case assertion:
            sendError(OAuthError.unsupported_grant_type, "Assertion flow not supported", null);
            setStatus(Status.SERVER_ERROR_NOT_IMPLEMENTED);
            break;
          case refresh_token:
            toRet = doRefreshFlow(clientId, clientSecret, params);
            break;
          case none:
            toRet = doNoneFlow(clientId, clientSecret, params);
            break;
          default:
            toRet = sendError(OAuthError.unsupported_grant_type, "Flow not supported", null);
            setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
        }
      } catch (IllegalArgumentException e) { // can not exchange code.
        toRet = sendError(OAuthError.invalid_grant, e.getMessage(), null);
        setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
      }
    } catch (IllegalArgumentException iae) {
      toRet = sendError(OAuthError.unsupported_grant_type, "Flow not supported", null);
      setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
    } catch (NullPointerException npe) {
      toRet = sendError(OAuthError.unsupported_grant_type, "Flow not supported", null);
      setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
    }
    return toRet;
  }