/// <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>
        /// PostProcessACL. MS-DTYP section 2.5.4.9
        /// </summary>
        /// <param name="acl">ACL on which to substitute SIDs.</param>
        /// <param name="copyFilter">The filter for post-processing the ACL.</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="genericMapping">
        /// Mapping of generic permissions to resource manager-specific 
        /// permissions supplied by the caller.
        /// </param>
        /// <returns>
        /// The computed ACL with the SID substitutions performed.
        /// </returns>
        public static _ACL PostProcessACL(
            _ACL acl,
            CopyFilter copyFilter,
            _SID owner,
            _SID group,
            GenericMapping genericMapping)
        {
            #region Pseudocode  v20110329

            //// Substitute CreatorOwner and CreatorGroup SIDs and do GenericMapping in ACL

            //Initialize NewACL to Empty ACL

            //FOR each ACE in ACL DO

            //    // Determine if this ACE passes the filter to be copied to the new ACL

            //    SET CopyThisAce = FALSE

            //    CASE CopyFilter OF

            //        CopyAllAces:
            //            BEGIN
            //                SET CopyThisAce = TRUE
            //            END

            //        CopyInheritedAces:
            //            BEGIN
            //                IF (ACE.AceFlags contains INHERITED_ACE) THEN
            //                    SET CopyThisAce = TRUE
            //                ENDIF
            //            END

            //        CopyExplicitAces:
            //            BEGIN
            //                IF (ACE.AceFlags does not contain INHERITED_ACE) THEN
            //                   SET CopyThisAce = TRUE
            //                ENDIF
            //            END

            //    ENDCASE

            //    Set NewACE to ACE

            //    IF (CopyThisAce) THEN

            //        CASE ACE.Sid OF

            //            CREATOR_OWNER:
            //                NewACE.Sid = Owner

            //            CREATOR_GROUP:
            //                NewACE.Sid = Group
            //        ENDCASE

            //        IF (ACE.Mask contains GENERIC_READ) THEN
            //            Add GenericMapping.GenericRead to NewACE.Mask
            //        ENDIF

            //        IF (ACE.Mask contains GENERIC_WRITE) THEN
            //            Add GenericMapping.GenericWrite to NewACE.Mask
            //        ENDIF

            //        IF (ACE.Mask contains GENERIC_EXECUTE) THEN
            //            Add GenericMapping.GenericExecute to NewACE.Mask
            //        ENDIF

            //        Append NewACE to NewACL
            //    ENDIF

            //END FOR

            //RETURN NewACL
            //// END PostProcessACL

            #endregion

            _ACL newAcl = new _ACL();
            newAcl.AclRevision = acl.AclRevision;
            newAcl.Aces = new object[] { };
            List<object> newAces = new List<object>();

            if (acl.Aces != null)
            {
                foreach (object ace in acl.Aces)
                {
                    object newAce = ObjectUtility.DeepClone(ace);
                    _ACE_HEADER header = (_ACE_HEADER)ObjectUtility.GetFieldValue(newAce, "Header");

                    bool copyThisAce = false;
                    switch (copyFilter)
                    {
                        case CopyFilter.CopyAllAces:
                            copyThisAce = true;
                            break;
                        case CopyFilter.CopyInheritedAces:
                            if ((header.AceFlags & ACE_FLAGS.INHERITED_ACE) == ACE_FLAGS.INHERITED_ACE)
                            {
                                copyThisAce = true;
                            }
                            break;
                        case CopyFilter.CopyExplicitAces:
                            if ((header.AceFlags & ACE_FLAGS.INHERITED_ACE) == ACE_FLAGS.None)
                            {
                                copyThisAce = true;
                            }
                            break;
                    }

                    if (copyThisAce)
                    {
                        #region Substitute CreatorOwner and CreatorGroup SIDs in ACL

                        _SID sid = (_SID)ObjectUtility.GetFieldValue(newAce, "Sid");
                        if (ObjectUtility.DeepCompare(sid, GetWellKnownSid(WellKnownSid.CREATOR_OWNER, null)))
                        {
                            ObjectUtility.SetFieldValue(newAce, "Sid", owner);
                            header.AceSize = (ushort)(header.AceSize
                                - (sid.SubAuthorityCount - owner.SubAuthorityCount) * sizeof(uint));
                            ObjectUtility.SetFieldValue(newAce, "Header", header);

                        }
                        else if (ObjectUtility.DeepCompare(sid, GetWellKnownSid(WellKnownSid.CREATOR_GROUP, null)))
                        {
                            ObjectUtility.SetFieldValue(newAce, "Sid", group);
                            header.AceSize = (ushort)(header.AceSize
                                - (sid.SubAuthorityCount - group.SubAuthorityCount) * sizeof(uint));
                            ObjectUtility.SetFieldValue(newAce, "Header", header);
                        }
                        #endregion

                        #region Do GenericMapping in ACL

                        uint mask = (uint)ObjectUtility.GetFieldValue(newAce, "Mask");

                        if ((mask & ACCESS_MASK_GENERIC_READ) == ACCESS_MASK_GENERIC_READ)
                        {
                            mask = mask | genericMapping.GenericRead;
                            ObjectUtility.SetFieldValue(newAce, "Mask", mask);
                        }
                        if ((mask & ACCESS_MASK_GENERIC_WRITE) == ACCESS_MASK_GENERIC_WRITE)
                        {
                            mask = mask | genericMapping.GenericWrite;
                            ObjectUtility.SetFieldValue(newAce, "Mask", mask);
                        }
                        if ((mask & ACCESS_MASK_GENERIC_EXECUTE) == ACCESS_MASK_GENERIC_EXECUTE)
                        {
                            mask = mask | genericMapping.GenericExecute;
                            ObjectUtility.SetFieldValue(newAce, "Mask", mask);
                        }
                        #endregion

                        //Append NewACE to NewACL
                        newAces.Add(newAce);
                    }
                }
            }
            newAcl.Aces = newAces.ToArray();
            newAcl.AceCount = (ushort)newAcl.Aces.Length;
            newAcl.AclSize = DtypUtility.CalculateAclSize(newAcl);

            return newAcl;
        }
        /// <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;
        }