private AuthenticationAPIClient(Auth0 auth0, OkHttpClient client, Gson gson) {
   this.auth0 = auth0;
   this.client = client;
   this.gson = gson;
   this.factory = new RequestFactory();
   final Telemetry telemetry = auth0.getTelemetry();
   if (telemetry != null) {
     factory.setClientInfo(telemetry.getValue());
   }
 }
  private <T> ParameterizableRequest<T> delegation(Class<T> clazz) {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl()).newBuilder().addPathSegment(DELEGATION_PATH).build();

    final Map<String, Object> parameters =
        ParameterBuilder.newBuilder()
            .setClientId(getClientId())
            .setGrantType(ParameterBuilder.GRANT_TYPE_JWT)
            .asDictionary();

    return factory.POST(url, client, gson, clazz).addParameters(parameters);
  }
  /**
   * Performs a custom <a href="https://auth0.com/docs/auth-api#!#post--delegation">delegation</a>
   * request that will yield a delegation token. Example usage:
   *
   * <pre><code>
   * client.delegation()
   *      .addParameter("api_type", "firebase")
   *      .start(new BaseCallback<Map<String, Object>>() {
   *          {@literal}Override
   *          public void onSuccess(Map<String, Object> payload) {}
   *
   *          {@literal}Override
   *          public void onFailure(Auth0Exception error) {}
   *      });
   * </code></pre>
   *
   * @return a request to configure and start
   */
  @SuppressWarnings("WeakerAccess")
  public ParameterizableRequest<Map<String, Object>> delegation() {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl()).newBuilder().addPathSegment(DELEGATION_PATH).build();

    final Map<String, Object> parameters =
        ParameterBuilder.newBuilder()
            .setClientId(getClientId())
            .setGrantType(ParameterBuilder.GRANT_TYPE_JWT)
            .asDictionary();
    return factory.rawPOST(url, client, gson).addParameters(parameters);
  }
  /**
   * Start a custom passwordless flow
   *
   * @return a request to configure and start
   */
  @SuppressWarnings("WeakerAccess")
  public ParameterizableRequest<Void> passwordless() {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl())
            .newBuilder()
            .addPathSegment(PASSWORDLESS_PATH)
            .addPathSegment(START_PATH)
            .build();

    final Map<String, Object> parameters =
        ParameterBuilder.newBuilder().setClientId(getClientId()).asDictionary();
    return factory.POST(url, client, gson).addParameters(parameters);
  }
  /**
   * Unlink a user identity calling <a
   * href="https://auth0.com/docs/auth-api#!#post--unlink">'/unlink'</a> endpoint Example usage:
   *
   * <pre><code>
   * client.unlink("{auth0 user id}", "{user access token}")
   *      .start(new BaseCallback<Void>() {
   *          {@literal}Override
   *          public void onSuccess(Void payload) {}
   *
   *          {@literal}Override
   *          public void onFailure(Auth0Exception error) {}
   *      });
   * </code></pre>
   *
   * @param userId of the identity to unlink
   * @param accessToken of the main identity obtained after login
   * @return a request to start
   */
  @SuppressWarnings("WeakerAccess")
  public Request<Void> unlink(String userId, String accessToken) {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl()).newBuilder().addPathSegment(UNLINK_PATH).build();

    final Map<String, Object> parameters =
        ParameterBuilder.newBuilder()
            .setAccessToken(accessToken)
            .set(CLIENT_ID_KEY, getClientId())
            .set(USER_ID_KEY, userId)
            .asDictionary();

    return factory.POST(url, client, gson).addParameters(parameters);
  }
  private AuthenticationRequest loginWithResourceOwner(Map<String, Object> parameters) {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl())
            .newBuilder()
            .addPathSegment(OAUTH_PATH)
            .addPathSegment(RESOURCE_OWNER_PATH)
            .build();

    final Map<String, Object> requestParameters =
        ParameterBuilder.newBuilder()
            .setClientId(getClientId())
            .setConnection(defaultDatabaseConnection)
            .addAll(parameters)
            .asDictionary();
    return factory
        .authenticationPOST(url, client, gson)
        .addAuthenticationParameters(requestParameters);
  }
  /**
   * Log in a user with a OAuth 'access_token' of a Identity Provider like Facebook or Twitter using
   * <a href="https://auth0.com/docs/auth-api#!#post--oauth-access_token">'\oauth\access_token'
   * endpoint</a> Example usage:
   *
   * <pre><code>
   * client.loginWithOAuthAccessToken("{token}", "{connection name}")
   *      .setConnection("second-database")
   *      .start(new BaseCallback<Credentials>() {
   *          {@literal}Override
   *          public void onSuccess(Credentials payload) { }
   *
   *          {@literal}Override
   *          public void onFailure(Auth0Exception error) { }
   *      });
   * </code></pre>
   *
   * @param token obtained from the IdP
   * @param connection that will be used to authenticate the user, e.g. 'facebook'
   * @return a request to configure and start that will yield {@link Credentials}
   */
  @SuppressWarnings("WeakerAccess")
  public AuthenticationRequest loginWithOAuthAccessToken(String token, String connection) {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl())
            .newBuilder()
            .addPathSegment(OAUTH_PATH)
            .addPathSegment(ACCESS_TOKEN_PATH)
            .build();

    Map<String, Object> parameters =
        ParameterBuilder.newAuthenticationBuilder()
            .setClientId(getClientId())
            .setConnection(connection)
            .setAccessToken(token)
            .asDictionary();

    return factory.authenticationPOST(url, client, gson).addAuthenticationParameters(parameters);
  }
  /**
   * Request a change password using <a
   * href="https://auth0.com/docs/auth-api#!#post--dbconnections-change_password">'/dbconnections/change_password'</a>
   * Example usage:
   *
   * <pre><code>
   * client.requestChangePassword("{email}")
   *      .start(new BaseCallback<Void>() {
   *          {@literal}Override
   *          public void onSuccess(Void payload) {}
   *
   *          {@literal}Override
   *          public void onFailure(Auth0Exception error) {}
   *      });
   * </code></pre>
   *
   * @param email of the user that changes the password. It's also where the email will be sent with
   *     the link to perform the change password.
   * @return a request to configure and start
   */
  @SuppressWarnings("WeakerAccess")
  public DatabaseConnectionRequest<Void> requestChangePassword(String email) {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl())
            .newBuilder()
            .addPathSegment(DB_CONNECTIONS_PATH)
            .addPathSegment(CHANGE_PASSWORD_PATH)
            .build();

    final Map<String, Object> parameters =
        ParameterBuilder.newBuilder()
            .set(EMAIL_KEY, email)
            .setClientId(getClientId())
            .setConnection(defaultDatabaseConnection)
            .asDictionary();
    final ParameterizableRequest<Void> request =
        factory.POST(url, client, gson).addParameters(parameters);
    return new DatabaseConnectionRequest<>(request);
  }
  /**
   * Fetch the token information from Auth0, using the authorization_code grant type
   *
   * <p>For Public Client, e.g. Android apps ,you need to provide the code_verifier used to generate
   * the challenge sent to Auth0 {@literal /authorize} method like:
   *
   * <pre>{@code
   * AuthenticationAPIClient client = new AuthenticationAPIClient(new Auth0("clientId", "domain"));
   * client
   *     .token("code", "redirect_uri")
   *     .setCodeVerifier("code_verifier")
   *     .start(new Callback<Credentials> {...});
   * }</pre>
   *
   * For the rest of clients, clients who can safely keep a {@literal client_secret}, you need to
   * provide it instead like:
   *
   * <pre>{@code
   * AuthenticationAPIClient client = new AuthenticationAPIClient(new Auth0("clientId", "domain"));
   * client
   *     .token("code", "redirect_uri")
   *     .setClientSecret("client_secret")
   *     .start(new Callback<Credentials> {...});
   * }</pre>
   *
   * @param authorizationCode the authorization code received from the /authorize call.
   * @param redirectUri the uri sent to /authorize as the 'redirect_uri'.
   * @return a request to obtain access_token by exchanging a authorization code.
   */
  @SuppressWarnings("WeakerAccess")
  public TokenRequest token(String authorizationCode, String redirectUri) {
    Map<String, Object> parameters =
        ParameterBuilder.newBuilder()
            .setClientId(getClientId())
            .setGrantType(GRANT_TYPE_AUTHORIZATION_CODE)
            .set(OAUTH_CODE_KEY, authorizationCode)
            .set(REDIRECT_URI_KEY, redirectUri)
            .asDictionary();

    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl())
            .newBuilder()
            .addPathSegment(OAUTH_PATH)
            .addPathSegment(TOKEN_PATH)
            .build();

    ParameterizableRequest<Credentials> request =
        factory.POST(url, client, gson, Credentials.class).addParameters(parameters);
    return new TokenRequest(request);
  }
  /**
   * Creates a user in a DB connection using <a
   * href="https://auth0.com/docs/auth-api#!#post--dbconnections-signup">'/dbconnections/signup'
   * endpoint</a> Example usage:
   *
   * <pre><code>
   * client.createUser("{email}", "{password}", "{username}")
   *      .setConnection("{connection name}")
   *      .start(new BaseCallback<DatabaseUser>() {
   *          {@literal}Override
   *          public void onSuccess(DatabaseUser payload) { }
   *
   *          {@literal}@Override
   *          public void onFailure(Auth0Exception error) { }
   *      });
   * </code></pre>
   *
   * @param email of the user and must be non null
   * @param password of the user and must be non null
   * @param username of the user and must be non null
   * @return a request to start
   */
  @SuppressWarnings("WeakerAccess")
  public DatabaseConnectionRequest<DatabaseUser> createUser(
      String email, String password, String username) {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl())
            .newBuilder()
            .addPathSegment(DB_CONNECTIONS_PATH)
            .addPathSegment(SIGN_UP_PATH)
            .build();

    final Map<String, Object> parameters =
        ParameterBuilder.newBuilder()
            .set(USERNAME_KEY, username)
            .set(EMAIL_KEY, email)
            .set(PASSWORD_KEY, password)
            .setConnection(defaultDatabaseConnection)
            .setClientId(getClientId())
            .asDictionary();
    final ParameterizableRequest<DatabaseUser> request =
        factory.POST(url, client, gson, DatabaseUser.class).addParameters(parameters);
    return new DatabaseConnectionRequest<>(request);
  }
  private ParameterizableRequest<UserProfile> profileRequest() {
    HttpUrl url =
        HttpUrl.parse(auth0.getDomainUrl()).newBuilder().addPathSegment(TOKEN_INFO_PATH).build();

    return factory.POST(url, client, gson, UserProfile.class);
  }
 public String getBaseURL() {
   return auth0.getDomainUrl();
 }
 public String getClientId() {
   return auth0.getClientId();
 }