package org.scribe.oauth;

import org.scribe.builder.api.DefaultApi20;
import org.scribe.model.*;

public class OAuth20ServiceImpl implements OAuthService
{
  private static final String VERSION = "2.0";

  private final DefaultApi20 api;
  private final OAuthConfig config;

  /**
   * Default constructor
   *
   * @param api OAuth2.0 api information
   * @param config OAuth 2.0 configuration param object
   */
  public OAuth20ServiceImpl(DefaultApi20 api, OAuthConfig config)
  {
    this.api = api;
    this.config = config;
  }

  /**
   * {@inheritDoc}
   */
  public Token getAccessToken(Token requestToken, Verifier verifier)
  {
    OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint());
    request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
    request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
    request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue());
    request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
    if (config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, config.getScope());
    if (config.hasGrantType()) request.addQuerystringParameter(OAuthConstants.GRANT_TYPE, config.getGrantType());
    Response response = request.send();
    return api.getAccessTokenExtractor().extract(response.getBody());
  }

  /**
   * {@inheritDoc}
   */
  public Token refreshAccessToken(Token accessToken)
  {

    String accessTokenEndpoint = api.getAccessTokenEndpoint();
    if (accessTokenEndpoint.contains("?grant_type="))
    {
      // handle the ugly case where the grant_type parameter is already hardcoded in the constant url
      accessTokenEndpoint = accessTokenEndpoint.substring(0, accessTokenEndpoint.indexOf("?"));
    }
    OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), accessTokenEndpoint);
    request.addQuerystringParameter(OAuthConstants.CLIENT_ID, config.getApiKey());
    request.addQuerystringParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());
    request.addQuerystringParameter(OAuthConstants.REDIRECT_URI, config.getCallback());
    request.addQuerystringParameter(OAuthConstants.GRANT_TYPE, api.getRefreshTokenParameterName());
    request.addQuerystringParameter(api.getRefreshTokenParameterName(), accessToken.getToken());
    Response response = request.send();
    return api.getAccessTokenExtractor().extract(response.getBody());
  }

  /**
   * {@inheritDoc}
   */
  public Token getRequestToken()
  {
    throw new UnsupportedOperationException("Unsupported operation, please use 'getAuthorizationUrl' and redirect your users there");
  }

  /**
   * {@inheritDoc}
   */
  public String getVersion()
  {
    return VERSION;
  }

  /**
   * {@inheritDoc}
   */
  public void signRequest(Token accessToken, OAuthRequest request)
  {
    request.addQuerystringParameter(OAuthConstants.ACCESS_TOKEN, accessToken.getToken());
  }

  /**
   * {@inheritDoc}
   */
  public String getAuthorizationUrl(Token requestToken)
  {
    return api.getAuthorizationUrl(config);
  }

}

@@ -90,16 +90,46 @@
 model.*;
+%0Aimport org.scribe.model.Verb;
 %0A%0Apublic
@@ -760,24 +760,655 @@
 ndpoint());%0A
+%0A      if (api.getAccessTokenVerb().equals(Verb.POST))%0A      %7B%0A        request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());%0A        request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());%0A        request.addBodyParameter(OAuthConstants.CODE, verifier.getValue());%0A        request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback());%0A        if (config.hasScope()) request.addBodyParameter(OAuthConstants.SCOPE, config.getScope());%0A        if (config.hasGrantType()) request.addBodyParameter(OAuthConstants.GRANT_TYPE, config.getGrantType());%0A      %7D%0A      else%0A      %7B%0A    
     request.
@@ -1470,32 +1470,36 @@
 g.getApiKey());%0A
+    
     request.addQ
@@ -1568,32 +1568,36 @@
 iSecret());%0A    
+  
+  
 request.addQuery
@@ -1651,24 +1651,28 @@
 etValue());%0A
+    
     request.
@@ -1743,32 +1743,36 @@
 allback());%0A    
+ 
+   
 if (config.hasSc
@@ -1848,24 +1848,28 @@
 etScope());%0A
+    
     if (conf
@@ -1966,24 +1966,32 @@
 antType());%0A
+      %7D%0A
     Response
@@ -2601,16 +2601,536 @@
 point);%0A
+    if (api.getAccessTokenVerb().equals(Verb.POST))%0A    %7B%0A       request.addBodyParameter(OAuthConstants.CLIENT_ID, config.getApiKey());%0A       request.addBodyParameter(OAuthConstants.CLIENT_SECRET, config.getApiSecret());%0A       request.addBodyParameter(OAuthConstants.REDIRECT_URI, config.getCallback());%0A       request.addBodyParameter(OAuthConstants.GRANT_TYPE, api.getRefreshTokenParameterName());%0A       request.addBodyParameter(api.getRefreshTokenParameterName(), accessToken.getToken());%0A    %7D%0A    else%0A    %7B%0A   
     requ
@@ -3200,32 +3200,35 @@
 tApiKey());%0A    
+ 
+  
 request.addQuery
@@ -3293,24 +3293,27 @@
 iSecret());%0A
+   
     request.
@@ -3384,32 +3384,35 @@
 allback());%0A    
+   
 request.addQuery
@@ -3491,24 +3491,27 @@
 ame());%0A    
+ 
+  
 request.addQ
@@ -3587,24 +3587,31 @@
 etToken());%0A
+    %7D%0A%0A
     Response

Patch getAccessToken method: when token verb is GET put params on query and when token is POST put param on body