@Override
  protected void refreshToken(final DefaultHttpClient client) throws OAuth2Exception {
    final String refreshToken = accessToken.getRefreshToken();
    if (refreshToken == null) {
      throw new OAuth2Exception("No OAuth2 refresh token");
    }

    // refresh the token
    try {
      accessToken =
          OAuthClientUtils.getAccessToken(
              getAccessTokenService(), OAUTH2_CONSUMER, new RefreshTokenGrant(refreshToken));
    } catch (OAuthServiceException e) {
      throw new OAuth2Exception(e);
    }
  }
  @Override
  protected void init() throws OAuth2Exception {
    final URI authURI =
        OAuthClientUtils.getAuthorizationURI(
            oauth2GrantServiceURI.toASCIIString(),
            OAuth2Provider.CLIENT_ID,
            OAuth2Provider.REDIRECT_URI,
            null,
            null);

    // Disable automatic redirects handling
    final HttpParams params = new BasicHttpParams();
    params.setParameter(ClientPNames.HANDLE_REDIRECTS, false);
    final DefaultHttpClient httpClient = new DefaultHttpClient(params);

    JsonNode oAuthAuthorizationData = null;
    String authenticityCookie = null;
    try {
      // 1. Need to (basic) authenticate against the OAuth2 service
      final HttpGet method = new HttpGet(authURI);
      method.addHeader(
          "Authorization",
          "Basic " + Base64.encodeBase64String("odatajclient:odatajclient".getBytes()));
      final HttpResponse response = httpClient.execute(method);

      // 2. Pull out OAuth2 authorization data and "authenticity" cookie (CXF specific)
      oAuthAuthorizationData = new XmlMapper().readTree(EntityUtils.toString(response.getEntity()));

      final Header setCookieHeader = response.getFirstHeader("Set-Cookie");
      if (setCookieHeader == null) {
        throw new IllegalStateException("OAuth flow is broken");
      }
      authenticityCookie = setCookieHeader.getValue();
    } catch (Exception e) {
      throw new OAuth2Exception(e);
    }

    String code = null;
    try {
      // 3. Submit the HTTP form for allowing access to the application
      final URI location =
          new URIBuilder(oAuthAuthorizationData.get("replyTo").asText())
              .addParameter(
                  "session_authenticity_token",
                  oAuthAuthorizationData.get("authenticityToken").asText())
              .addParameter("client_id", oAuthAuthorizationData.get("clientId").asText())
              .addParameter("redirect_uri", oAuthAuthorizationData.get("redirectUri").asText())
              .addParameter("oauthDecision", "allow")
              .build();
      final HttpGet method = new HttpGet(location);
      method.addHeader(
          "Authorization",
          "Basic " + Base64.encodeBase64String("odatajclient:odatajclient".getBytes()));
      method.addHeader("Cookie", authenticityCookie);

      final HttpResponse response = httpClient.execute(method);

      final Header locationHeader = response.getFirstHeader("Location");
      if (response.getStatusLine().getStatusCode() != 303 || locationHeader == null) {
        throw new IllegalStateException("OAuth flow is broken");
      }

      // 4. Get the authorization code value out of this last redirect
      code = StringUtils.substringAfterLast(locationHeader.getValue(), "=");

      EntityUtils.consumeQuietly(response.getEntity());
    } catch (Exception e) {
      throw new OAuth2Exception(e);
    }

    // 5. Obtain the access token
    try {
      accessToken =
          OAuthClientUtils.getAccessToken(
              getAccessTokenService(), OAUTH2_CONSUMER, new AuthorizationCodeGrant(code));
    } catch (OAuthServiceException e) {
      throw new OAuth2Exception(e);
    }

    if (accessToken == null) {
      throw new OAuth2Exception("No OAuth2 access token");
    }
  }