class HaloAuthenticator implements Authenticator {

    @Override
    public synchronized Request authenticate(Route route, Response response) throws IOException {
        HaloSession session = mSessionManager.getSession(HALO_SESSION_NAME);
        try {
            if (session == null || session.isSessionExpired() || session.mayBeServerExpired()) {
                flushSession();
                //Do auth
                Token token = null;
                if (!response.request().url().toString().endsWith(TokenRemoteDatasource.URL_GET_CLIENT_TOKEN) &&
                        !response.request().url().toString().endsWith(TokenRemoteDatasource.URL_GET_USER_TOKEN)) {
                    //request app token
                    token = requestToken();
                    if (token != null) {
                        session = new Session(token);
                    }
                }
            }
        } catch (Exception e) {
            Halog.e(getClass(), "The token could not be obtained. " + e.getMessage());
            throw e;
        }

        //The request authentication finished successfully
        if (session != null) {
            //check if its a client based login to recover account
            if(getCredentials().getLoginType()==Credentials.CLIENT_BASED_LOGIN) {
                //recover from logged user if there is a halo auth api
                if (mAuthenticationRecover != null && !mAuthenticationRecover.recoverStatus()) {
                    mAuthenticationRecover.recoverAccount();
                }
            }
            //Store the session
            mSessionManager.setSession(HALO_SESSION_NAME, session);
            return response.request()
                    .newBuilder()
                    .header(AUTHENTICATION_HEADER, session.getSessionAuthentication())
                    .build();
        }
        //Do not reconnect, we can not authenticate with the current token
        return null;
    }

    public  HaloAuthenticator(@NonNull HaloFramework framework,
                             @NonNull HaloManagerApi managerApi,
                             @NonNull HaloSessionManager sessionManager,
                             @NonNull Credentials credentials);

}