/// <summary>
        /// Access Check Algorithm. MS-DTYP section 2.5.4.1
        /// </summary>
        /// <param name="securityDescriptor">
        /// SECURITY_DESCRIPTOR structure that is assigned to the object.
        /// </param>
        /// <param name="token">
        /// Token is an authorization context containing all SIDs 
        /// that represent the security principal
        /// </param>
        /// <param name="accessRequestMask">
        /// Set of permissions requested on the object.
        /// </param>
        /// <param name="objectTree">
        /// A tree representation of the hierarchy of objects for which 
        /// to check access. Each node represents an object with two values. 
        /// A GUID that represents the object itself and a value called 
        /// Remaining, which indicates the user rights request for that 
        /// node that have not yet been satisfied. It can be null.
        /// </param>
        /// <param name="principalSelfSubstitudeSid">
        /// A SID that logically replaces the SID in any ACE that contains 
        /// the well-known PRINCIPAL_SELF SID. It can be null.
        /// </param>
        /// <returns>
        /// Returns TRUE if access is allowed. Otherwise, it returns FALSE if access is denied. 
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown when the Dacl field of securityDescriptor doesn't exist, but the DACLPresent flag is set.
        /// Thrown when the Revision field of securityDescriptor is invalid
        /// </exception>
        public static bool AccessCheck(
            _SECURITY_DESCRIPTOR securityDescriptor,
            Token token,
            uint accessRequestMask,
            AccessCheckObjectTree objectTree,
            _SID? principalSelfSubstitudeSid)
        {
            //MS-ADTS Section 5.1.3.3.1 Null vs. Empty DACLs
            //The presence of a NULL DACL in the nTSecurityDescriptor attribute of an object grants full
            //access to the object to any principal that requests it; normal access checks are not performed
            //with respect to the object.

            if (securityDescriptor.Revision != 0x1)
            {
                throw new ArgumentException("The Revision field is invalid.", "securityDescriptor");
            }

            if ((securityDescriptor.Control & SECURITY_DESCRIPTOR_Control.DACLPresent)
                == SECURITY_DESCRIPTOR_Control.None)
            {
                return true;
            }
            else if (securityDescriptor.Dacl == null)
            {
                throw new ArgumentException(
                    "The Dacl field of securityDescriptor doesn't exist, but the DACLPresent flag is set.", "securityDescriptor");
            }

            //Pscudocode
            //
            //Set DACL to SecurityDescriptor Dacl field
            //Set RemainingAccess to Access Request mask
            //
            //IF RemainingAccess contains ACCESS_SYSTEM_SECURITY access flag THEN
            //IF Token.Privileges contains SeSecurityPrivilege THEN
            //Remove ACCESS_SYSTEM_SECURITY access bit from RemainingAccess
            //END IF
            //END IF
            //
            //IF RemainingAccess contains WRITE_OWNER access bit THEN
            //IF Token.Privileges contains SeTakeOwnershipPrivilege THEN
            //Remove WRITE_OWNER access bit from RemainingAccess
            //END IF
            //END IF
            //-- the owner of an object is always granted READ_CONTROL and WRITE_DAC.
            //CALL SidInToken( Token, SecurityDescriptor.Owner, PrincipalSelfSubst)
            //IF SidInToken returns True THEN
            //Remove READ_CONTROL and WRITE_DAC from RemainingAccess
            //END IF

            _ACL? dacl = securityDescriptor.Dacl;
            uint remainingAccess = accessRequestMask;
            AccessCheckObjectTree localTree = new AccessCheckObjectTree();
            Guid[] allNodes = new Guid[] { };

            if ((remainingAccess & ACCESS_MASK_ACCESS_SYSTEM_SECURITY) != 0 && token.Privileges != null)
            {
                foreach (_LUID privilege in token.Privileges)
                {
                    if (ObjectUtility.DeepCompare(privilege, GetPrivilegeLuid(PrivilegeName.SE_SECURITY_NAME)))
                    {
                        remainingAccess &= ~ACCESS_MASK_ACCESS_SYSTEM_SECURITY;
                    }
                }
            }
            if ((remainingAccess & ACCESS_MASK_WRITE_OWNER) != 0 && token.Privileges != null)
            {
                foreach (_LUID privilege in token.Privileges)
                {
                    if (ObjectUtility.DeepCompare(privilege, GetPrivilegeLuid(PrivilegeName.SE_TAKE_OWNERSHIP_NAME)))
                    {
                        remainingAccess &= ~ACCESS_MASK_WRITE_OWNER;
                    }
                }
            }
            if (securityDescriptor.OwnerSid != null
                && SidInToken(token, securityDescriptor.OwnerSid.Value, principalSelfSubstitudeSid))
            {
                remainingAccess &= ~(uint)(ACCESS_MASK_READ_CONTROL | ACCESS_MASK_WRITE_DAC);
            }

            //IF Object Tree is not NULL THEN
            //Set LocalTree to Object Tree
            //FOR each node in LocalTree DO
            //Set node.Remaining to RemainingAccess
            //END FOR
            //END IF

            if (objectTree != null && objectTree.Root != null)
            {
                localTree = (AccessCheckObjectTree)ObjectUtility.DeepClone(objectTree);
                List<Guid> tmpList = new List<Guid>();
                tmpList.Add(localTree.Root.Value);
                tmpList.AddRange(localTree.GetDescendentNodes(localTree.Root.Value));
                allNodes = tmpList.ToArray();
                foreach (Guid node in allNodes)
                {
                    localTree.SetTreeNodeData(node, remainingAccess);
                }
            }

            //FOR each ACE in DACL DO
            //IF ACE.flag does not contain INHERIT_ONLY_ACE THEN
            //CASE ACE.Type OF
            //CASE Allow Access:
            //CALL SidInToken( Token, ACE.Sid, and PrincipalSelfSubst )
            //IF SidInToken returns True THEN
            //    Remove ACE.AccessMask from RemainingAccess
            //    FOR each node in LocalTree DO
            //    Remove ACE.AccessMask from node.Remaining
            //END FOR
            //END IF
            //CASE Deny Access:
            //CALL SidInToken( Token, ACE.Sid, PrincipalSelfSubst )
            //IF SidInToken returns True THEN
            //    IF any bit of RemainingAccess is in ACE.AccessMask THEN
            //    Return access_denied
            //END IF
            //END IF
            //CASE Object Allow Access:
            //CALL SidInToken( Token, ACE.Sid, PrincipalSelfSubst )
            //IF SidInToken returns True THEN
            //    IF ACE.Object is contained in LocalTree THEN
            //    Locate node n in LocalTree such that
            //    n.GUID is the same as ACE.Object
            //    Remove ACE.AccessMask from n.Remaining
            //    FOR each node ns such that ns is a descendent of n DO
            //    Remove ACE.AccessMask from ns.Remaining
            //    END FOR
            //    FOR each node np such that np is an ancestor of n DO
            //    Set np.Remaining = np.Remaining or np-1.Remaining
            //END FOR
            //END IF
            //END IF
            //CASE Object Deny Access:
            //CALL SidInToken( Token, ACE.Sid, PrincipalSelfSubst )
            //IF SidInToken returns True THEN
            //    Locate node n in LocalTree such that
            //    n.GUID is the same as ACE.Object
            //    IF n exists THEN
            //    If any bit of n.Remaining is in ACE.AccessMask THEN
            //    Return access_denied
            //END IF
            //END IF
            //END IF
            //END CASE
            //END IF
            //END FOR

            if (dacl.Value.Aces != null)
            {
                foreach (object ace in dacl.Value.Aces)
                {
                    _ACE_HEADER header = (_ACE_HEADER)ObjectUtility.GetFieldValue(ace, "Header");
                    _SID sid = (_SID)ObjectUtility.GetFieldValue(ace, "Sid");

                    if ((header.AceFlags & ACE_FLAGS.INHERIT_ONLY_ACE) == ACE_FLAGS.INHERIT_ONLY_ACE
                        || !SidInToken(token, sid, principalSelfSubstitudeSid))
                    {
                        continue;
                    }

                    bool ret = DtypUtility.AceAccessCheck(ace, ref remainingAccess, ref localTree, allNodes);
                    if (ret == false)
                    {
                        return false;
                    }
                }
            }

            //IF RemainingAccess = 0 THEN
            //Return success
            //Else
            //Return access_denied
            //END IF

            bool status;
            if (objectTree != null && objectTree.Root != null)
            {
                status = (localTree.GetTreeNodeData(localTree.Root.Value) == 0);
            }
            else
            {
                status = (remainingAccess == 0);
            }
            return status;
        }
        /// <summary>
        /// A support function, SidInToken, takes the authorization context, 
        /// a SID (referenced below as the SidToTest parameter), and an optional 
        /// PrincipalSelfSubstitute parameter, and returns TRUE if the SidToTest 
        /// is present in the authorization context; otherwise, it returns FALSE. 
        /// The well-known SID PRINCIPAL_SELF, if passed as SidToTest, is replaced 
        /// by the PrincipalSelfSubstitute SID prior to the examination of the 
        /// authorization context. MS-DTYP section 2.5.4.1
        /// </summary>
        /// <param name="token">
        /// Token is an authorization context containing all SIDs 
        /// that represent the security principal
        /// </param>
        /// <param name="sidToTest">
        /// The SID for which to search in Token
        /// </param>
        /// <param name="principalSelfSubstitute">
        /// a SID with which SidToTest may be replaced
        /// </param>
        /// <returns>
        /// Returns TRUE if the SidToTest is present in the authorization context; 
        /// otherwise, it returns FALSE. 
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown when the well-known SID PRINCIPAL_SELF, if passed as SidToTest, but 
        /// principalSelfSubstitute does't exist.
        /// </exception>
        public static bool SidInToken(
            Token token,
            _SID sidToTest,
            _SID? principalSelfSubstitute)
        {
            //
            //Pseudocode syntax
            //
            //--
            //-- On entry
            //-- Token is an authorization context containing all SIDs
            //-- that represent the security principal
            //-- SidToTest, the SID for which to search in Token
            //-- PrincipalSelfSubstitute, a SID with which SidToTest may be
            //-- replaced
            //IF SidToTest is the Well Known SID PRINCIPAL_SELF THEN
            //set SidToTest to be PrincipalSelfSubstitute
            //END IF
            //FOR EACH SID s in Token DO
            //IF s equals SidToTest THEN
            //return TRUE
            //END IF
            //END FOR
            //Return FALSE
            //END-SUBROUTINE

            if (ObjectUtility.DeepCompare(GetWellKnownSid(WellKnownSid.PRINCIPAL_SELF, null), sidToTest))
            {
                if (principalSelfSubstitute != null)
                {
                    sidToTest = (_SID)principalSelfSubstitute;
                }
                else
                {
                    throw new ArgumentException("The principalSelfSubstitute doesn't exist", "principalSelfSubstitute");
                }
            }
            if (token.Sids != null)
            {
                foreach (_SID sid in token.Sids)
                {
                    if (ObjectUtility.DeepCompare(sid, sidToTest))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
        /// <summary>
        /// Create SecurityDescriptor in absolute format. MS-DTYP section 2.5.4.3
        /// </summary>
        /// <param name="parentDescriptor">
        /// Security descriptor for the parent (container) object of the new object. 
        /// If the object has no parent, this parameter is null.
        /// </param>
        /// <param name="creatorDescriptor">
        /// Security descriptor for the new object provided by the creator of the object. 
        /// Caller can pass null.
        /// </param>
        /// <param name="isContainerObject">
        /// TRUE when the object is a container; otherwise, FALSE.
        /// </param>
        /// <param name="objectTypes">
        /// An array of pointers to GUID structures that identify the object types or 
        /// classes of the object associated with NewDescriptor (the return value). 
        /// For Active Directory objects, this array contains pointers to the class 
        /// GUIDs of the object's structural class and all attached auxiliary classes. 
        /// If the object for which this descriptor is being created does not have a GUID, 
        /// this field MUST be set to null.
        /// </param>
        /// <param name="autoInheritFlags">
        /// A set of bit flags that control how access control entries (ACEs) are 
        /// inherited from ParentDescriptor.
        /// </param>
        /// <param name="token">
        /// Token supplied by the caller for default security information for the new object.
        /// </param>
        /// <param name="genericMapping">
        /// Mapping of generic permissions to resource manager-specific permissions 
        /// supplied by the caller.
        /// </param>
        /// <returns>
        /// Output security descriptor for the object computed by the algorithm.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// Thrown when the OwnerSid or GroupSid field of parentDescriptor is null, but
        /// autoInheritFlags is set to DEFAULT_OWNER_FROM_PARENT or DEFAULT_GROUP_FROM_PARENT.
        /// Thrown when the Dacl field of parentDescriptor doesn't exist, but the DACLPresent flag is set.
        /// Thrown when the Sacl field of parentDescriptor doesn't exist, but the SP flag is set.
        /// </exception>
        public static _SECURITY_DESCRIPTOR CreateSecurityDescriptor(
            _SECURITY_DESCRIPTOR? parentDescriptor,
            _SECURITY_DESCRIPTOR? creatorDescriptor,
            bool isContainerObject,
            Guid[] objectTypes,
            SecurityDescriptorAutoInheritFlags autoInheritFlags,
            Token token,
            GenericMapping genericMapping)
        {
            const byte DEFAULT_REVISION = 1;

            _SECURITY_DESCRIPTOR newDescriptor = new _SECURITY_DESCRIPTOR();
            newDescriptor.Revision = DEFAULT_REVISION;

            //Compute the Owner field (v20100908)

            //IF CreatorDescriptor.Owner is NULL THEN
            //IF AutoInheritFlags contains DEFAULT_OWNER_FROM_PARENT THEN
            //Set NewDescriptor.Owner to ParentDescriptor.Owner
            //ELSE
            //Set NewDescriptor.Owner to Token.SIDs[Token.OwnerIndex]
            //ENDIF
            //ELSE
            //Set NewDescriptor.Owner to CreatorDescriptor.Owner
            //ENDIF

            if (creatorDescriptor != null)
            {
                newDescriptor.OwnerSid = creatorDescriptor.Value.OwnerSid;
            }
            else if ((autoInheritFlags & SecurityDescriptorAutoInheritFlags.DEFAULT_OWNER_FROM_PARENT)
                == SecurityDescriptorAutoInheritFlags.DEFAULT_OWNER_FROM_PARENT)
            {
                if (parentDescriptor != null)
                {
                    newDescriptor.OwnerSid = parentDescriptor.Value.OwnerSid;
                }
                else
                {
                    throw new ArgumentException(
                        "The parentDescriptor doesn't exist, but DEFAULT_OWNER_FROM_PARENT flag is set.",
                        "parentDescriptor");
                }
            }
            else
            {
                newDescriptor.OwnerSid = token.Sids[token.OwnerIndex];
            }

            //Compute the Group field

            //IF CreatorDescriptor.Group is NULL THEN
            //IF AutoInheritFlags contains DEFAULT_GROUP_FROM_PARENT THEN
            //Set NewDescriptor.Group to ParentDescriptor.Group
            //ELSE
            //Set NewDescriptor.Group to Token.SIDs[Token.PrimaryGroup]
            //ENDIF
            //ELSE
            //Set NewDescriptor.Group to CreatorDescriptor.Group
            //ENDIF
            if (creatorDescriptor != null)
            {
                newDescriptor.GroupSid = creatorDescriptor.Value.GroupSid;
            }
            else if ((autoInheritFlags & SecurityDescriptorAutoInheritFlags.DEFAULT_GROUP_FROM_PARENT)
                == SecurityDescriptorAutoInheritFlags.DEFAULT_GROUP_FROM_PARENT)
            {
                if (parentDescriptor != null)
                {
                    newDescriptor.GroupSid = parentDescriptor.Value.GroupSid;
                }
                else
                {
                    throw new ArgumentException(
                        "The parentDescriptor doesn't exist, but DEFAULT_GROUP_FROM_PARENT flag is set.",
                        "parentDescriptor");
                }
            }
            else
            {
                newDescriptor.GroupSid = token.Sids[token.PrimaryGroup];
            }

            _ACL? parentDacl = null;
            _ACL? parentSacl = null;
            SECURITY_DESCRIPTOR_Control parentControl = SECURITY_DESCRIPTOR_Control.None;
            _ACL? creatorDacl = null;
            _ACL? creatorSacl = null;
            SECURITY_DESCRIPTOR_Control creatorControl = SECURITY_DESCRIPTOR_Control.None;
            #region Check Sacl or Dacl filed against SP or DACLPresent flag in the control field.

            if (parentDescriptor != null)
            {
                parentControl = parentDescriptor.Value.Control;
                if ((parentDescriptor.Value.Control & SECURITY_DESCRIPTOR_Control.DACLPresent)
                         == SECURITY_DESCRIPTOR_Control.DACLPresent)
                {
                    if (parentDescriptor.Value.Dacl == null)
                    {
                        throw new ArgumentException(
                            "The Dacl field of parentDescriptor doesn't exist, but the DACLPresent flag is set.",
                            "parentDescriptor");
                    }
                    else
                    {
                        parentDacl = parentDescriptor.Value.Dacl;
                    }
                }
                if ((parentDescriptor.Value.Control & SECURITY_DESCRIPTOR_Control.SACLPresent)
                        == SECURITY_DESCRIPTOR_Control.SACLPresent)
                {
                    if (parentDescriptor.Value.Sacl == null)
                    {
                        throw new ArgumentException(
                            "The Sacl field of parentDescriptor doesn't exist, but the SP flag is set.",
                            "parentDescriptor");
                    }
                    else
                    {
                        parentSacl = parentDescriptor.Value.Sacl;
                    }
                }
            }
            if (creatorDescriptor != null)
            {
                creatorControl = creatorDescriptor.Value.Control;
                if ((creatorDescriptor.Value.Control & SECURITY_DESCRIPTOR_Control.DACLPresent)
                        == SECURITY_DESCRIPTOR_Control.DACLPresent)
                {
                    if (creatorDescriptor.Value.Dacl == null)
                    {
                        throw new ArgumentException(
                            "The Dacl field of creatorDescriptor doesn't exist, but the DACLPresent flag is set.",
                            "creatorDescriptor");
                    }
                    else
                    {
                        creatorDacl = creatorDescriptor.Value.Dacl;
                    }
                }
                if ((creatorDescriptor.Value.Control & SECURITY_DESCRIPTOR_Control.SACLPresent)
                        == SECURITY_DESCRIPTOR_Control.SACLPresent)
                {
                    if (creatorDescriptor.Value.Sacl == null)
                    {
                        throw new ArgumentException(
                            "The Sacl field of creatorDescriptor doesn't exist, but the SP flag is set.",
                            "creatorDescriptor");
                    }
                    else
                    {
                        creatorSacl = creatorDescriptor.Value.Sacl;
                    }
                }
            }

            #endregion

            //Compute the DACL

            //CALL ComputeACL WITH
            //COMPUTE_DACL, ParentDescriptor.DACL, ParentDescriptor.Control,
            //CreatorDescriptor.DACL,CreatorDescriptor.Control
            //IsContainerObject, ObjectTypes, GenericMapping,
            //NewDescriptor.Owner, NewDescriptor.Group, Token
            //RETURNING NewDACL, NewControl
            //Set NewDescriptor.DACL to NewDACL
            //Set NewDescriptor.Control to NewControl

            SECURITY_DESCRIPTOR_Control newControl = SECURITY_DESCRIPTOR_Control.None;
            _ACL? newDacl = ComputeACL(
               AclComputeType.COMPUTE_DACL,
               parentDacl,
               parentControl,
               creatorDacl,
               creatorControl,
               isContainerObject,
               objectTypes,
               autoInheritFlags,
               genericMapping,
               newDescriptor.OwnerSid.Value,
               newDescriptor.GroupSid.Value,
               token,
               out newControl);

            newDescriptor.Dacl = newDacl;
            newDescriptor.Control = newControl;

            //Compute the SACL

            //CALL ComputeACL WITH
            //COMPUTE_SACL, ParentDescriptor.SACL, ParentDescriptor.Control,
            //CreatorDescriptor.SACL,CreatorDescriptor.Control
            //IsContainerObject, ObjectTypes, GenericMapping,
            //NewDescriptor.Owner, NewDescriptor.Group, Token
            //RETURNING NewSACL, NewControl
            //Set NewDescriptor.SACLto NewSACL
            //Set NewDescriptor.Control to (NewDescriptor.Control OR NewControl)
            //RETURN NewDescriptor

            _ACL? newSacl = ComputeACL(
                    AclComputeType.COMPUTE_SACL,
                    parentSacl,
                    parentControl,
                    creatorSacl,
                    creatorControl,
                    isContainerObject,
                    objectTypes,
                    autoInheritFlags,
                    genericMapping,
                    newDescriptor.OwnerSid.Value,
                    newDescriptor.GroupSid.Value,
                    token,
                    out newControl);

            newDescriptor.Sacl = newSacl;
            newDescriptor.Control |= newControl;

            //New SecurityDescriptor is in absolute format.
            newDescriptor.Control = newDescriptor.Control & (~SECURITY_DESCRIPTOR_Control.SelfRelative);
            return newDescriptor;
        }
        /// <summary>
        /// MandatoryIntegrityCheck. MS-DTYP section 2.5.4.1
        /// </summary>
        /// <param name="tokenIntegritySID">
        /// Mandatory Integrity SID in the Token
        /// </param>
        /// <param name="aceIntegritySID">
        /// Mandatory Integrity label SID in the Security descriptor of the object
        /// </param>
        /// <param name="mandatoryInformation">
        /// Output of the function describing the allowable bits for the caller
        /// </param>
        /// <param name="token">
        /// Authorization context
        /// </param>
        /// <param name="objectSecurityDescriptor">
        /// SECURITY_DESCRIPTOR structure that is assigned to the object
        /// </param>
        /// <returns>True if check is done successfully; otherwise, false</returns>
        public static bool MandatoryIntegrityCheck(
            _SID tokenIntegritySID,
            _SID aceIntegritySID,
            out uint mandatoryInformation,
            Token token,
            _SECURITY_DESCRIPTOR objectSecurityDescriptor)
        {
            //Set TokenPolicy to Token MandatoryPolicy field
            //Set ObjectIntegrityACE to SecurityDescriptor ObjectIntegrity ACE field
            //Set ObjectIntegrityAceMask to SecurityDescriptor ObjectIntegrity Accessmask field
            //
            //IF TokenPolicy.Policy EQUAL TOKEN_MANDATORY_POLICY_OFF OR
            //TokenPolicy.Policy EQUAL TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN THEN
            //Set MandatoryInformation.AllowedAccess to GENERIC_ALL
            //Return success
            //END IF
            //
            //IF ObjectIntegrityACE.AceFlag NOT EQUAL INHERIT_ONLY_ACE THEN
            //Set AceMask to ObjectIintegrityACE.AccessMask
            //Set AceIntegritysid to ObjectIntegrityACE.TrusteeSid
            //ELSE
            //Set AceMask to SYSTEM_MANDATORY_LABEL_NO_WRITE_UP
            //--The DefaultMandatorySid is derived from policy managed in an
            //--implementation specific manner. The SID for ML_MEDIUM is used by
            //--Windows.
            //Set AceIntegritysid to DefaultMandatorySid
            //END IF

            TokenMandatoryPolicyValue tokenPolicy = token.MandatoryPolicy;
            _SYSTEM_MANDATORY_LABEL_ACE? objectIntegrityACE = null;
            mandatoryInformation = 0;
            bool tokenDominates;

            if (tokenPolicy == TokenMandatoryPolicyValue.TOKEN_MANDATORY_POLICY_OFF
                || tokenPolicy == TokenMandatoryPolicyValue.TOKEN_MANDATORY_POLICY_NEW_PROCESS_MIN)
            {
                mandatoryInformation = ACCESS_MASK_GENERIC_ALL;
                return true;
            }

            if ((objectSecurityDescriptor.Control & SECURITY_DESCRIPTOR_Control.SACLPresent)
                    == SECURITY_DESCRIPTOR_Control.SACLPresent
                && objectSecurityDescriptor.Sacl != null)
            {
                if (objectSecurityDescriptor.Sacl.Value.Aces != null)
                {
                    foreach (object ace in objectSecurityDescriptor.Sacl.Value.Aces)
                    {
                        _SID sid = (_SID)ObjectUtility.GetFieldValue(ace, "Sid");
                        if (ObjectUtility.DeepCompare(sid, aceIntegritySID))
                        {
                            objectIntegrityACE = (_SYSTEM_MANDATORY_LABEL_ACE)ace;
                        }
                    }
                }
            }

            SYSTEM_MANDATORY_LABEL_ACE_Mask objectIntegrityAceMask;
            _SID aceIntegritySid;

            if (objectIntegrityACE != null && objectIntegrityACE.Value.Header.AceFlags != ACE_FLAGS.INHERIT_ONLY_ACE)
            {
                objectIntegrityAceMask = objectIntegrityACE.Value.Mask;
                aceIntegritySid = objectIntegrityACE.Value.Sid;
            }
            else
            {
                objectIntegrityAceMask = SYSTEM_MANDATORY_LABEL_ACE_Mask.SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
                //The DefaultMandatorySid is derived from policy managed in an
                //implementation specific manner. The SID for ML_MEDIUM is used by
                //Windows.
                aceIntegritySid = GetWellKnownSid(WellKnownSid.ML_MEDIUM, null);
            }
            //
            //Note:SidDominates is removed from the current function, because it's declared but not used.
            //
            //CALL sidEqual(AceIntegritysid, TokenIntegritysid)
            //IF AceIntegritySid EQUALS Token.MandatoryIntegritySid THEN
            //Set TokenDominates to TRUE
            //Set ObjectDominates to TRUE
            //ELSE
            //CALL SidDominates (Token.MandatoryIntegritySid, AceIntegritysid)
            //IF SidDominates returns TRUE THEN
            //Set TokenDominates to TRUE
            //ELSE
            //Set TokenDominates to FALSE
            //END IF
            //Set ObjectDominates to NOT(TokenDominates)
            //END IF

            tokenDominates = SidDominates((_SID)token.IntegrityLevelSid, aceIntegritySid);

            //IF TokenPolicy EQUAL TOKEN_MANDATORY_POLICY_NO_WRITE_UP THEN
            //Add READ to MandatoryInformation.AllowedAccess
            //Add EXECUTE to MandatoryInformation.AllowedAccess
            //IF TokenDominates is TRUE THEN
            //Add WRITE to MandatoryInformation.AllowedAccess
            //END IF
            //END IF
            //
            //IF TokenDominates is FALSE THEN
            //IF ObjectIntegrityAceMask & SYSTEM_MANDATORY_LABEL_NO_READ_UP THEN
            //Remove READ from MandatoryInformation.AllowedAccess
            //END IF
            //IF ObjectIntegrityAceMask & SYSTEM_MANDATORY_LABEL_NO_WRITE_UP THEN
            //Remove WRITE from MandatoryInformation.AllowedAccess
            //END IF
            //IF ObjectIntegrityAceMask & SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP THEN
            //Remove EXECUTE from MandatoryInformation.AllowedAccess
            //END IF
            //END IF
            //
            //IF Token.Privileges contains SeRelabelPrivilegeTHEN
            //Add WRITE_OWNER to MandatoryInformation.AllowedAccess
            //END IF

            if (tokenPolicy == TokenMandatoryPolicyValue.TOKEN_MANDATORY_POLICY_NO_WRITE_UP)
            {
                mandatoryInformation |= ACCESS_MASK_GENERIC_READ;
                mandatoryInformation |= ACCESS_MASK_GENERIC_EXECUTE;
                if (tokenDominates)
                {
                    mandatoryInformation |= ACCESS_MASK_GENERIC_WRITE;
                }
            }

            if (!tokenDominates)
            {
                if ((objectIntegrityAceMask
                    & SYSTEM_MANDATORY_LABEL_ACE_Mask.SYSTEM_MANDATORY_LABEL_NO_READ_UP)
                    == SYSTEM_MANDATORY_LABEL_ACE_Mask.SYSTEM_MANDATORY_LABEL_NO_READ_UP)
                {
                    mandatoryInformation &= ~ACCESS_MASK_GENERIC_READ;
                }
                if ((objectIntegrityAceMask
                    & SYSTEM_MANDATORY_LABEL_ACE_Mask.SYSTEM_MANDATORY_LABEL_NO_WRITE_UP)
                    == SYSTEM_MANDATORY_LABEL_ACE_Mask.SYSTEM_MANDATORY_LABEL_NO_WRITE_UP)
                {
                    mandatoryInformation &= ~ACCESS_MASK_GENERIC_WRITE;
                }
                if ((objectIntegrityAceMask
                    & SYSTEM_MANDATORY_LABEL_ACE_Mask.SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP)
                    == SYSTEM_MANDATORY_LABEL_ACE_Mask.SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP)
                {
                    mandatoryInformation &= ~ACCESS_MASK_GENERIC_EXECUTE;
                }
            }

            if (token.Privileges != null)
            {
                foreach (_LUID privilege in token.Privileges)
                {
                    if (ObjectUtility.DeepCompare(privilege, GetPrivilegeLuid(PrivilegeName.SE_RELABEL_NAME)))
                    {
                        mandatoryInformation |= ACCESS_MASK_WRITE_OWNER;
                    }
                }
            }
            return true;
        }
        /// <summary>
        /// ComputeACL. MS-DTYP section 2.5.4.4
        /// </summary>
        /// <param name="computeType">Enumeration of COMPUTE_DACL and COMPUTE_SACL.</param>
        /// <param name="parentAcl">ACL from the parent security descriptor.</param>
        /// <param name="parentControl">Control flags from the parent security descriptor.</param>
        /// <param name="creatorAcl">ACL supplied in the security descriptor by the creator.</param>
        /// <param name="creatorControl">Control flags supplied in the security descriptor by the creator.</param>
        /// <param name="isContainerObject">TRUE if the object is a container; otherwise, FALSE.</param>
        /// <param name="objectTypes">Array of GUIDs for the object type being created.</param>
        /// <param name="autoInheritFlags">
        /// A set of bit flags that control how access control entries (ACEs) are 
        /// inherited from ParentDescriptor.
        /// </param>
        /// <param name="genericMapping">
        /// Mapping of generic permissions to resource manager-specific permissions supplied by the caller.
        /// </param>
        /// <param name="owner">Owner to use in substituting the CreatorOwner SID.</param>
        /// <param name="group">Group to use in substituting the CreatorGroup SID.</param>
        /// <param name="token">Token for default values.</param>
        /// <param name="computedControl">ComputedControl</param>
        /// <returns>Computed ACL</returns>
        public static _ACL? ComputeACL(
            AclComputeType computeType,
            _ACL? parentAcl,
            SECURITY_DESCRIPTOR_Control parentControl,
            _ACL? creatorAcl,
            SECURITY_DESCRIPTOR_Control creatorControl,
            bool isContainerObject,
            Guid[] objectTypes,
            SecurityDescriptorAutoInheritFlags autoInheritFlags,
            GenericMapping genericMapping,
            _SID owner,
            _SID group,
            Token token,
            out SECURITY_DESCRIPTOR_Control computedControl)
        {
            #region Pseudocode  v20110329

            //// The details of the algorithm to merge the parent ACL and the supplied ACL.
            //// The Control flags computed are slightly different based on whether it is the
            //// ACL in the DACL or the SACL field of the descriptor.
            //// The caller specifies whether it is a DACL or a SACL using the parameter,
            //// ComputeType.
            //Set ComputedACL to NULL
            //Set ComputedControl to NULL

            //CALL ContainsInheritableACEs WITH ParentACL RETURNING ParentHasInheritableACEs

            //IF ParentHasInheritableACEs = TRUE THEN

            //    // The Parent ACL has inheritable ACEs. The Parent ACL should be used if no Creator
            //    // ACL is supplied, or if the Creator ACL was supplied AND it is a default ACL based
            //    // on object type information

            //    IF(CreatorACL is not present) OR
            //      ((CreatorACL is present) AND
            //      (AutoInheritFlags contains DEFAULT_DESCRIPTOR_FOR_OBJECT))
            //    THEN
            //        // Use only the inherited ACEs from the parent.  First compute the ACL from the
            //        // parent ACL, then clean it up by resolving the generic mappings etc.

            //        CALL ComputeInheritedACLFromParent WITH
            //          ACL set to ParentACL,
            //          IsContainerObject set to IsContainerObject,
            //          ObjectTypes set to ObjectTypes

            //        RETURNING NextACL
            //        CALL PostProcessACL WITH
            //          ACL set to NextACL,
            //          CopyFilter set to CopyInheritedAces,
            //          Owner set to Owner,
            //          Group set to Group,
            //          GenericMapping set to GenericMapping

            //        RETURNING FinalACL

            //        Set ComputedACL to FinalACL
            //        RETURN
            //    ENDIF

            //IF ((CreatorACL is present) AND
            //  (AutoInheritFlags does not contain DEFAULT_DESCRIPTOR_FOR_OBJECT))
            //THEN
            //    // Since a creator ACL is present, and we’re not defaulting the
            //    // descriptor, determine which ACEs are inherited and compute the new ACL
            //    CALL PreProcessACLFromCreator WITH
            //       ACL set to CreatorACL
            //    RETURNING PreACL

            //    CALL ComputeInheritedACLFromCreator WITH
            //       ACL set to PreACL,
            //       IsContainerObject set to IsContainerObject,
            //       ObjectTypes set to ObjectTypes
            //    RETURNING TmpACL

            //    //  Special handling for DACL types of ACLs

            //    IF (ComputeType = DACL_COMPUTE) THEN

            //        // DACL-specific operations

            //        IF (CreatorControl does not have DACL_PROTECTED flag set) AND
            //           (AutoInheritFlags contains DACL_AUTO_INHERIT)
            //        THEN

            //            //  We’re not working from a protected DACL, and we’re supposed to
            //            //  allow automatic inheritance.  Compute the inherited ACEs from
            //            //  Parent ACL this time, and append that to the ACL that we’re building

            //            CALL ComputeInheritedACLFromParent WITH
            //              ACL set to ParentACL,
            //              IsContainerObject set to IsContainerObject,
            //              ObjectTypes set to ObjectTypes
            //            RETURNING InheritedParentACL

            //            Append InheritedParentACL.ACEs to TmpACL.ACE
            //            Set DACL_AUTO_INHERITED flag in ComputedControl

            //        ENDIF

            //    ENDIF  // DACL-Specific behavior
            //    IF (ComputeType = SACL_COMPUTE) THEN

            //        // Similar to the above, perform SACL-specific operations

            //        IF (CreatorControl does not have SACL_PROTECTED flag set) AND
            //           (AutoInheritFlags contains SACL_AUTO_INHERIT flag)
            //        THEN

            //            //  We’re not working from a protected SACL, and we’re supposed to
            //            //  allow automatic inheritance.  Compute the inherited ACEs from
            //            //  Parent ACL this time, and append that to the ACL that we’re building

            //            CALL ComputeInheritedACLFromParent WITH
            //              ACL set to ParentACL,
            //              IsContainerObject set to IsContainerObject,
            //              ObjectTypes set to ObjectTypes
            //            RETURNING InheritedParentACL

            //            Append InheritedParentACL.ACEs to TmpACL.ACE
            //            Set SACL_AUTO_INHERITED flag in ComputedControl

            //        ENDIF

            //    ENDIF  // SACL-Specific behavior

            //    CALL PostProcessACL WITH
            //      ACL set to TmpACL,
            //      CopyFilter set to CopyInheritedAces,
            //      Owner set to Owner,
            //      Group set to Group,
            //      GenericMapping set to GenericMapping
            //    RETURNING ProcessedACL

            //    Set ComputedACL to ProcessedACL
            //    RETURN
            //ENDIF  // CreatorACL is present

            //ELSE // ParentACL does not contain inheritable ACEs

            //    IF CreatorACL = NULL THEN
            //        // No ACL supplied for the object
            //        IF (ComputeType = DACL_COMPUTE) THEN
            //            Set TmpACL to Token.DefaultDACL
            //        ELSE
            //            // No default for SACL; left as NULL
            //        ENDIF

            //    ELSE
            //        // Explicit ACL was supplied for the object - either default or not.
            //        // In either case, use it for the object, since there are no inherited ACEs.
            //        CALL PreProcessACLFromCreator WITH CreatorACL
            //        RETURNING TmpACL
            //    ENDIF

            //    CALL PostProcessACL WITH
            //      ACL set to TmpACL,
            //      CopyFilter set to CopyAllAces,
            //      Owner set to Owner,
            //      Group set to Group,
            //      GenericMapping set to GenericMapping

            //        RETURNING ProcessedACL
            //        Set ComputedACL to ProcessedACL

            //ENDIF
            //// END ComputeACL

            #endregion

            _ACL? computedACL = null;
            computedControl = SECURITY_DESCRIPTOR_Control.None;
            _ACL tmpAcl = new _ACL();
            _ACL preAcl = new _ACL();

            if (parentAcl != null && ContainsInheritableACEs(parentAcl.Value))
            {
                // ParentACL contains inheritable ACEs
                if ((creatorAcl == null) || ((creatorAcl != null) && (autoInheritFlags
                    & SecurityDescriptorAutoInheritFlags.DEFAULT_DESCRIPTOR_FOR_OBJECT)
                    == SecurityDescriptorAutoInheritFlags.DEFAULT_DESCRIPTOR_FOR_OBJECT))
                {
                    // Use only the inherited ACEs from the parent
                    _ACL nextAcl = ComputeInheritedACLfromParent(parentAcl.Value, isContainerObject, objectTypes);
                    _ACL finalAcl = PostProcessACL(nextAcl, CopyFilter.CopyInheritedAces, owner, group, genericMapping);
                    computedACL = finalAcl;
                }
                else
                {
                    preAcl = PreProcessACLfromCreator(creatorAcl.Value);
                    tmpAcl = ComputeInheritedACLfromCreator(preAcl, isContainerObject, objectTypes);

                    _ACL? inheritedAcl = null;
                    if ((computeType == AclComputeType.COMPUTE_DACL)
                        && (creatorControl & SECURITY_DESCRIPTOR_Control.DACLProtected)
                            == SECURITY_DESCRIPTOR_Control.None
                        && (autoInheritFlags & SecurityDescriptorAutoInheritFlags.DACL_AUTO_INHERIT)
                            == SecurityDescriptorAutoInheritFlags.DACL_AUTO_INHERIT)
                    {
                        // Compute the inherited ACEs from the parent
                        inheritedAcl = ComputeInheritedACLfromParent(
                            parentAcl.Value,
                            isContainerObject,
                            objectTypes);

                        computedControl |= SECURITY_DESCRIPTOR_Control.DACLAutoInherited;
                    }
                    else if ((computeType == AclComputeType.COMPUTE_SACL)
                        && (creatorControl & SECURITY_DESCRIPTOR_Control.SACLProtected)
                            == SECURITY_DESCRIPTOR_Control.None
                        && (autoInheritFlags & SecurityDescriptorAutoInheritFlags.SACL_AUTO_INHERIT)
                            == SecurityDescriptorAutoInheritFlags.SACL_AUTO_INHERIT)
                    {
                        // Compute the inherited ACEs from the parent
                        inheritedAcl = ComputeInheritedACLfromParent(
                            parentAcl.Value,
                            isContainerObject,
                            objectTypes);

                        computedControl |= SECURITY_DESCRIPTOR_Control.SACLAutoInherited;
                    }
                    if (inheritedAcl != null)
                    {
                        List<object> tmpAces = new List<object>();
                        tmpAces.AddRange(tmpAcl.Aces);
                        tmpAces.AddRange(inheritedAcl.Value.Aces);
                        tmpAcl.Aces = tmpAces.ToArray();
                        tmpAcl.AceCount = (ushort)tmpAcl.Aces.Length;
                        tmpAcl.AclSize = DtypUtility.CalculateAclSize(tmpAcl);
                    }

                    computedACL = PostProcessACL(tmpAcl, CopyFilter.CopyInheritedAces, owner, group, genericMapping);
                }
            }
            else
            {
                // ParentACL does not contain inheritable ACEs
                if (creatorAcl == null)
                {
                    if (computeType == AclComputeType.COMPUTE_DACL)
                    {
                        tmpAcl = token.DefaultDACL;
                    }
                    else
                    {
                        //No default for SACL;left as NULL
                        return null;
                    }
                }
                else
                {
                    // Explicit ACL was supplied for the object - either default or not.
                    // In either case, use it for the object, since there are no inherited ACEs.
                    tmpAcl = PreProcessACLfromCreator(creatorAcl.Value);
                }
                computedACL = PostProcessACL(tmpAcl, CopyFilter.CopyAllAces, owner, group, genericMapping);
            }

            if (computedACL != null)
            {
                computedControl |= ((computeType == AclComputeType.COMPUTE_DACL)
                    ? SECURITY_DESCRIPTOR_Control.DACLPresent
                    : SECURITY_DESCRIPTOR_Control.SACLPresent);
            }
            return computedACL;
        }