/** {@inheritDoc} */
  @Override
  public void setup(OAuth2Settings settings) throws OAuth2SettingsException {
    /* validate supplied settings */
    if (settings == null) {
      throw new OAuth2SettingsException("Missing settings.");
    }
    if (Utils.isNullOrEmpty(settings.getTokenUri())) {
      throw new OAuth2SettingsException("Token server URI missing.");
    } else {
      tokenServer = settings.getTokenUri();
    }
    if (Utils.isNullOrEmpty(settings.getRefreshToken())) {
      throw new OAuth2SettingsException("Refresh token cannot be null or empty.");
    }
    if (Utils.isNullOrEmpty(settings.getClientId())) {
      throw new OAuth2SettingsException("Client ID cannot be null or empty.");
    }
    if (settings.getClientSecret() != null) {
      tokenParams.put("client_secret", settings.getClientSecret());
    }
    if (!Utils.isNullOrEmpty(settings.getScope())) {
      tokenParams.put("scope", settings.getScope());
    }

    /* populate token request params */
    tokenParams.put("client_id", settings.getClientId());
    tokenParams.put("grant_type", "refresh_token");
    tokenParams.put("refresh_token", settings.getRefreshToken());
    for (Entry<String, String> entry : settings.getExtraTokenParams().entrySet()) {
      if (!tokenParams.containsKey(entry.getKey())) {
        tokenParams.put(entry.getKey(), entry.getValue());
      }
    }
  }
  /** {@inheritDoc} */
  @Override
  public void setup(OAuth2Settings settings) throws OAuth2SettingsException {
    /* validate supplied settings */
    if (settings == null) {
      throw new OAuth2SettingsException("Missing settings.");
    }
    if (Utils.isNullOrEmpty(settings.getTokenUri())) {
      throw new OAuth2SettingsException("Token server URI missing.");
    } else {
      tokenServer = settings.getTokenUri();
    }
    if (Utils.isNullOrEmpty(settings.getUsername())) {
      throw new OAuth2SettingsException("Username cannot be null or empty.");
    }
    if (Utils.isNullOrEmpty(settings.getPassword())) {
      throw new OAuth2SettingsException("Password cannot be null or empty.");
    }

    /* populate token request params */
    tokenParams.put("username", settings.getUsername());
    tokenParams.put("password", settings.getPassword());
    tokenParams.put("response_type", "password");
    for (Entry<String, String> entry : settings.getExtraAuthorizeParams().entrySet()) {
      if (!tokenParams.containsKey(entry.getKey())) {
        tokenParams.put(entry.getKey(), entry.getValue());
      }
    }
  }
 /** Sends a POST request to obtain an access token. */
 private void obtainAccessToken() {
   try {
     token = new OAuth2Token();
     error = new OAuth2Error();
     /* build the request and send it to the token server */
     CloseableHttpClient client = HttpClients.createDefault();
     HttpPost request = new HttpPost(tokenServer);
     request.setEntity(new UrlEncodedFormEntity(Utils.mapToList(tokenParams)));
     CloseableHttpResponse response = client.execute(request);
     HttpEntity entity = response.getEntity();
     /* get the response and parse it */
     JsonParser jp = json.getFactory().createParser(entity.getContent());
     while (jp.nextToken() != null) {
       JsonToken jsonToken = jp.getCurrentToken();
       switch (jsonToken) {
         case FIELD_NAME:
           String name = jp.getCurrentName();
           jsonToken = jp.nextToken();
           if (name.equals("access_token")) {
             token.setAccessToken(jp.getValueAsString());
           } else if (name.equals("token_type")) {
             token.setType(OAuth2TokenType.valueOf(jp.getValueAsString().toUpperCase()));
           } else if (name.equals("expires_in")) {
             token.setExpiresIn(jp.getValueAsInt());
           } else if (name.equals("refresh_token")) {
             token.setRefreshToken(jp.getValueAsString());
           } else if (name.equals("kid")) {
             token.setKeyId(jp.getValueAsString());
           } else if (name.equals("mac_key")) {
             token.setMacKey(jp.getValueAsString());
           } else if (name.equals("mac_algorithm")) {
             token.setMacAlgorithm(jp.getValueAsString());
           } else if (name.equals("error")) {
             error.setType(OAuth2ErrorType.valueOf(jp.getValueAsString().toUpperCase()));
           } else if (name.equals("error_description")) {
             error.setDescription(jp.getValueAsString());
           } else if (name.equals("error_uri")) {
             error.setUri(jp.getValueAsString());
           }
           ready = true;
           break;
         default:
           break;
       }
     }
     jp.close();
     response.close();
     client.close();
   } catch (IOException e) {
     error.setType(OAuth2ErrorType.SERVER_ERROR);
     error.setDescription("Failed to obtain access token from the server.");
   }
   /* notify all waiting objects */
   synchronized (waitObject) {
     ready = true;
     waitObject.notifyAll();
   }
 }