/// <summary>
        /// Get the latest AD token given the reseller domain and client credentials
        /// </summary>
        /// <param name="domain">domain of the reseller</param>
        /// <param name="clientId">clientID of the application</param>
        /// <param name="clientSecret">client secret of the application, also refered to as key</param>
        /// <param name="adAuthorizationToken">ad authorization token, can be null</param>
        /// <returns>Latest AD Authorization token</returns>
        public static AuthorizationToken GetAD_Token(string domain, string clientId, string clientSecret, AuthorizationToken adAuthorizationToken = null)
        {
            if (adAuthorizationToken == null || (adAuthorizationToken != null && adAuthorizationToken.IsNearExpiry()))
            {
                //// Refresh the token on one of two conditions
                //// 1. If the token has never been retrieved
                //// 2. If the token is near expiry
                var adToken = GetADToken(domain, clientId, clientSecret);
                adAuthorizationToken = new AuthorizationToken(adToken.access_token.ToString(), Convert.ToInt64(adToken.expires_in.ToString()));
            }

            return adAuthorizationToken;
        }
        /// <summary>
        /// Get the latest sales agent token given the AD Authorization Token
        /// </summary>
        /// <param name="adAuthorizationToken">AD Authorization Token</param>
        /// <param name="saAuthorizationToken">Sales agent authorization token, can be null</param>
        /// <returns>Latest sales agent token</returns>
        public static AuthorizationToken GetSA_Token(AuthorizationToken adAuthorizationToken, AuthorizationToken saAuthorizationToken = null)
        {
            if (saAuthorizationToken == null || (saAuthorizationToken != null && saAuthorizationToken.IsNearExpiry()))
            {
                //// Refresh the token on one of two conditions
                //// 1. If the token has never been retrieved
                //// 2. If the token is near expiry
                
                var saToken = GetSA_Token(adAuthorizationToken.AccessToken);
                saAuthorizationToken = new AuthorizationToken(saToken.access_token.ToString(), Convert.ToInt64(saToken.expires_in.ToString()));
            }

            return saAuthorizationToken;
        }
        /// <summary>
        /// Get a object instance with the token for requests initialized for the received tenant or the CSP tenant
        /// (if empty parameter).
        /// </summary>
        public AzureADGraphApiHelper(string forCustomerTenant = null)
        {
            // If empty, initialize for CSP Tenant authentication
            if (string.IsNullOrWhiteSpace(forCustomerTenant))
            { // Use CSP Tenant context
                _forCustomerTenant = Constants.CSP_TENANT_NAME;
            }
            else
            { // Initialize for customer tenant authentication
                _forCustomerTenant = forCustomerTenant;
            }

            // Get the AD token for the requests
            _tokenForRequests = GetADTokenForRequests(_forCustomerTenant).Result;
        }
        /// <summary>
        /// Gets the AD token for the requests, for the received customer tenant.
        /// </summary>
        public async Task<AuthorizationToken> GetADTokenForRequests(string customerTenant)
        {
            if (_tokenForRequests != null)
            {
                // already initialized
                return _tokenForRequests;
            }

            AuthenticationContext _authenticationContext = new AuthenticationContext(string.Format(Constants.AAD_INSTANCE,
                customerTenant));

            UserCredential _userCredential = new UserCredential(Constants.CSP_SERVICE_USERNAME,
                Constants.CSP_SERVICE_PASSWORD);

            // else. Initialize and return
            AuthenticationResult authenticationResult = await _authenticationContext.AcquireTokenAsync(
                  Constants.GRAPH_RESOURCE_URL,
                  Constants.AZURE_AD_APP_ID_NATIVE_APP,
                  _userCredential);

            _tokenForRequests = new AuthorizationToken(authenticationResult.AccessToken,
             authenticationResult.ExpiresOn.DateTime);

            return _tokenForRequests;
        }