public class HttpConstants {
    
    /**
     * This class cannot be instantiated.
     */
    private HttpConstants() {}

    public static final String AUTHORIZATION_HEADER = "Authorization";
    public static final String CHARSET_STRING = "UTF-8";
    public static final Charset ENCODING_CHARSET = Charset.forName(CHARSET_STRING);
    public static final String CONTENT_TYPE = "Content-Type";
    public static final String CONTENT_TYPE_JSON = "application/json";
    public static final String CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded";
    public static final String CONTENT_TYPE_HEADER = "Content-Type";
    public static final String CONTENT_LENGTH_HEADER = "Content-Length";

    public static final int DEFAULT_REQUEST_TIMEOUT_IN_MS = 5000;
    public static final int DEFAULT_CONNECTION_TIMEOUT_IN_MS = 5000;

    public enum HttpMethods {
        /**
         * See <a href="https://tools.ietf.org/html/rfc7231#section-4.3.1">HTTP/1.1 Semantics and Content: GET</a>.
         */
        GET("GET"),
        POST("POST");
        
        private final String method;
        
        private HttpMethods(String method) {
            this.method = method;
        }
        
        /**
         * Returns the HTTP Method to be sent with the HTTP Request message.
         * 
         * @return the HTTP method
         */
        public String getMethod() {
            return method;
        }
    }
} public interface HttpProvider extends Closeable {
    
    /**
     * Wrapper for an HTTP request.
     */
    public static interface HttpRequest {
        
        /**
         * Add the Authorization header to this request, with the specified 
         * <tt>value</tt>.
         * See also 
         * <a href="https://tools.ietf.org/html/rfc7235#section-4.2">RFC 7235</a>.
         * 
         * @param value the value to add in the Authorization header
         */
        void addAuthorizationHeader(String value);

        /**
         * Adds the additional (name, value)-pair to be sent as HTTP Headers
         * on the HTTP Request.
         * See also
         * <a href="https://tools.ietf.org/html/rfc7230#section-3.2">RFC 7230</a>.
         *
         * @param name the name of the HTTP Header to add
         * @param value the value of the HTTP Header to add
         */
        default void addHeader(String name, String value) {
            throw new UnsupportedOperationException("addHeader not supported");
        }

    }
    
    /**
     * Wrapper for authorizing HTTP requests.
     */
    public static interface HttpRequestAuthorizer {
        
        /**
         * Computes and adds a signature or token to the request as appropriate 
         * for the authentication or authorization scheme.
         * 
         * @param httpRequest the HttpRequest under construction, 
         *      to which to attach authorization
         * @param method the HTTP method 
         * @param url the URL of the request
         * @param formParams the 
         *      Content-Type: application/x-www-form-urlencoded
         *      form parameters.
         */
        void authorize(HttpRequest httpRequest, String method, String url, 
                Map<String, List<String>> formParams);

    }
    
    /**
     * Wrapper for HTTP responses.
     */
    public static interface HttpResponse {
        
        /**
         * Returns the HTTP response status code.
         * 
         * @return the HTTP response status code as an int
         */
        int getStatusCode();
        
        /**
         * Returns the HTTP Content-Length header value.
         * The content length of the response body.
         * 
         * @return the content length of the response body.
         */
        long getContentLength();
        
        /**
         * Get the response body, as an <tt>InputStream</tt>.
         * 
         * @return if there was a response entity, returns the InputStream reading bytes 
         *      from that response entity.
         *      otherwise, if there was no response entity, this method returns null.
         * @throws IOException if there is I/O trouble
         */
        InputStream getResponseBody() throws IOException;

        /**
         * Returns all the headers from the response
         * @return returns a Map of headers if the method implementation returns the headers 
         *      or throws Unsupported Operation Exception if the method is not implemented
         */

        default Map<String, List<String>> getHeaders() {
            throw new UnsupportedOperationException();
        }
        
    }

    /**
     * Gets the RequestBuilder, with the specified method, url, and requestBodyJson.
     * The Authorization header has already been set according to the 
     * httpRequestAuthorizer implementation.
     * 
     * @param httpRequestAuthorizer for adding the Authorization header value
     * @param method HTTP method value
     * @param url HTTP request URL
     * @param requestBodyJson the
     *      Content-Type: application/json
     *      JSON request body.
     * @return the HttpRequest object you can {@link #execute(HttpRequest)}.
     */
    HttpRequest getRequest(HttpRequestAuthorizer httpRequestAuthorizer, String method, String url, String requestBodyJson);
    
    /**
     * Gets the RequestBuilder, with the specified method, url, and formParams. 
     * The Authorization header has already been set according to the 
     * httpRequestAuthorizer implementation.
     * 
     * @param httpRequestAuthorizer for adding the Authorization header value
     * @param method HTTP method value
     * @param url HTTP request URL
     * @param formParams the 
     *      Content-Type: application/x-www-form-urlencoded
     *      form parameters.
     * @return the HttpRequest object you can {@link #execute(HttpRequest)}.
     */
    HttpRequest getRequest(HttpRequestAuthorizer httpRequestAuthorizer, String method, String url,
            Map<String, List<String>> formParams);
    
    /**
     * Execute the <tt>httpRequest</tt>.
     * Implementing classes would commonly invoke or schedule a RESTful HTTPS API call 
     * over the wire to the configured Service as part of <tt>execute</tt>.
     * 
     * @param httpRequest the HttpRequest
     * @return the HttpResponse to the request
     * @throws HttpException if there is trouble executing the httpRequest
     * @throws IOException if there is I/O trouble executing the httpRequest
     */
    HttpResponse execute(HttpRequest httpRequest) throws HttpException, IOException;
    
} public static interface HttpRequest {
        
    /**
     * Add the Authorization header to this request, with the specified 
     * <tt>value</tt>.
     * See also 
     * <a href="https://tools.ietf.org/html/rfc7235#section-4.2">RFC 7235</a>.
     * 
     * @param value the value to add in the Authorization header
     */
    void addAuthorizationHeader(String value);

    /**
     * Adds the additional (name, value)-pair to be sent as HTTP Headers
     * on the HTTP Request.
     * See also
     * <a href="https://tools.ietf.org/html/rfc7230#section-3.2">RFC 7230</a>.
     *
     * @param name the name of the HTTP Header to add
     * @param value the value of the HTTP Header to add
     */
    default void addHeader(String name, String value) {
        throw new UnsupportedOperationException("addHeader not supported");
    }

} public class RequestExecutionException extends RuntimeException {

    /**
     * Creates a new instance of <code>RequestExecutionException</code> without
     * detail message.
     */
    public RequestExecutionException() {
    }

    /**
     * Constructs an instance of <code>RequestExecutionException</code> with the
     * specified detail message.
     *
     * @param msg the detail message.
     */
    public RequestExecutionException(String msg) {
        super(msg);
    }
    
    /**
     * Constructs an instance of <code>RequestExecutionException</code> with the
     * specified detail message and cause.
     *
     * @param msg the detail message.
     * @param cause the cause
     */
    public RequestExecutionException(String msg, Throwable cause) {
        super(msg, cause);
    }
    
    /**
     * Constructs an instance of <code>RequestExecutionException</code> with the
     * specified cause.
     *
     * @param cause the cause
     */
    public RequestExecutionException(Throwable cause) {
        super(cause);
    }
} public class ResponseParsingException extends RuntimeException {

    /**
     * Creates a new instance of <code>ResponseParsingException</code> without
     * detail message.
     */
    public ResponseParsingException() {
    }

    /**
     * Constructs an instance of <code>ResponseParsingException</code> with the
     * specified detail message.
     *
     * @param msg the detail message.
     */
    public ResponseParsingException(String msg) {
        super(msg);
    }
    
    /**
     * Constructs an instance of <code>ResponseParsingException</code> with the
     * specified detail message and cause.
     *
     * @param msg the detail message.
     * @param cause the cause
     */
    public ResponseParsingException(String msg, Throwable cause) {
        super(msg, cause);
    }
    
    /**
     * Constructs an instance of <code>ResponseParsingException</code> with the
     * specified cause.
     *
     * @param cause the cause
     */
    public ResponseParsingException(Throwable cause) {
        super(cause);
    }
} public class NoRetryPolicy implements RetryPolicy {

    @Override
    public boolean shouldRetry(RetryContext retryContext) {
        return false;
    }

    @Override
    public int getNextRetryIntervalMillis(RetryContext retryContext) {
        return 0;
    }
} @FunctionalInterface
public interface Retryable {
    /**
     * Execute an operation with retry semantics.
     * @return http response from retry semantics.
     * @throws IOException
     * @throws HttpException
     */
    HttpProvider.HttpResponse execute() throws IOException, HttpException;
} public class ErrorResponse {
    
    /**
     * The error value.
     * From OAuth2.0 <a href="https://tools.ietf.org/html/rfc6749#section-5.2">Error Response</a> 
     * section, the following parameter: 
     * error
         REQUIRED.  A single ASCII [USASCII] error code from the
         following:

         invalid_request
               The request is missing a required parameter, includes an
               unsupported parameter value (other than grant type),
               repeats a parameter, includes multiple credentials,
               utilizes more than one mechanism for authenticating the
               client, or is otherwise malformed.

         invalid_client
               Client authentication failed (e.g., unknown client, no
               client authentication included, or unsupported
               authentication method).  The authorization server MAY
               return an HTTP 401 (Unauthorized) status code to indicate
               which HTTP authentication schemes are supported.  If the
               client attempted to authenticate via the "Authorization"
               request header field, the authorization server MUST
               respond with an HTTP 401 (Unauthorized) status code and
               include the "WWW-Authenticate" response header field
               matching the authentication scheme used by the client.

         invalid_grant
               The provided authorization grant (e.g., authorization
               code, resource owner credentials) or refresh token is
               invalid, expired, revoked, does not match the redirection
               URI used in the authorization request, or was issued to
               another client.

         unauthorized_client
               The authenticated client is not authorized to use this
               authorization grant type.

         unsupported_grant_type
               The authorization grant type is not supported by the
               authorization server.

         invalid_scope
               The requested scope is invalid, unknown, malformed, or
               exceeds the scope granted by the resource owner.

         Values for the "error" parameter MUST NOT include characters
         outside the set %x20-21 / %x23-5B / %x5D-7E.
     * 
     */
    private final String error;
    
    /**
     * The error_description value.
     * From OAuth2.0 <a href="https://tools.ietf.org/html/rfc6749#section-5.2">Error Response</a> 
     * section, the following parameter: 
     * error_description
         OPTIONAL.  Human-readable ASCII [USASCII] text providing
         additional information, used to assist the client developer in
         understanding the error that occurred.
         Values for the "error_description" parameter MUST NOT include
         characters outside the set %x20-21 / %x23-5B / %x5D-7E.
     */
    @JsonProperty("error_description")
    private final String errorDescription;
    
    /**
     * The numeric HTTP status code.
     * See also the HTTP 
     * <a href="https://tools.ietf.org/html/rfc7231#section-6">Response Status Codes</a> 
     * section.
     * 
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final Integer httpStatus;
    
    /**
     * A unique error identifier, useful for support questions, 
     * or tracking purposes.
     * 
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final String errorId;

    /**
     * A more detailed categorized code for the error, specific to the HERE authorization server 
     * semantics.
     * 
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final Integer errorCode;
    
    /**
     * A potentially-human-readable message describing the error.
     * No machine or automated code should process or interpret this value.
     * 
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final String message;

    /**
     * The title for this error response.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final String title;

    /**
     * The HTTP status code for this error response.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final Integer status;

    /**
     * The error code for this error response.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final String code;

    /**
     * The cause for this error response.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final String cause;

    /**
     * The action for this error response.  Actionable instructions for the user.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final String action;

    /**
     * The unique request correlation id, useful for support questions,
     * or tracking purposes.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     */
    private final String correlationId;

    public ErrorResponse() {
        this(null, null, null, null, null, null,
                null, null, null, null, null, null);
    }
    
    public ErrorResponse(
            String error,
            String errorDescription,
            String errorId,
            Integer httpStatus,
            Integer errorCode,
            String message) {
        this(error,
                errorDescription,
                errorId,
                httpStatus,
                errorCode,
                message,
                null, null, null, null, null, null);
    }

    public ErrorResponse(
            String error,
            String errorDescription,
            String errorId,
            Integer httpStatus,
            Integer errorCode,
            String message,
            String title,
            Integer status,
            String code,
            String cause,
            String action,
            String correlationId) {
        this.error = error;
        this.errorDescription = errorDescription;
        this.httpStatus = httpStatus;
        this.errorId = errorId;
        this.errorCode = errorCode;
        this.message = message;

        this.title = title;
        this.status = status;
        this.code = code;
        this.cause = cause;
        this.action = action;
        this.correlationId = correlationId;
    }
    
    /**
     * The error value.
     * From OAuth2.0 <a href="https://tools.ietf.org/html/rfc6749#section-5.2">Error Response</a> 
     * section, the following parameter: 
     * error
         REQUIRED.  A single ASCII [USASCII] error code from the
         following:

         invalid_request
               The request is missing a required parameter, includes an
               unsupported parameter value (other than grant type),
               repeats a parameter, includes multiple credentials,
               utilizes more than one mechanism for authenticating the
               client, or is otherwise malformed.

         invalid_client
               Client authentication failed (e.g., unknown client, no
               client authentication included, or unsupported
               authentication method).  The authorization server MAY
               return an HTTP 401 (Unauthorized) status code to indicate
               which HTTP authentication schemes are supported.  If the
               client attempted to authenticate via the "Authorization"
               request header field, the authorization server MUST
               respond with an HTTP 401 (Unauthorized) status code and
               include the "WWW-Authenticate" response header field
               matching the authentication scheme used by the client.

         invalid_grant
               The provided authorization grant (e.g., authorization
               code, resource owner credentials) or refresh token is
               invalid, expired, revoked, does not match the redirection
               URI used in the authorization request, or was issued to
               another client.

         unauthorized_client
               The authenticated client is not authorized to use this
               authorization grant type.

         unsupported_grant_type
               The authorization grant type is not supported by the
               authorization server.

         invalid_scope
               The requested scope is invalid, unknown, malformed, or
               exceeds the scope granted by the resource owner.

         Values for the "error" parameter MUST NOT include characters
         outside the set %x20-21 / %x23-5B / %x5D-7E.
     * 
     * @return the error
     */
    public String getError() {
        return error;
    }

    /**
     * The error_description value.
     * From OAuth2.0 <a href="https://tools.ietf.org/html/rfc6749#section-5.2">Error Response</a> 
     * section, the following parameter: 
     * error_description
         OPTIONAL.  Human-readable ASCII [USASCII] text providing
         additional information, used to assist the client developer in
         understanding the error that occurred.
         Values for the "error_description" parameter MUST NOT include
         characters outside the set %x20-21 / %x23-5B / %x5D-7E.
     * 
     * @return the error description
     */
    public String getErrorDescription() {
        return errorDescription;
    }
    
    /**
     * The httpStatus.
     * The numeric HTTP status code.
     * See also the HTTP 
     * <a href="https://tools.ietf.org/html/rfc7231#section-6">Response Status Codes</a> 
     * section.
     * 
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     * 
     * @return the httpStatus
     */
    public Integer getHttpStatus() {
       return httpStatus;
    }

    /**
     * The errorId.
     * A unique error identifier, useful for support questions, 
     * or tracking purposes.
     * 
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     * 
     * @return the errorId
     */
    public String getErrorId() {
        return errorId;
    }

    /**
     * The errorCode.
     * A more detailed categorized code for the error, specific to the HERE authorization server 
     * semantics.
     * 
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     *
     * @return the errorCode
     */
    public Integer getErrorCode() {
        return errorCode;
    }

    /**
     * The message.
     * A potentially-human-readable message describing the error.
     * No machine or automated code should process or interpret this value.
     * 
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     * 
     * @return the message
     */
    public String getMessage() {
        return message;
    }

    /**
     * The title for this error response.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     *
     * @return the title
     */
    public String getTitle() {
        return title;
    }

    /**
     * The HTTP status code for this error response.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     *
     * @return the status
     */
    public Integer getStatus() {
        return status;
    }

    /**
     * The error code for this error response.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     *
     * @return the error code
     */
    public String getCode() {
        return code;
    }

    /**
     * The cause for this error response.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     *
     * @return the cause for this error response
     */
    public String getCause() {
        return cause;
    }

    /**
     * The action for this error response.  Actionable instructions for the user.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     *
     * @return the action for this error response
     */
    public String getAction() {
        return action;
    }

    /**
     * The unique request correlation id, useful for support questions,
     * or tracking purposes.
     *
     * <p>
     * This property is a HERE extension to RFC6749 providing additional data.
     * 
     * @return the correlationId
     */
    public String getCorrelationId() {
        return correlationId;
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ErrorResponse that = (ErrorResponse) o;
        return Objects.equals(error, that.error) &&
                Objects.equals(errorDescription, that.errorDescription) &&
                Objects.equals(httpStatus, that.httpStatus) &&
                Objects.equals(errorId, that.errorId) &&
                Objects.equals(errorCode, that.errorCode) &&
                Objects.equals(message, that.message) &&
                Objects.equals(title, that.title) &&
                Objects.equals(status, that.status) &&
                Objects.equals(code, that.code) &&
                Objects.equals(cause, that.cause) &&
                Objects.equals(action, that.action) &&
                Objects.equals(correlationId, that.correlationId);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return Objects.hash(error, errorDescription, httpStatus, errorId, errorCode, message, title, status, code, cause, action, correlationId);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String toString() {
        return "ErrorResponse [error=" + error + ", errorDescription=" + errorDescription + ", httpStatus=" + httpStatus
                + ", errorId=" + errorId + ", errorCode=" + errorCode + ", message=" + message
                + ", title=" + title + ", status=" + status + ", code=" + code
                + ", cause=" + cause + ", action=" + action + ", correlationId=" + correlationId
                + "]";
    }

} public class RetryExecutor {

    private final RetryPolicy retryPolicy;
    private static final Logger LOGGER = Logger.getLogger(RetryExecutor.class.getName());

    public RetryExecutor(RetryPolicy retryPolicy) {
        this.retryPolicy = retryPolicy;
    }

    /**
     * Execute the given {@link Retryable} until retry policy decides to give up.
     * @param retryable the {@link Retryable} to execute
     * @return http response return from {@code Retryable}
     * @throws Exception
     */
    public HttpProvider.HttpResponse execute(Retryable retryable) throws Exception {
        RetryContext retryContext = new RetryContext();
        HttpProvider.HttpResponse httpResponse;

        while (true) {
            try {
                httpResponse = retryable.execute();
                retryContext.setLastRetryResponse(httpResponse);
                //clearing the exception generated by the last failed retry
                retryContext.setLastException(null);
            } catch (Exception e) {
                retryContext.setLastException(e);
            }

            if (retryPolicy.shouldRetry(retryContext)) {
                retryContext.incrementRetryCount();

                int waitInterval = retryPolicy.getNextRetryIntervalMillis(retryContext);

                LOGGER.warning("Retrying after - "+ waitInterval +" milliseconds...");
                try {
                    Thread.sleep(waitInterval);
                } catch (InterruptedException e){
                    LOGGER.warning("Got InterruptedException while waiting to retry.");
                }
            } else {
                break;
            }
        }

        if (retryContext.getLastException() != null) {
            throw retryContext.getLastException();
        }

        return retryContext.getLastRetryResponse();
    }
} public interface RetryPolicy {

    /**
     * Decides whether retry should happen based on last response or last exception thrown.
     * @param retryContext An instance of {@link RetryContext}
     * @return true if retry should happen otherwise false.
     */
    boolean shouldRetry(RetryContext retryContext);

    /**
     * Calculates wait interval after which retry should happen in milliseconds.
     * @param retryContext An instance of {@link RetryContext}
     * @return wait interval in milliseconds
     */
    int getNextRetryIntervalMillis(RetryContext retryContext);
} public interface OlpHttpMessage {
    String X_CORRELATION_ID = "X-Correlation-ID";

    /**
     * Get the correlationId (the unique value for tracking a request across services and within a service).
     *
     * @return the correlationId
     */
    String getCorrelationId();

    /**
     * Set the correlationId (the unique value for tracking a request across services and within a service).
     *
     * @param correlationId     the correlationId
     * @return                  the class implementing this method. Allows chaining methods,
     *                          e.g. classInstance.setCorrelationId("abc123").setFoo().setBar()
     */
    OlpHttpMessage setCorrelationId(String correlationId);
} public class CloseUtil {

    /**
     * A null-safe invocation of closeable.close(), such that if an IOException is
     * triggered, it is wrapped instead in an UncheckedIOException.
     *
     * @param closeable the closeable to be closed
     */
    public static void nullSafeCloseThrowingUnchecked(Closeable closeable) {
        if (null != closeable) {
            try {
                closeable.close();
            } catch (IOException ioe) {
                throw new UncheckedIOException(ioe);
            }
        }

    }
} public class OAuthConstants {
    
    /**
     * We commonly use "UTF-8" charset, this String is its name.
     */
    public static final String UTF_8_STRING = "UTF-8";
    
    /**
     * This is the constant for the "UTF-8" Charset already loaded.
     */
    public static final Charset UTF_8_CHARSET = Charset.forName(UTF_8_STRING);
} public interface Serializer {
    
    /**
     * Reads from the input jsonInputStream containing bytes from a JSON stream, 
     * and returns the corresponding Map&lt;String, Object&gt;.
     * 
     * @param jsonInputStream the input stream
     * @return the corresponding deserialized Map&lt;String, Object&gt;
     */
    Map<String, Object> jsonToMap(InputStream jsonInputStream);
    
    <T> T jsonToPojo (InputStream jsonInputStream, Class<T> pojoClass);
    
    String objectToJson(Object object);
    
    void writeObjectToJson(OutputStream outputStream, Object object);

}
import com.here.account.http.HttpConstants;
import com.here.account.http.HttpProvider;
import com.here.account.http.HttpProvider.HttpRequest;
import com.here.account.oauth2.RequestExecutionException;
import com.here.account.oauth2.ResponseParsingException;
import com.here.account.oauth2.retry.NoRetryPolicy;
import com.here.account.oauth2.retry.Retryable;
import com.here.account.oauth2.ErrorResponse;
import com.here.account.oauth2.retry.RetryExecutor;
import com.here.account.oauth2.retry.RetryPolicy;
import com.here.account.olp.OlpHttpMessage;
import com.here.account.util.CloseUtil;
import com.here.account.util.OAuthConstants;
import com.here.account.util.Serializer;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.function.BiFunction;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
/*
 * Copyright (c) 2018 HERE Europe B.V.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.here.account.client;





/**
 * An OLP Client that talks to an OLP Resource Server, in OAuth2-speak.
 * It is expected that a wrapper class invokes methods on an instance 
 * of this class, so that simple Java create(), read(), update(), 
 * and delete() methods can be written with POJOs.
 * 
 * Suitable for use with JSON-object response APIs.
 * 
 * @author kmccrack
 */
public class Client {

    private static final Logger LOGGER = Logger.getLogger(Client.class.getName());

    public static class Builder {
        private HttpProvider httpProvider;
        private Serializer serializer;