/// <summary>
        /// Retrieve listing of all roles.
        /// </summary>
        /// <returns>String array of roles</returns>
        public override string[] GetAllRoles()
        {
            var groupUsersCache = CacheController.GetActiveDirectoryGroupUsersCache();

            string[] groups;

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

                if (_cacheTimeoutInMinutes > 0)
                {
                    CacheController.SetCache(CacheItem.ActiveDirectoryGroupUsers, groupUsersCache, new DateTimeOffset(DateTime.UtcNow.AddMinutes(_cacheTimeoutInMinutes)));
                }
            }
            else if (groupUsersCache.TryGetValue("AllGroups", out groups))
            {
                // Found group in cache. Return.
                return(groups);
            }

            // "AllGroups" not in cache. Get groups from AD.
            var groupsList = new List <string>();
            var roles      = SearchActiveDirectory(_connectionStringName, "(&(objectCategory=group)(|(groupType=-2147483646)(groupType=-2147483644)(groupType=-2147483640)))", "samAccountName");

            foreach (var role in roles)
            {
                switch (_groupMode)
                {
                case GroupMode.WhiteList:
                    if (_whiteListGroups.Contains(role))
                    {
                        groupsList.Add(role);
                    }
                    break;

                case GroupMode.BlackList:
                    if (!_blackListGroups.Contains(role))
                    {
                        groupsList.Add(role);
                    }
                    break;
                }
            }

            groups = groupsList.ToArray();
            groupUsersCache.TryAdd("AllGroups", groups);

            return(groups);
        }
        /// <summary>
        /// Gets the users in role.
        /// </summary>
        /// <param name="roleName">Name of the role. Case insensitive.</param>
        /// <returns>Returns the users in role.</returns>
        public override string[] GetUsersInRole(string roleName)
        {
            if (!RoleExists(roleName))
            {
                throw new ProviderException($"The role '{roleName}' was not found.");
            }

            var groupUsersCache = CacheController.GetActiveDirectoryGroupUsersCache();

            string[] groupUsers;

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

                if (_cacheTimeoutInMinutes > 0)
                {
                    CacheController.SetCache(CacheItem.ActiveDirectoryGroupUsers, groupUsersCache, new DateTimeOffset(DateTime.UtcNow.AddMinutes(_cacheTimeoutInMinutes)));
                }
            }
            else if (groupUsersCache.TryGetValue(roleName, out groupUsers))
            {
                // Found group in cache. Return.
                return(groupUsers);
            }

            // Group not in cache. Get group's users from AD.
            var groupUsersList = new List <string>();

            // Get list of users from membership provider. We only return a user if it's also in the membership user list. We need this because p.GetMembers()
            // returns all users in the role, regardless of the organization unit/container. Since UserController.GetAllUsers() filters by this info, we can use
            // that user list to guarantee that users returned here are also filtered by that info.
            var allUsersFromMembershipProvider = Controller.UserController.GetAllUsers();

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

                    if (p != null)
                    {
                        var usersInRole = p.GetMembers(true);

                        foreach (var user in usersInRole)
                        {
                            if (allUsersFromMembershipProvider.Any(u => u.UserName.Equals(user.SamAccountName, StringComparison.OrdinalIgnoreCase)))
                            {
                                groupUsersList.Add(user.SamAccountName);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new ProviderException("Unable to query Active Directory.", ex);
                }
            }

            groupUsers = groupUsersList.ToArray();
            groupUsersCache.TryAdd(roleName, groupUsers);

            return(groupUsers);
        }