/// <summary>
        /// Gets the type of the account.
        /// </summary>
        /// <param name="entry">The entry.</param>
        /// <returns>
        /// A Rainbow.Framework.Helpers.ADHelper.ADAccountType value...
        /// </returns>
        private static ADAccountType GetAccountType(DirectoryEntry entry)
        {
            ADAccountType           accounttype = ADAccountType.user;
            PropertyValueCollection objectClass = entry.Properties["objectClass"];

            for (int i = 0; i < objectClass.Count; i++)
            {
                if ((string)objectClass[i] == "group")
                {
                    accounttype = ADAccountType.group;
                    break;
                }
            }
            return(accounttype);
        }
        /// <summary>
        /// Gets the member list.
        /// </summary>
        /// <param name="Refresh">if set to <c>true</c> [refresh].</param>
        /// <param name="ADDomain">The AD domain.</param>
        /// <param name="AppCache">The app cache.</param>
        /// <returns>A System.Data.DataTable value...</returns>
        public static DataTable GetMemberList(bool Refresh, string ADDomain, Cache AppCache)
        {
            // see if we want to refresh, if not, get it from the cache if available
            if (!Refresh)
            {
                object tmp = AppCache.Get("ADUsersAndGroups" + ADDomain);
                if (tmp != null)
                {
                    return(((DataSet)tmp).Tables[0]);
                }
            }

            // create dataset
            using (DataSet ds = new DataSet())
            {
                using (DataTable dt = new DataTable())
                {
                    ds.Tables.Add(dt);

                    DataColumn dc = new DataColumn("DisplayName", typeof(string));
                    dt.Columns.Add(dc);
                    dc = new DataColumn("AccountName", typeof(string));
                    dt.Columns.Add(dc);
                    dc = new DataColumn("AccountType", typeof(string));
                    dt.Columns.Add(dc);

                    // add built in users first
                    dt.Rows.Add(new Object[] { "Admins", "Admins", "group" });
                    dt.Rows.Add(new Object[] { "All Users", "All Users", "group" });
                    dt.Rows.Add(new Object[] { "Authenticated Users", "Authenticated Users", "group" });
                    dt.Rows.Add(new Object[] { "Unauthenticated Users", "Unauthenticated Users", "group" });

                    // construct root entry
                    using (DirectoryEntry rootEntry = GetDomainRoot(ADDomain))
                    {
                        if (ADDomain.Trim().ToLower().StartsWith("ldap://"))
                        {
                            string DomainName = GetNetbiosName(rootEntry);

                            // get users/groups
                            DirectorySearcher mySearcher = new DirectorySearcher(rootEntry);
                            mySearcher.Filter = "(|(objectClass=group)(&(objectClass=user)(objectCategory=person)))";
                            mySearcher.PropertiesToLoad.Add("cn");
                            mySearcher.PropertiesToLoad.Add("objectClass");
                            mySearcher.PropertiesToLoad.Add("sAMAccountName");

                            SearchResultCollection mySearcherSearchResult;
                            try
                            {
                                mySearcherSearchResult = mySearcher.FindAll();
                                foreach (SearchResult resEnt in mySearcherSearchResult)
                                {
                                    DirectoryEntry entry        = resEnt.GetDirectoryEntry();
                                    string         name         = (string)entry.Properties["cn"][0];
                                    string         abbreviation = (string)entry.Properties["sAMAccountName"][0];
                                    ADAccountType  accounttype  = GetAccountType(entry);
                                    dt.Rows.Add(
                                        new Object[] { name, DomainName + "\\" + abbreviation, accounttype.ToString() });
                                }
                            }
                            catch
                            {
                                throw new Exception("Could not get users/groups from domain '" + ADDomain + "'.");
                            }
                        }
                        else if (ADDomain.Trim().ToLower().StartsWith("winnt://"))
                        {
                            string DomainName = rootEntry.Name;

                            // Get the users
                            rootEntry.Children.SchemaFilter.Add("user");
                            foreach (DirectoryEntry user in rootEntry.Children)
                            {
                                string fullname    = (string)user.Properties["FullName"][0];
                                string accountname = user.Name;
                                dt.Rows.Add(
                                    new Object[] { fullname, DomainName + "\\" + fullname, ADAccountType.user.ToString() });
                            }

                            // Get the users
                            rootEntry.Children.SchemaFilter.Add("group");
                            foreach (DirectoryEntry user in rootEntry.Children)
                            {
                                string fullname    = user.Name;
                                string accountname = user.Name;
                                dt.Rows.Add(
                                    new Object[]
                                    { fullname, DomainName + "\\" + fullname, ADAccountType.group.ToString() });
                            }
                        }
                    }

                    // add dataset to the cache
                    AppCache.Insert("ADUsersAndGroups" + ADDomain, ds);

                    // return datatable
                    return(dt);
                }
            }
        }
        /// <summary>
        /// This function returns an EmailAddressList object.
        /// </summary>
        /// <param name="Account">Windows user or group</param>
        /// <returns>EmailAddressList</returns>
        public static EmailAddressList GetEmailAddresses(string Account)
        {
            // Lookup the domain in which we must look for the user or group
            string[] account = Account.Split("\\".ToCharArray());
            if (account.Length != 2)
            {
                return(new EmailAddressList()); // not a valid windows account!
            }
            DirectoryEntry rootEntry = null;

            string[] domains = Config.ADdns.Split(";".ToCharArray());
            // jes1111 - ConfigurationSettings.AppSettings["ADdns"].Split(";".ToCharArray());
            for (int i = 0; i < domains.Length; i++)
            {
                if (domains[i].Trim().ToLower().StartsWith("winnt://"))
                {
                    continue; // NT domains do not keep track of email addresses
                }
                rootEntry = GetDomainRoot(domains[i]);
                if (GetNetbiosName(rootEntry).Trim().ToLower() == account[0].Trim().ToLower())
                {
                    break;
                }
                else
                {
                    rootEntry = null;
                }
            }

            // Unknown domain : return empty list
            if (rootEntry == null)
            {
                return(new EmailAddressList());
            }

            // Domain found: lets lookup the object
            DirectorySearcher mySearcher = new DirectorySearcher(rootEntry);

            mySearcher.Filter = "(&(|(objectClass=group)(&(objectClass=user)(objectCategory=person)))(sAMAccountName=" +
                                account[1] + "))";
            mySearcher.PropertiesToLoad.Add("mail");
            mySearcher.PropertiesToLoad.Add("objectClass");
            mySearcher.PropertiesToLoad.Add("member");

            DirectoryEntry entry = null;

            try
            {
                entry = mySearcher.FindOne().GetDirectoryEntry();
            }
            catch
            {
                throw new Exception("Could not get users/groups from domain '" + account[0] + "'.");
            }

            // no object found
            if (entry == null)
            {
                return(new EmailAddressList());
            }

            // determine accounttype

            ADAccountType accounttype = GetAccountType(entry);

            EmailAddressList eal = new EmailAddressList();

            // object is user --> retrieve its emailaddress and return
            if (accounttype == ADAccountType.user)
            {
                try
                {
                    eal.Add(entry.Properties["mail"][0]);
                }
                catch
                {
                }
                return(eal);
            }

            // object is group --> retrieve all users that are contained
            // in the group or in groups of the group
            GetUsersInGroup(entry, eal, new ArrayList());
            return(eal);
        }
        // Added by gman3001: 2004/10/26
        /// <summary>
        /// This function returns an array of strings consisting of the AD groups that this user belongs to.
        /// </summary>
        /// <param name="UserAccount">Windows user or group</param>
        /// <returns>Groups string array</returns>
        public static string[] GetUserGroups(string UserAccount)
        {
            ArrayList UGroups = new ArrayList();

            if (UserAccount != null)
            {
                // Lookup the domain in which we must look for the user or group
                string[] account = UserAccount.Split("\\".ToCharArray());
                if (account.Length != 2)
                {
                    return((string[])UGroups.ToArray(typeof(string)));  // not a valid windows account!
                }
                DirectoryEntry rootEntry = null;
                string[]       domains   = Config.ADdns.Split(";".ToCharArray());
                // jes1111 - ConfigurationSettings.AppSettings["ADdns"].Split(";".ToCharArray());
                for (int i = 0; i < domains.Length; i++)
                {
                    if (domains[i].Trim().ToLower().StartsWith("winnt://"))
                    {
                        continue; // NT domains do not keep track of email addresses
                    }
                    rootEntry = GetDomainRoot(domains[i]);
                    if (GetNetbiosName(rootEntry).Trim().ToLower() == account[0].Trim().ToLower())
                    {
                        break;
                    }
                    else
                    {
                        rootEntry = null;
                    }
                }

                // Unknown domain : return empty list
                if (rootEntry == null)
                {
                    return((string[])UGroups.ToArray(typeof(string)));
                }

                // Domain found: lets lookup the object
                DirectorySearcher mySearcher = new DirectorySearcher(rootEntry);
                mySearcher.Filter =
                    "(&(|(objectClass=group)(&(objectClass=user)(objectCategory=person)))(sAMAccountName=" + account[1] +
                    "))";
                mySearcher.PropertiesToLoad.Add("objectClass");
                mySearcher.PropertiesToLoad.Add("member");
                mySearcher.PropertiesToLoad.Add("sAMAccountName");
                mySearcher.PropertiesToLoad.Add("displayName");

                DirectoryEntry entry = null;
                try
                {
                    entry = mySearcher.FindOne().GetDirectoryEntry();
                }
                catch
                {
                    throw new Exception("Could not get users/groups from domain '" + account[0] +
                                        "'. Either the user/group does not exist, or you do not have the necessary permissions in the Active Directory.");
                }

                // no object found
                if (entry == null)
                {
                    return((string[])UGroups.ToArray(typeof(string)));
                }

                // determine accounttype
                ADAccountType accounttype = GetAccountType(entry);

                // object is user --> retrieve the name of the groups it is a member of and return
                if (accounttype == ADAccountType.user)
                {
                    try
                    {
                        PropertyValueCollection values = (PropertyValueCollection)entry.Properties["sAMAccountName"];
                        string accountPath             = string.Empty;
                        if (values != null && values.Count > 0)
                        {
                            accountPath = account[0] + "\\" + values[0].ToString();
                            UGroups.Add(accountPath);
                        }
                        //Add generic system groups to the group list, since this user was authenticated when they entered the website
                        //this user is in the 'Authenticated Users' and 'All Users' groups by default
                        UGroups.Add("Authenticated Users");
                        UGroups.Add("All Users");

                        string rootPath = entry.Path;
                        rootPath = rootPath.Substring(0, rootPath.IndexOf("/", 7) + 1);

                        for (int i = 0; i < entry.Properties["memberOf"].Count; i++)
                        {
                            DirectoryEntry currentEntry =
                                new DirectoryEntry(rootPath + entry.Properties["memberOf"][i].ToString());
                            if (GetAccountType(currentEntry) == ADAccountType.group)
                            {
                                // add to group list if this is a group
                                values = currentEntry.Properties["sAMAccountName"];
                                if (values != null && values.Count > 0)
                                {
                                    string GroupName = account[0] + "\\" + values[0].ToString();
                                    if (!UGroups.Contains(GroupName))
                                    {
                                        UGroups.Add(GroupName);
                                    }
                                }
                            }
                        }
                    }
                    catch
                    {
                    }
                }
            }
            return((string[])UGroups.ToArray(typeof(string)));
        }