/// <summary>
        /// get constructed claim for the specified principal
        /// </summary>
        /// <param name="principal">target principal</param>
        /// <returns>a CLAIM_ENTRY if the specified principal is a member of an authentication silo</returns>
        CLAIM_ENTRY?getAuthSiloClaim(DirectoryEntry principal)
        {
            //AuthSiloClaim is not issued until the domain functional level is at DS_BEHAVIOR_WIN2012R2 or higher.
            using (DirectoryEntry root = new DirectoryEntry("LDAP://" + domainNC))
            {
                if (root.Properties[ConstValue.msDSBehaviorVersion] == null)
                {
                    return(null);
                }

                if ((root.Properties[ConstValue.msDSBehaviorVersion] == null) ||
                    (int.Parse(root.Properties[ConstValue.msDSBehaviorVersion].Value.ToString()) < ConstValue.WinSvr2012R2))
                {
                    return(null);
                }

                if ((principal.Properties[ConstValue.msDSAssignedAuthNPolicySilo] == null) ||
                    (principal.Properties[ConstValue.msDSAssignedAuthNPolicySilo].Value == null))
                {
                    return(null);
                }

                //Check if user is assigned to an enforced silo.
                using (DirectoryEntry assignedSilo = new DirectoryEntry("LDAP://" + principal.Properties[ConstValue.msDSAssignedAuthNPolicySilo].Value.ToString()))
                {
                    if ((assignedSilo.Properties[ConstValue.msDSAuthNPolicySiloEnforced] == null) ||
                        (!bool.Parse(assignedSilo.Properties[ConstValue.msDSAuthNPolicySiloEnforced].Value.ToString())))
                    {
                        return(null);
                    }

                    if (assignedSilo.Properties[ConstValue.msDSAuthNPolicySiloMembers] == null)
                    {
                        return(null);
                    }

                    //Check if silo is configured with the user as a member.
                    bool   memberOfSilo = false;
                    string dn           = principal.Properties[ConstValue.distinguishedname].Value.ToString();
                    foreach (var siloMember in assignedSilo.Properties[ConstValue.msDSAuthNPolicySiloMembers])
                    {
                        if (siloMember.Equals(dn))
                        {
                            memberOfSilo = true;
                            break;
                        }
                    }

                    if (memberOfSilo == false)
                    {
                        return(null);
                    }

                    //Fill in the claim details and return the claim.
                    CLAIM_ENTRY claim = new CLAIM_ENTRY();
                    claim.Id                          = ConstValue.authSiloClaimName;
                    claim.Type                        = CLAIM_TYPE.CLAIM_TYPE_STRING;
                    claim.Values.Struct3              = new CLAIM_TYPE_VALUE_LPWSTR();
                    claim.Values.Struct3.ValueCount   = 1;
                    claim.Values.Struct3.StringValues = new string[] { assignedSilo.Properties[ConstValue.name].Value.ToString() };
                    return(claim);
                }
            }
        }
        /// <summary>
        /// get constructed claim for the specified principal
        /// </summary>
        /// <param name="principal">target principal</param>
        /// <returns>a CLAIM_ENTRY if the specified principal is a member of an authentication silo</returns>
        CLAIM_ENTRY? getAuthSiloClaim(DirectoryEntry principal)
        {
            //AuthSiloClaim is not issued until the domain functional level is at DS_BEHAVIOR_WIN2012R2 or higher.
            using (DirectoryEntry root = new DirectoryEntry("LDAP://" + domainNC))
            {

                if (root.Properties[ConstValue.msDSBehaviorVersion] == null)
                {
                    return null;
                }

                if ((root.Properties[ConstValue.msDSBehaviorVersion] == null)
                    || (int.Parse(root.Properties[ConstValue.msDSBehaviorVersion].Value.ToString()) < ConstValue.WinSvr2012R2))
                {
                    return null;
                }

                if ((principal.Properties[ConstValue.msDSAssignedAuthNPolicySilo] == null)
                    || (principal.Properties[ConstValue.msDSAssignedAuthNPolicySilo].Value == null))
                {
                    return null;
                }

                //Check if user is assigned to an enforced silo.
                using (DirectoryEntry assignedSilo = new DirectoryEntry("LDAP://" + principal.Properties[ConstValue.msDSAssignedAuthNPolicySilo].Value.ToString()))
                {
                    if ((assignedSilo.Properties[ConstValue.msDSAuthNPolicySiloEnforced] == null)
                        || (!bool.Parse(assignedSilo.Properties[ConstValue.msDSAuthNPolicySiloEnforced].Value.ToString())))
                    {
                        return null;
                    }

                    if (assignedSilo.Properties[ConstValue.msDSAuthNPolicySiloMembers] == null)
                    {
                        return null;
                    }

                    //Check if silo is configured with the user as a member.
                    bool memberOfSilo = false;
                    string dn = principal.Properties[ConstValue.distinguishedname].Value.ToString();
                    foreach (var siloMember in assignedSilo.Properties[ConstValue.msDSAuthNPolicySiloMembers])
                    {
                        if (siloMember.Equals(dn))
                        {
                            memberOfSilo = true;
                            break;
                        }
                    }

                    if (memberOfSilo == false)
                    {
                        return null;
                    }

                    //Fill in the claim details and return the claim.
                    CLAIM_ENTRY claim = new CLAIM_ENTRY();
                    claim.Id = ConstValue.authSiloClaimName;
                    claim.Type = CLAIM_TYPE.CLAIM_TYPE_STRING;
                    claim.Values.Struct3 = new CLAIM_TYPE_VALUE_LPWSTR();
                    claim.Values.Struct3.ValueCount = 1;
                    claim.Values.Struct3.StringValues = new string[] { assignedSilo.Properties[ConstValue.name].Value.ToString() };
                    return claim;
                }
            }
        }