/**
   * Invokes Microsoft Azure Mobile Service authentication using a provider-specific oAuth token
   *
   * @param provider The provider used for the authentication process
   * @param oAuthToken The oAuth token used for authentication
   * @param callback Callback to invoke when the authentication process finishes
   */
  public void authenticate(
      String provider, String oAuthToken, final UserAuthenticationCallback callback) {
    if (oAuthToken == null || oAuthToken.trim() == "") {
      throw new IllegalArgumentException("oAuthToken can not be null or empty");
    }

    // Create the login URL
    String url =
        mClient.getAppUrl().toString() + LoginManager.START_URL + normalizeProvider(provider);

    authenticateWithToken(oAuthToken, url, callback);
  }
  /**
   * Invokes Microsoft Azure Mobile Services authentication using the specified token
   *
   * @param token The token used for authentication
   * @param url The URL used for the authentication process
   * @param callback Callback to invoke when the authentication process finishes
   */
  private void authenticateWithToken(
      String token, String url, final UserAuthenticationCallback callback) {
    if (token == null) {
      throw new IllegalArgumentException("token can not be null");
    }

    if (url == null) {
      throw new IllegalArgumentException("url can not be null");
    }

    // Create a request
    final ServiceFilterRequest request =
        new ServiceFilterRequestImpl(new HttpPost(url), mClient.getAndroidHttpClientFactory());
    request.addHeader(HTTP.CONTENT_TYPE, MobileServiceConnection.JSON_CONTENTTYPE);

    try {
      // Set request's content with the token
      request.setContent(token);
    } catch (Exception e) {
      // this should never happen
    }
    final MobileServiceConnection connection = mClient.createConnection();

    // Create the AsyncTask that will execute the request
    new RequestAsyncTask(request, connection) {
      @Override
      protected void onPostExecute(ServiceFilterResponse response) {
        if (callback != null) {

          if (mTaskException == null && response != null) {
            MobileServiceUser user = null;
            try {
              // Get the user from the response and create a
              // MobileServiceUser object from the JSON
              String content = response.getContent();
              user = createUserFromJSON((JsonObject) new JsonParser().parse((content.trim())));

            } catch (Exception e) {
              // Something went wrong, call onCompleted method
              // with exception
              callback.onCompleted(
                  null,
                  new MobileServiceException("Error while authenticating user.", e),
                  response);
              return;
            }

            // Call onCompleted method
            callback.onCompleted(user, null, response);
          } else {
            // Something went wrong, call onCompleted method with
            // exception
            callback.onCompleted(
                null,
                new MobileServiceException("Error while authenticating user.", mTaskException),
                response);
          }
        }
      }
    }.executeTask();
  }
  /**
   * Invokes an interactive authentication process using the specified Authentication Provider
   *
   * @param provider The provider used for the authentication process
   * @param context The context used to create the authentication dialog
   * @param callback Callback to invoke when the authentication process finishes
   */
  public void authenticate(
      String provider, Context context, final UserAuthenticationCallback callback) {
    if (context == null) {
      throw new IllegalArgumentException("context cannot be null");
    }

    if (provider == null || provider.length() == 0) {
      throw new IllegalArgumentException("provider cannot be null or empty");
    }

    // Create login URL
    String startUrl =
        mClient.getAppUrl().toString() + LoginManager.START_URL + normalizeProvider(provider);
    // Create the expected end URL
    String endUrl = mClient.getAppUrl().toString() + LoginManager.END_URL;

    final UserAuthenticationCallback externalCallback = callback;

    // Shows an interactive view with the provider's login
    showLoginUI(
        startUrl,
        endUrl,
        context,
        new LoginUIOperationCallback() {

          @Override
          public void onCompleted(String url, Exception exception) {
            if (externalCallback != null) {
              if (exception == null) {
                MobileServiceUser user = null;
                try {
                  String decodedUrl = URLDecoder.decode(url, MobileServiceClient.UTF8_ENCODING);

                  JsonObject json =
                      (JsonObject)
                          new JsonParser()
                              .parse(
                                  decodedUrl.substring(
                                      decodedUrl.indexOf(TOKEN_MARK) + TOKEN_MARK.length()));

                  user = createUserFromJSON(json);
                } catch (Exception e) {
                  // If exists an external callback, call
                  // onComplete method
                  // method with exception
                  if (externalCallback != null) {
                    externalCallback.onCompleted(null, e, null);
                  }
                  return;
                }

                // If exists an external callback, call
                // onComplete method
                if (externalCallback != null) {
                  externalCallback.onCompleted(user, null, null);
                }
              } else {
                externalCallback.onCompleted(null, exception, null);
              }
            }
          }
        });
  }