public static async Task<GenderizeResult> GenderizeName(string name, string country)
        {            
            // if there's a cached entry for this first name and country, return it
            if (Cache.ContainsKey(name + "_" + country))
            {
                if (Cache[name + "_" + country] == null)
                    return null;
                // well, return it only if it meets the confidence and count requirements
                if((Cache[name + "_" + country].Probability>=ProbabilityThreshold)&&(Cache[name + "_" + country].Count>=CountThreshold))
                    return Cache[name + "_" + country];
            }
            else
            {
                HttpClient client = new HttpClient();

                // query the API to infer gender from the first name AND the country of the user
                string query = string.Format("https://api.genderize.io/?name={0}&country_id={1}{2}", name, country, (ApiKey != String.Empty) ? "&apikey=" + ApiKey : string.Empty);
                var response =  client.GetAsync(query).Result;
                if (response.IsSuccessStatusCode)
                {
                    JObject jo = JObject.Parse(await response.Content.ReadAsStringAsync());
                    // if the gender proerty comes back as null, it's possible that there are no entries for that name in the specified country
                    // let's try to infer the gender from the first name alone, then
                    if ((string)jo["gender"] == null)
                    {
                        query = string.Format("https://api.genderize.io/?name={0}{1}", name, (ApiKey != String.Empty) ? "&apikey=" + ApiKey : string.Empty);
                        response = client.GetAsync(query).Result;
                        jo = JObject.Parse(await response.Content.ReadAsStringAsync());
                    }
                    // if we did get a gender inference
                    if ((string)jo["gender"] != null)
                    {
                        GenderizeResult gr = new GenderizeResult
                        {
                            Name = (string)jo["name"],
                            Gender = (string)jo["gender"],
                            Probability = (float)jo["probability"],
                            Count = (int)jo["count"]
                        };
                        // cache the result
                        Cache.Add(name + "_" + country, gr);
                        // if the confidence meets the thresholds, return the GenderizeResult
                        if ((gr.Probability >= ProbabilityThreshold) && (gr.Count >= CountThreshold))
                            return gr;
                    }
                    else
                    {
                        // the name was not present at all in the API.
                        // add placeholder in cache, so we don't keep calling the API needlessly for this name/country combination
                        Cache.Add(name + "_" + country, null);
                    }
                }
            }
            return null;
        }
        // infers the gender of the current user, then recursely infers the gender mix for all of his/her reports
        // populated the Reports collection in the process   
        // same note about 1 hour execution limit applies here
        public async void GetGenderMix(string accessToken)
        {
            Males = Females = Undefined = Contacts = 0;

            // infer account's gender
            GenderData = await GenderizeProxy.GenderizeName(FirstName, Country);

            // if we could not establish the user's gender
            if (GenderData == null)
            {
                Undefined = 1;
            }
            else
            {
                // we have a successful inference. The account is the first entry for his/her own org            
                if (GenderData.Gender == "male")
                {
                    Males = 1;
                }
                else
                {
                    Females = 1;
                }
            }
            // retrieve all the direct reports of the current account
            string[] upnComponents = UPN.Split('@');
            string alias = upnComponents[0];
            string domain = upnComponents[1];
            string reportsQuery = String.Format("https://graph.windows.net/{0}/users/{1}/directReports?api-version=1.6", domain, UPN);
            HttpClient httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            HttpResponseMessage response = httpClient.GetAsync(reportsQuery).Result;
            if (response.IsSuccessStatusCode)
            {
                string rez = response.Content.ReadAsStringAsync().Result;
                JObject jo = JObject.Parse(rez);

                // if the account does have reports
                foreach (JObject jreport in jo["value"])
                {
                    if ((string)jreport["userPrincipalName"] != null)
                    {
                        // create an account representing the report
                        Account report = new Account
                        {
                            UPN = (string)jreport["userPrincipalName"],
                            FirstName = (string)jreport["givenName"],
                            Country = InferCountryFromPhoneNumber((string)jreport["telephoneNumber"]),
                            Reports = new List<Account>()
                        };
                        // recurse on it
                        report.GetGenderMix(accessToken);
                        // fold back into the tally the gender numbers of the sub org
                        Males += report.Males;
                        Females += report.Females;
                        Undefined += report.Undefined;
                        Contacts += report.Contacts;
                        // append the Account represeting the report to the Reports collection
                        Reports.Add(report);
                    }
                    // no UPN means that the accunt is not a User, but a Contact. We don't count those here.
                    else
                        Contacts += 1;
                }
            }
            if (Reports.Count != 0)
                Console.WriteLine(" {0}'s org - {1} males, {2} females, {3} indetermined", UPN, Males, Females, Undefined);

        }