/// <summary>
        /// Retrieve listing of all roles to which a specified user belongs.
        /// </summary>
        /// <param name="userName"></param>
        /// <returns>String array of roles</returns>
        public override string[] GetRolesForUser(string userName)
        {
            var userGroupsCache = CacheController.GetActiveDirectoryUserGroupsCache();

            string[] userGroups;

            if (userGroupsCache == null)
            {
                // App just started or timeout purged cache. Create cache object and add to cache.
                userGroupsCache = new ConcurrentDictionary <string, string[]>();

                if (_cacheTimeoutInMinutes > 0)
                {
                    CacheController.SetCache(CacheItem.ActiveDirectoryUserGroups, userGroupsCache, new DateTimeOffset(DateTime.UtcNow.AddMinutes(_cacheTimeoutInMinutes)));
                }
            }
            else if (userGroupsCache.TryGetValue(userName, out userGroups))
            {
                // Found user in cache. Return.
                return(userGroups);
            }

            // User not in cache. Get user's groups from AD.
            var userGroupsList = new List <string>();

            using (var context = new PrincipalContext(ContextType.Domain, _domain, _domainDN))
            {
                try
                {
                    var p = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, userName);

                    if (p != null)
                    {
                        var groups = p.GetAuthorizationGroups();

                        //foreach (var group in groups)
                        // Don't user foreach because we need to swallow NoMatchingPrincipalException, which can't be done with a foreach
                        using (var e = groups.GetEnumerator())
                        {
                            while (e.MoveNext())
                            {
                                string accountName = null;
                                try
                                {
                                    accountName = e.Current.SamAccountName;
                                }
                                catch (NoMatchingPrincipalException) { } // Encountered with a customer. See https://social.msdn.microsoft.com/Forums/vstudio/en-US/9dd81553-3539-4281-addd-3eb75e6e4d5d/

                                switch (_groupMode)
                                {
                                case GroupMode.WhiteList:
                                    if (_whiteListGroups.Contains(accountName))
                                    {
                                        userGroupsList.Add(accountName);
                                    }
                                    break;

                                case GroupMode.BlackList:
                                    if (!_blackListGroups.Contains(accountName))
                                    {
                                        userGroupsList.Add(accountName);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new ProviderException("Unable to query Active Directory.", ex);
                }
            }

            userGroups = userGroupsList.ToArray();
            userGroupsCache.TryAdd(userName, userGroups);

            return(userGroups);
        }