public static async Task <string> GetIdServerAccessToken(IdServerResourceOwnerClientSettings settings, HttpClientHandler httpClientHandler)
        {
            await semaphoreSlim.WaitAsync();

            try
            {
                if (settings == null)
                {
                    throw new ArgumentException("Parameter IdServerResourceOwnerClientSettings not provided");
                }

                int settingsHash = $"{settings.BaseAddress}|{settings.ClientId}|{settings.ClientSecret}|{settings.Scopes}|{settings.UserName}|{settings.Password}".GetHashCode();

                if (_idServerAccessTokens.ContainsKey(settingsHash) && _idServerAccessTokens[settingsHash] != null)
                {
                    TokenResponse response = _idServerAccessTokens[settingsHash];
                    //ToDo: possibly preemptively check if token is still valid
                    return(response.AccessToken);
                }

                try
                {
                    IdentityClient identityClient = new IdentityClient(settings.BaseAddress, settings.ClientId, settings.ClientSecret, httpClientHandler);

                    TokenResponse reponse = await identityClient.RequestTokenAsync(settings.UserName, settings.Password, settings.Scopes).ConfigureAwait(false);

                    if (reponse == null || string.IsNullOrEmpty(reponse.AccessToken))
                    {
                        throw new HttpClientException(System.Net.HttpStatusCode.Unauthorized, "Authorisation error: No AccessToken returned");
                    }

                    _idServerAccessTokens.Add(settingsHash, reponse);

                    return(reponse.AccessToken);
                }
                catch (Exception exc)
                {
                    throw new HttpClientException(System.Net.HttpStatusCode.Unauthorized, $"Authorisation error: {exc.Message}");
                }
            }
            finally
            {
                semaphoreSlim.Release();
            }
        }