PermissionSet.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / BCL / System / Security / PermissionSet.cs / 1305376 / PermissionSet.cs

                            // ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// [....]
// 
 
namespace System.Security {
    using System; 
    using System.Threading;
    using System.Security.Util;
    using System.Collections;
    using System.IO; 
    using System.Security.Permissions;
    using System.Runtime.CompilerServices; 
    using System.Security.Policy; 
#if FEATURE_SERIALIZATION
    using System.Runtime.Serialization.Formatters.Binary; 
#endif // FEATURE_SERIALIZATION
    using BindingFlags = System.Reflection.BindingFlags;
    using System.Runtime.Serialization;
    using System.Text; 
    using System.Globalization;
    using System.Runtime.Versioning; 
    using System.Diagnostics.Contracts; 

    [Serializable] 
    internal enum SpecialPermissionSetFlag
    {
        // These also appear in clr/src/vm/permset.h
        Regular = 0, 
        NoSet = 1,
        EmptySet = 2, 
        SkipVerification = 3 
    }
 
    [Serializable]
    [StrongNameIdentityPermissionAttribute(SecurityAction.InheritanceDemand, Name = "mscorlib", PublicKey = "0x" + AssemblyRef.EcmaPublicKeyFull)]
[System.Runtime.InteropServices.ComVisible(true)]
    public class PermissionSet : ISecurityEncodable, ICollection, IStackWalk, IDeserializationCallback 
    {
    #if _DEBUG 
        internal static readonly bool debug; 
    #endif
 
        [System.Diagnostics.Conditional( "_DEBUG" )]
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
        private static void DEBUG_WRITE(String str) { 
        #if _DEBUG
            if (debug) Console.WriteLine(str); 
        #endif 
         }
 
        [System.Diagnostics.Conditional( "_DEBUG" )]
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
        private static void DEBUG_COND_WRITE(bool exp, String str) 
        {
        #if _DEBUG 
            if (debug && (exp)) Console.WriteLine(str); 
        #endif
        } 

        [System.Diagnostics.Conditional( "_DEBUG" )]
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] 
        private static void DEBUG_PRINTSTACK(Exception e)
        { 
        #if _DEBUG 
            if (debug) Console.Error.WriteLine((e).StackTrace);
        #endif 
        }

        // These members are accessed from EE using their hardcoded offset.
        // Please update the PermissionSetObject in object.h if you make any changes 
        // to the fields here. !dumpobj will show the field layout
 
        // First the fields that are serialized x-appdomain (for perf reasons) 
        private bool m_Unrestricted;
        [OptionalField(VersionAdded = 2)] 
        private bool m_allPermissionsDecoded = false;

        [OptionalField(VersionAdded = 2)]
        internal TokenBasedSet m_permSet = null; 

        // This is a hack so that SQL can operate under default policy without actually 
        // granting permissions in assemblies that they disallow.  @ 

 
        [OptionalField(VersionAdded = 2)]
        private bool m_ignoreTypeLoadFailures = false;

        // This field will be populated only for non X-AD scenarios where we create a XML-ised string of the PermissionSet 
        [OptionalField(VersionAdded = 2)]
        private String m_serializedPermissionSet; 
 
        [NonSerialized] private bool m_CheckedForNonCas;
        [NonSerialized] private bool m_ContainsCas; 
        [NonSerialized] private bool m_ContainsNonCas;

        // only used during non X-AD serialization to save the m_permSet value (which we dont want serialized)
        [NonSerialized] private TokenBasedSet m_permSetSaved; 

        // Following 4 fields are used only for serialization compat purposes: DO NOT USE THESE EVER! 
#pragma warning disable 169 
        private bool readableonly;
        private TokenBasedSet m_unrestrictedPermSet; 
        private TokenBasedSet m_normalPermSet;

        [OptionalField(VersionAdded = 2)]
        private bool m_canUnrestrictedOverride; 
#pragma warning restore 169
        // END: Serialization-only fields 
 
        internal static readonly PermissionSet s_fullTrust = new PermissionSet( true );
 
#if FEATURE_REMOTING
        [OnDeserializing]
        private void OnDeserializing(StreamingContext ctx)
        { 
            Reset();
        } 
 
        [OnDeserialized]
        private void OnDeserialized(StreamingContext ctx) 
        {
            if (m_serializedPermissionSet != null)
            {
                // Whidbey non X-AD case 
                FromXml(SecurityElement.FromString(m_serializedPermissionSet));
            } 
            else if (m_normalPermSet != null) 
            {
                // Everett non X-AD case 
                m_permSet = m_normalPermSet.SpecialUnion(m_unrestrictedPermSet);
            }
            else if (m_unrestrictedPermSet != null)
            { 
                // Everett non X-AD case
                m_permSet = m_unrestrictedPermSet.SpecialUnion(m_normalPermSet); 
            } 

            m_serializedPermissionSet = null; 
            m_normalPermSet = null;
            m_unrestrictedPermSet = null;

        } 

        [OnSerializing] 
        private void OnSerializing(StreamingContext ctx) 
        {
 
            if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
            {
                m_serializedPermissionSet = ToString(); // For v2.x and beyond
                if (m_permSet != null) 
                    m_permSet.SpecialSplit(ref m_unrestrictedPermSet, ref m_normalPermSet, m_ignoreTypeLoadFailures);
                m_permSetSaved = m_permSet; 
                m_permSet = null; 
            }
        } 
#endif // !FEATURE_REMOTING

#if FEATURE_REMOTING || _DEBUG
        [OnSerialized] 
        private void OnSerialized(StreamingContext context)
        { 
#if FEATURE_REMOTING 
            if ((context.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
            { 
                m_serializedPermissionSet = null;
                m_permSet = m_permSetSaved;
                m_permSetSaved = null;
                m_unrestrictedPermSet = null; 
                m_normalPermSet = null;
            } 
#else // !FEATURE_REMOTING 
            Contract.Assert(false, "PermissionSet does not support serialization on CoreCLR");
#endif // !FEATURE_REMOTING 
        }
#endif // FEATURE_REMOTING || _DEBUG

        internal PermissionSet() 
        {
            Reset(); 
            m_Unrestricted = true; 
        }
 
        internal PermissionSet(bool fUnrestricted)
            : this()
        {
            SetUnrestricted(fUnrestricted); 
        }
 
        public PermissionSet(PermissionState state) 
            : this()
        { 
            if (state == PermissionState.Unrestricted)
            {
                SetUnrestricted( true );
            } 
            else if (state == PermissionState.None)
            { 
                SetUnrestricted( false ); 
            }
            else 
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionState"));
            }
        } 

        public PermissionSet(PermissionSet permSet) 
            : this() 
        {
            if (permSet == null) 
            {
                Reset();
                return;
            } 

            m_Unrestricted = permSet.m_Unrestricted; 
            m_CheckedForNonCas = permSet.m_CheckedForNonCas; 
            m_ContainsCas = permSet.m_ContainsCas;
            m_ContainsNonCas = permSet.m_ContainsNonCas; 
            m_ignoreTypeLoadFailures = permSet.m_ignoreTypeLoadFailures;

            if (permSet.m_permSet != null)
            { 
                m_permSet = new TokenBasedSet(permSet.m_permSet);
 
                // now deep copy all permissions in set 
                for (int i = m_permSet.GetStartingIndex(); i <= m_permSet.GetMaxUsedIndex(); i++)
                { 
                    Object obj = m_permSet.GetItem(i);
                    IPermission perm = obj as IPermission;
#if FEATURE_CAS_POLICY
                    ISecurityElementFactory elem = obj as ISecurityElementFactory; 
#endif // FEATURE_CAS_POLICY
                    if (perm != null) 
                    { 
                        m_permSet.SetItem(i, perm.Copy());
                    } 
#if FEATURE_CAS_POLICY
                    else if (elem != null)
                    {
                        m_permSet.SetItem(i, elem.Copy()); 
                    }
#endif // FEATURE_CAS_POLICY 
                } 
            }
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        public virtual void CopyTo(Array array, int index)
        { 
            if (array == null)
                throw new ArgumentNullException( "array" ); 
            Contract.EndContractBlock(); 

            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this); 

            while (enumerator.MoveNext())
            {
                array.SetValue(enumerator.Current , index++ ); 
            }
        } 
 

        // private constructor that doesn't create any token based sets 
        private PermissionSet( Object trash, Object junk )
        {
            m_Unrestricted = false;
        } 

 
        // Returns an object appropriate for synchronizing access to this 
        // Array.
        public virtual Object SyncRoot 
        {  get { return this; } }

        // Is this Array synchronized (i.e., thread-safe)?  If you want a synchronized
        // collection, you can use SyncRoot as an object to synchronize your 
        // collection with.  You could also call GetSynchronized()
        // to get a synchronized wrapper around the Array. 
        public virtual bool IsSynchronized 
        {  get { return false; } }
 
        // Is this Collection ReadOnly?
        public virtual bool IsReadOnly
        {  get {return false; } }
 
        // Reinitializes all state in PermissionSet - DO NOT null-out m_serializedPermissionSet
        internal void Reset() 
        { 
            m_Unrestricted = false;
            m_allPermissionsDecoded = true; 
            m_permSet = null;

            m_ignoreTypeLoadFailures = false;
 
            m_CheckedForNonCas = false;
            m_ContainsCas = false; 
            m_ContainsNonCas = false; 
            m_permSetSaved = null;
 

        }

        internal void CheckSet() 
        {
            if (this.m_permSet == null) 
                this.m_permSet = new TokenBasedSet(); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public bool IsEmpty()
        {
            if (m_Unrestricted) 
                return false;
 
            if (m_permSet == null || m_permSet.FastIsEmpty()) 
                return true;
 
            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);

            while (enumerator.MoveNext())
            { 
                IPermission perm = (IPermission)enumerator.Current;
 
                if (!perm.IsSubsetOf( null )) 
                {
                    return false; 
                }
            }

            return true; 
        }
 
        internal bool FastIsEmpty() 
        {
            if (m_Unrestricted) 
                return false;

            if (m_permSet == null || m_permSet.FastIsEmpty())
                return true; 

            return false; 
        } 

        public virtual int Count 
        {
            get
            {
                int count = 0; 

                if (m_permSet != null) 
                    count += m_permSet.GetCount(); 

                return count; 
            }
        }

        internal IPermission GetPermission(int index) 
        {
            if (m_permSet == null) 
                return null; 
            Object obj = m_permSet.GetItem( index );
            if (obj == null) 
                return null;
            IPermission perm = obj as IPermission;
            if (perm != null)
                return perm; 
#if FEATURE_CAS_POLICY
            perm = CreatePermission(obj, index); 
#endif // FEATURE_CAS_POLICY 
            if (perm == null)
                return null; 
            Contract.Assert( PermissionToken.IsTokenProperlyAssigned( perm, PermissionToken.GetToken( perm ) ),
                             "PermissionToken was improperly assigned" );
            Contract.Assert( PermissionToken.GetToken( perm ).m_index == index,
                             "Assigning permission to incorrect index in tokenbasedset" ); 
            return perm;
        } 
 
        internal IPermission GetPermission(PermissionToken permToken)
        { 
            if (permToken == null)
                return null;

            return GetPermission( permToken.m_index ); 
        }
 
        internal IPermission GetPermission( IPermission perm ) 
        {
            if (perm == null) 
                return null;

            return GetPermission(PermissionToken.GetToken( perm ));
        } 

#if FEATURE_CAS_POLICY 
        public IPermission GetPermission(Type permClass) 
        {
            return GetPermissionImpl(permClass); 
        }

        protected virtual IPermission GetPermissionImpl(Type permClass)
        { 
            if (permClass == null)
                return null; 
 
            return GetPermission(PermissionToken.FindToken(permClass));
        } 
#endif // FEATURE_CAS_POLICY

        public IPermission SetPermission(IPermission perm)
        { 
            return SetPermissionImpl(perm);
        } 
 
        // SetPermission overwrites a permission in a permissionset.
        protected virtual IPermission SetPermissionImpl(IPermission perm) 
        {
            // can't get token if perm is null
            if (perm == null)
                return null; 

            PermissionToken permToken = PermissionToken.GetToken(perm); 
 
            if ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0)
            { 
                // SetPermission Makes the Permission "Restricted"
                m_Unrestricted = false;
            }
 
            CheckSet();
 
            IPermission currPerm = GetPermission( permToken.m_index ); 

            m_CheckedForNonCas = false; 

            // Should we copy here?
            m_permSet.SetItem( permToken.m_index, perm );
            return perm; 
        }
 
        public IPermission AddPermission(IPermission perm) 
        {
            return AddPermissionImpl(perm); 
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        protected virtual IPermission AddPermissionImpl(IPermission perm) 
        {
            // can't get token if perm is null 
            if (perm == null) 
                return null;
 
            m_CheckedForNonCas = false;

            // If the permission set is unrestricted, then return an unrestricted instance
            // of perm. 

            PermissionToken permToken = PermissionToken.GetToken(perm); 
 
            if (this.IsUnrestricted() && ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0))
            { 
                Type perm_type = perm.GetType();
                Object[] objs = new Object[1];
                objs[0] = PermissionState.Unrestricted;
                return (IPermission) Activator.CreateInstance(perm_type, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, objs, null ); 
            }
 
            CheckSet(); 
            IPermission currPerm = GetPermission(permToken.m_index);
 
            // If a Permission exists in this slot, then union it with perm
            // Otherwise, just add perm.

            if (currPerm != null) { 
                IPermission ip_union = currPerm.Union(perm);
                m_permSet.SetItem( permToken.m_index, ip_union ); 
                return ip_union; 
            } else {
                // Should we copy here? 
                m_permSet.SetItem( permToken.m_index, perm );
                return perm;
            }
 
        }
 
        private IPermission RemovePermission( int index ) 
        {
            IPermission perm = GetPermission(index); 
            if (perm == null)
                return null;
            return (IPermission)m_permSet.RemoveItem( index ); // this cast is safe because the call to GetPermission will guarantee it is an IPermission
        } 

#if FEATURE_CAS_POLICY 
        public IPermission RemovePermission(Type permClass) 
        {
            return RemovePermissionImpl(permClass); 
        }

        protected virtual IPermission RemovePermissionImpl(Type permClass)
        { 
            if (permClass == null)
            { 
                return null; 
            }
 
            PermissionToken permToken = PermissionToken.FindToken(permClass);
            if (permToken == null)
            {
                return null; 
            }
 
            return RemovePermission(permToken.m_index); 
        }
#endif // FEATURE_CAS_POLICY 

        // Make this internal soon.
        internal void SetUnrestricted(bool unrestricted)
        { 
            m_Unrestricted = unrestricted;
            if (unrestricted) 
            { 
                // if this is to be an unrestricted permset, null the m_permSet member
                m_permSet = null; 
            }
        }

        public bool IsUnrestricted() 
        {
            return m_Unrestricted; 
        } 

        internal enum IsSubsetOfType 
        {
            Normal,
            CheckDemand,
            CheckPermitOnly, 
            CheckAssertion,
        } 
 
        internal bool IsSubsetOfHelper(PermissionSet target, IsSubsetOfType type, out IPermission firstPermThatFailed, bool ignoreNonCas)
        { 
    #if _DEBUG
            if (debug)
                DEBUG_WRITE("IsSubsetOf\n" +
                            "Other:\n" + 
                            (target == null ? "" : target.ToString()) +
                            "\nMe:\n" + 
                            ToString()); 
    #endif
 
            firstPermThatFailed = null;
            if (target == null || target.FastIsEmpty())
            {
                if(this.IsEmpty()) 
                    return true;
                else 
                { 
                    firstPermThatFailed = GetFirstPerm();
                    return false; 
                }
            }
            else if (this.IsUnrestricted() && !target.IsUnrestricted())
                return false; 
            else if (this.m_permSet == null)
                return true; 
            else 
            {
                target.CheckSet(); 

                for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i)
                {
                    IPermission thisPerm = this.GetPermission(i); 
                    if (thisPerm == null || thisPerm.IsSubsetOf(null))
                        continue; 
 
                    IPermission targetPerm = target.GetPermission(i);
#if _DEBUG 
                    PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
                    Contract.Assert(targetPerm == null || (token.m_type & PermissionTokenType.DontKnow) == 0, "Token not properly initialized");
#endif
 
                    if (target.m_Unrestricted)
                        continue; 
 
                    // targetPerm can be null here, but that is fine since it thisPerm is a subset
                    // of empty/null then we can continue in the loop. 
                    CodeAccessPermission cap = thisPerm as CodeAccessPermission;
                    if(cap == null)
                    {
                        if (!ignoreNonCas && !thisPerm.IsSubsetOf( targetPerm )) 
                        {
                            firstPermThatFailed = thisPerm; 
                            return false; 
                        }
                    } 
                    else
                    {
                        firstPermThatFailed = thisPerm;
                        switch(type) 
                        {
                        case IsSubsetOfType.Normal: 
                            if (!thisPerm.IsSubsetOf( targetPerm )) 
                                return false;
                            break; 
                        case IsSubsetOfType.CheckDemand:
                            if (!cap.CheckDemand( (CodeAccessPermission)targetPerm ))
                                return false;
                            break; 
                        case IsSubsetOfType.CheckPermitOnly:
                            if (!cap.CheckPermitOnly( (CodeAccessPermission)targetPerm )) 
                                return false; 
                            break;
                        case IsSubsetOfType.CheckAssertion: 
                            if (!cap.CheckAssert( (CodeAccessPermission)targetPerm ))
                                return false;
                            break;
                        } 
                        firstPermThatFailed = null;
                    } 
                } 
            }
 
            return true;
        }

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public bool IsSubsetOf(PermissionSet target)
        { 
            IPermission perm; 
            return IsSubsetOfHelper(target, IsSubsetOfType.Normal, out perm, false);
        } 

        internal bool CheckDemand(PermissionSet target, out IPermission firstPermThatFailed)
        {
            return IsSubsetOfHelper(target, IsSubsetOfType.CheckDemand, out firstPermThatFailed, true); 
        }
 
        internal bool CheckPermitOnly(PermissionSet target, out IPermission firstPermThatFailed) 
        {
            return IsSubsetOfHelper(target, IsSubsetOfType.CheckPermitOnly, out firstPermThatFailed, true); 
        }

        internal bool CheckAssertion(PermissionSet target)
        { 
            IPermission perm;
            return IsSubsetOfHelper(target, IsSubsetOfType.CheckAssertion, out perm, true); 
        } 

        internal bool CheckDeny(PermissionSet deniedSet, out IPermission firstPermThatFailed) 
        {
            firstPermThatFailed = null;
            if (deniedSet == null || deniedSet.FastIsEmpty() || this.FastIsEmpty())
                return true; 

            if(this.m_Unrestricted && deniedSet.m_Unrestricted) 
                return false; 

            CodeAccessPermission permThis, permThat; 
            PermissionSetEnumeratorInternal enumThis = new PermissionSetEnumeratorInternal(this);

            while (enumThis.MoveNext())
            { 
                permThis = enumThis.Current as CodeAccessPermission;
                if(permThis == null || permThis.IsSubsetOf(null)) 
                    continue; // ignore non-CAS permissions in the grant set. 
                if (deniedSet.m_Unrestricted)
                { 
                    firstPermThatFailed = permThis;
                    return false;
                }
                permThat = (CodeAccessPermission)deniedSet.GetPermission(enumThis.GetCurrentIndex()); 
                if (!permThis.CheckDeny(permThat))
                { 
                    firstPermThatFailed = permThis; 
                    return false;
                } 
            }
            if(this.m_Unrestricted)
            {
                PermissionSetEnumeratorInternal enumThat = new PermissionSetEnumeratorInternal(deniedSet); 
                while (enumThat.MoveNext())
                { 
                    if(enumThat.Current is IPermission) 
                        return false;
                } 
            }
            return true;
        }
 
        internal void CheckDecoded( CodeAccessPermission demandedPerm, PermissionToken tokenDemandedPerm )
        { 
            Contract.Assert( demandedPerm != null, "Expected non-null value" ); 

            if (this.m_allPermissionsDecoded || this.m_permSet == null) 
                return;

            if (tokenDemandedPerm == null)
                tokenDemandedPerm = PermissionToken.GetToken( demandedPerm ); 

            Contract.Assert( tokenDemandedPerm != null, "Unable to find token for demanded permission" ); 
 
            CheckDecoded( tokenDemandedPerm.m_index );
        } 

        internal void CheckDecoded( int index )
        {
            if (this.m_allPermissionsDecoded || this.m_permSet == null) 
                return;
 
            GetPermission(index); 
        }
 
        internal void CheckDecoded(PermissionSet demandedSet)
        {
            Contract.Assert(demandedSet != null, "Expected non-null value");
 
            if (this.m_allPermissionsDecoded || this.m_permSet == null)
                return; 
 
            PermissionSetEnumeratorInternal enumerator = demandedSet.GetEnumeratorInternal();
 
            while (enumerator.MoveNext())
            {
                CheckDecoded(enumerator.GetCurrentIndex());
            } 
        }
 
#if FEATURE_CAS_POLICY 
        static internal void SafeChildAdd( SecurityElement parent, ISecurityElementFactory child, bool copy )
        { 
            if (child == parent)
                return;
            if (child.GetTag().Equals( "IPermission" ) || child.GetTag().Equals( "Permission" ))
            { 
                parent.AddChild( child );
            } 
            else if (parent.Tag.Equals( child.GetTag() )) 
            {
                Contract.Assert( child is SecurityElement, "SecurityElement expected" ); 
                SecurityElement elChild = (SecurityElement)child;
                Contract.Assert( elChild.InternalChildren != null,
                    "Non-permission elements should have children" );
 
                for (int i = 0; i < elChild.InternalChildren.Count; ++i)
                { 
                    ISecurityElementFactory current = (ISecurityElementFactory)elChild.InternalChildren[i]; 
                    Contract.Assert( !current.GetTag().Equals( parent.Tag ),
                        "Illegal to insert a like-typed element" ); 
                    parent.AddChildNoDuplicates( current );
                }
            }
            else 
            {
                parent.AddChild( (ISecurityElementFactory)(copy ? child.Copy() : child) ); 
            } 
        }
#endif // FEATURE_CAS_POLICY 

        internal void InplaceIntersect( PermissionSet other )
        {
            Exception savedException = null; 

            m_CheckedForNonCas = false; 
 
            if (this == other)
                return; 

            if (other == null || other.FastIsEmpty())
            {
                // If the other is empty or null, make this empty. 
                Reset();
                return; 
            } 

            if (this.FastIsEmpty()) 
                return;

            int maxMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex();
            int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex(); 

            if (this.IsUnrestricted() && maxMax < otherMax) 
            { 
                maxMax = otherMax;
                this.CheckSet(); 
            }

            if (other.IsUnrestricted())
            { 
                other.CheckSet();
            } 
 
            for (int i = 0; i <= maxMax; ++i)
            { 
                Object thisObj = this.m_permSet.GetItem( i );
                IPermission thisPerm = thisObj as IPermission;
#if FEATURE_CAS_POLICY
                ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory; 
#endif // FEATURE_CAS_POLICY
 
                Object otherObj = other.m_permSet.GetItem( i ); 
                IPermission otherPerm = otherObj as IPermission;
#if FEATURE_CAS_POLICY 
                ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY

                if (thisObj == null && otherObj == null) 
                    continue;
 
#if FEATURE_CAS_POLICY 
                if (thisElem != null && otherElem != null)
                { 
                    // If we already have an intersection node, just add another child
                    if (thisElem.GetTag().Equals( s_str_PermissionIntersection ) ||
                        thisElem.GetTag().Equals( s_str_PermissionUnrestrictedIntersection ))
                    { 
                        Contract.Assert( thisElem is SecurityElement, "SecurityElement expected" );
                        SafeChildAdd( (SecurityElement)thisElem, otherElem, true ); 
                    } 
                    // If either set is unrestricted, intersect the nodes unrestricted
                    else 
                    {
                        bool copyOther = true;
                        if (this.IsUnrestricted())
                        { 
                            SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
                            newElemUU.AddAttribute( "class", thisElem.Attribute( "class" ) ); 
                            SafeChildAdd( newElemUU, thisElem, false ); 
                            thisElem = newElemUU;
                        } 
                        if (other.IsUnrestricted())
                        {
                            SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
                            newElemUU.AddAttribute( "class", otherElem.Attribute( "class" ) ); 
                            SafeChildAdd( newElemUU, otherElem, true );
                            otherElem = newElemUU; 
                            copyOther = false; 
                        }
 
                        SecurityElement newElem = new SecurityElement( s_str_PermissionIntersection );
                        newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );

                        SafeChildAdd( newElem, thisElem, false ); 
                        SafeChildAdd( newElem, otherElem, copyOther );
                        this.m_permSet.SetItem( i, newElem ); 
                    } 
                }
                else 
#endif // FEATURE_CAS_POLICY
                if (thisObj == null)
                {
                    // There is no object in , so intersection is empty except for IUnrestrictedPermissions 
                    if (this.IsUnrestricted())
                    { 
#if FEATURE_CAS_POLICY 
                        if (otherElem != null)
                        { 
                            SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
                            newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
                            SafeChildAdd( newElem, otherElem, true );
                            this.m_permSet.SetItem( i, newElem ); 
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                        } 
                        else 
#endif // FEATURE_CAS_POLICY
                        { 
                            PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
                            if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
                            {
                                this.m_permSet.SetItem( i, otherPerm.Copy() ); 
                                Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                            } 
                        } 
                    }
                } 
                else if (otherObj == null)
                {
                    if (other.IsUnrestricted())
                    { 
#if FEATURE_CAS_POLICY
                        if (thisElem != null) 
                        { 
                            SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
                            newElem.AddAttribute( "class", thisElem.Attribute( "class" ) ); 
                            SafeChildAdd( newElem, thisElem, false );
                            this.m_permSet.SetItem( i, newElem );
                        }
                        else 
#endif // FEATURE_CAS_POLICY
                        { 
                            PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); 
                            if ((token.m_type & PermissionTokenType.IUnrestricted) == 0)
                                this.m_permSet.SetItem( i, null ); 
                        }
                    }
                    else
                    { 
                        this.m_permSet.SetItem( i, null );
                    } 
                } 
                else
                { 
#if FEATURE_CAS_POLICY
                    if (thisElem != null)
                        thisPerm = this.CreatePermission(thisElem, i);
                    if (otherElem != null) 
                        otherPerm = other.CreatePermission(otherElem, i);
#endif // FEATURE_CAS_POLICY 
 
                    try
                    { 
                        IPermission intersectPerm;
                        if (thisPerm == null)
                            intersectPerm = otherPerm;
                        else if(otherPerm == null) 
                            intersectPerm = thisPerm;
                        else 
                            intersectPerm = thisPerm.Intersect( otherPerm ); 
                        this.m_permSet.SetItem( i, intersectPerm );
                    } 
                    catch (Exception e)
                    {
                        if (savedException == null)
                            savedException = e; 
                    }
                } 
            } 

            this.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted; 

            if (savedException != null)
                throw savedException;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public PermissionSet Intersect(PermissionSet other) 
        {
            if (other == null || other.FastIsEmpty() || this.FastIsEmpty()) 
            {
                return null;
            }
 
            int thisMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex();
            int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex(); 
            int minMax = thisMax < otherMax ? thisMax : otherMax; 

            if (this.IsUnrestricted() && minMax < otherMax) 
            {
                minMax = otherMax;
                this.CheckSet();
            } 

            if (other.IsUnrestricted() && minMax < thisMax) 
            { 
                minMax = thisMax;
                other.CheckSet(); 
            }

            PermissionSet pset = new PermissionSet( false );
 
            if (minMax > -1)
            { 
                pset.m_permSet = new TokenBasedSet(); 
            }
 
            for (int i = 0; i <= minMax; ++i)
            {
                Object thisObj = this.m_permSet.GetItem( i );
                IPermission thisPerm = thisObj as IPermission; 
#if FEATURE_CAS_POLICY
                ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory; 
#endif // FEATURE_CAS_POLICY 

                Object otherObj = other.m_permSet.GetItem( i ); 
                IPermission otherPerm = otherObj as IPermission;
#if FEATURE_CAS_POLICY
                ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY 

                if (thisObj == null && otherObj == null) 
                    continue; 

#if FEATURE_CAS_POLICY 
                if (thisElem != null && otherElem != null)
                {
                    bool copyOther = true;
                    bool copyThis = true; 
                    SecurityElement newElem = new SecurityElement( s_str_PermissionIntersection );
                    newElem.AddAttribute( "class", otherElem.Attribute( "class" ) ); 
                    if (this.IsUnrestricted()) 
                    {
                        SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion ); 
                        newElemUU.AddAttribute( "class", thisElem.Attribute( "class" ) );
                        SafeChildAdd( newElemUU, thisElem, true );
                        copyThis = false;
                        thisElem = newElemUU; 
                    }
                    if (other.IsUnrestricted()) 
                    { 
                        SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
                        newElemUU.AddAttribute( "class", otherElem.Attribute( "class" ) ); 
                        SafeChildAdd( newElemUU, otherElem, true );
                        copyOther = false;
                        otherElem = newElemUU;
                    } 

                    SafeChildAdd( newElem, otherElem, copyOther ); 
                    SafeChildAdd( newElem, thisElem, copyThis ); 
                    pset.m_permSet.SetItem( i, newElem );
                } 
                else
#endif // FEATURE_CAS_POLICY
                if (thisObj == null)
                { 
                    if (this.m_Unrestricted)
                    { 
#if FEATURE_CAS_POLICY 
                        if (otherElem != null)
                        { 
                            SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
                            newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
                            SafeChildAdd( newElem, otherElem, true );
                            pset.m_permSet.SetItem( i, newElem ); 
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                        } 
                        else 
#endif // FEATURE_CAS_POLICY
                        if (otherPerm != null) 
                        {
                            PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
                            if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
                            { 
                                pset.m_permSet.SetItem( i, otherPerm.Copy() );
                                Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); 
                            } 
                        }
                    } 
                }
                else if (otherObj == null)
                {
                    if (other.m_Unrestricted) 
                    {
#if FEATURE_CAS_POLICY 
                        if (thisElem != null) 
                        {
                            SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection ); 
                            newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
                            SafeChildAdd( newElem, thisElem, true );
                            pset.m_permSet.SetItem( i, newElem );
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); 
                        }
                        else 
#endif // FEATURE_CAS_POLICY 
                        if (thisPerm != null)
                        { 
                            PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
                            if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
                            {
                                pset.m_permSet.SetItem( i, thisPerm.Copy() ); 
                                Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                            } 
                        } 
                    }
                } 
                else
                {
#if FEATURE_CAS_POLICY
                    if (thisElem != null) 
                        thisPerm = this.CreatePermission(thisElem, i);
                    if (otherElem != null) 
                        otherPerm = other.CreatePermission(otherElem, i); 
#endif // FEATURE_CAS_POLICY
 
                    IPermission intersectPerm;
                    if (thisPerm == null)
                        intersectPerm = otherPerm;
                    else if(otherPerm == null) 
                        intersectPerm = thisPerm;
                    else 
                        intersectPerm = thisPerm.Intersect( otherPerm ); 
                    pset.m_permSet.SetItem( i, intersectPerm );
                    Contract.Assert( intersectPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); 
                }
            }

            pset.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted; 
            if (pset.FastIsEmpty())
                return null; 
            else 
                return pset;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        internal void InplaceUnion( PermissionSet other )
        { 
            // Unions the "other" PermissionSet into this one.  It can be optimized to do less copies than
            // need be done by the traditional union (and we don't have to create a new PermissionSet). 
 
            if (this == other)
                return; 

            // Quick out conditions, union doesn't change this PermissionSet
            if (other == null || other.FastIsEmpty())
                return; 

 
            m_CheckedForNonCas = false; 

 


            this.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
 
            if (this.m_Unrestricted)
            { 
                // if the result of Union is unrestricted permset, null the m_permSet member 
                this.m_permSet = null;
                return; 
            }


            // If we reach here, result of Union is not unrestricted 
            // We have to union "normal" permission no matter what now.
            int maxMax = -1; 
            if (other.m_permSet != null) 
            {
                maxMax = other.m_permSet.GetMaxUsedIndex(); 
                this.CheckSet();
            }
            // Save exceptions until the end
            Exception savedException = null; 

            for (int i = 0; i <= maxMax; ++i) 
            { 
                Object thisObj = this.m_permSet.GetItem( i );
                IPermission thisPerm = thisObj as IPermission; 
#if FEATURE_CAS_POLICY
                ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY
 
                Object otherObj = other.m_permSet.GetItem( i );
                IPermission otherPerm = otherObj as IPermission; 
#if FEATURE_CAS_POLICY 
                ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY 

                if (thisObj == null && otherObj == null)
                    continue;
 
#if FEATURE_CAS_POLICY
                if (thisElem != null && otherElem != null) 
                { 
                    if (thisElem.GetTag().Equals( s_str_PermissionUnion ) ||
                        thisElem.GetTag().Equals( s_str_PermissionUnrestrictedUnion )) 
                    {
                        Contract.Assert( thisElem is SecurityElement, "SecurityElement expected" );
                        SafeChildAdd( (SecurityElement)thisElem, otherElem, true );
                    } 
                    else
                    { 
                        SecurityElement newElem; 
                        if (this.IsUnrestricted() || other.IsUnrestricted())
                            newElem = new SecurityElement( s_str_PermissionUnrestrictedUnion ); 
                        else
                            newElem = new SecurityElement( s_str_PermissionUnion );
                        newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
                        SafeChildAdd( newElem, thisElem, false ); 
                        SafeChildAdd( newElem, otherElem, true );
                        this.m_permSet.SetItem( i, newElem ); 
                    } 
                }
                else 
#endif // FEATURE_CAS_POLICY
                if (thisObj == null)
                {
#if FEATURE_CAS_POLICY 
                    if (otherElem != null)
                    { 
                        this.m_permSet.SetItem( i, otherElem.Copy() ); 
                    }
                    else 
#endif // FEATURE_CAS_POLICY
                    if (otherPerm != null)
                    {
                        PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); 
                        if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !this.m_Unrestricted)
                        { 
                            this.m_permSet.SetItem( i, otherPerm.Copy() ); 
                        }
                    } 
                }
                else if (otherObj == null)
                {
                    continue; 
                }
                else 
                { 
#if FEATURE_CAS_POLICY
                    if (thisElem != null) 
                        thisPerm = this.CreatePermission(thisElem, i);
                    if (otherElem != null)
                        otherPerm = other.CreatePermission(otherElem, i);
#endif // FEATURE_CAS_POLICY 

                    try 
                    { 
                        IPermission unionPerm;
                        if(thisPerm == null) 
                            unionPerm = otherPerm;
                        else if(otherPerm == null)
                            unionPerm = thisPerm;
                        else 
                            unionPerm = thisPerm.Union( otherPerm );
                        this.m_permSet.SetItem( i, unionPerm ); 
                    } 
                    catch (Exception e)
                    { 
                        if (savedException == null)
                            savedException = e;
                    }
                } 
            }
 
            if (savedException != null) 
                throw savedException;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        public PermissionSet Union(PermissionSet other)
        { 
            // if other is null or empty, return a clone of myself
            if (other == null || other.FastIsEmpty()) 
            { 
                return this.Copy();
            } 

            if (this.FastIsEmpty())
            {
                return other.Copy(); 
            }
 
            int maxMax = -1; 

            PermissionSet pset = new PermissionSet(); 
            pset.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
            if (pset.m_Unrestricted)
            {
                // if the result of Union is unrestricted permset, just return 
                return pset;
            } 
 
            // degenerate case where we look at both this.m_permSet and other.m_permSet
            this.CheckSet(); 
            other.CheckSet();
            maxMax = this.m_permSet.GetMaxUsedIndex() > other.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : other.m_permSet.GetMaxUsedIndex();
            pset.m_permSet = new TokenBasedSet();
 

 
            for (int i = 0; i <= maxMax; ++i) 
            {
                Object thisObj = this.m_permSet.GetItem( i ); 
                IPermission thisPerm = thisObj as IPermission;
#if FEATURE_CAS_POLICY
                ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY 

                Object otherObj = other.m_permSet.GetItem( i ); 
                IPermission otherPerm = otherObj as IPermission; 
#if FEATURE_CAS_POLICY
                ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory; 
#endif // FEATURE_CAS_POLICY

                if (thisObj == null && otherObj == null)
                    continue; 

#if FEATURE_CAS_POLICY 
                if (thisElem != null && otherElem != null) 
                {
                    SecurityElement newElem; 
                    if (this.IsUnrestricted() || other.IsUnrestricted())
                        newElem = new SecurityElement( s_str_PermissionUnrestrictedUnion );
                    else
                        newElem = new SecurityElement( s_str_PermissionUnion ); 
                    newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
                    SafeChildAdd( newElem, thisElem, true ); 
                    SafeChildAdd( newElem, otherElem, true ); 
                    pset.m_permSet.SetItem( i, newElem );
                } 
                else
#endif // FEATURE_CAS_POLICY
                if (thisObj == null)
                { 
#if FEATURE_CAS_POLICY
                    if (otherElem != null) 
                    { 
                        pset.m_permSet.SetItem( i, otherElem.Copy() );
                        Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); 
                    }
                    else
#endif // FEATURE_CAS_POLICY
                    if (otherPerm != null) 
                    {
                        PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); 
                        if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted) 
                        {
                            pset.m_permSet.SetItem( i, otherPerm.Copy() ); 
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                        }
                    }
                } 
                else if (otherObj == null)
                { 
#if FEATURE_CAS_POLICY 
                    if (thisElem != null)
                    { 
                        pset.m_permSet.SetItem( i, thisElem.Copy() );
                    }
                    else
#endif // FEATURE_CAS_POLICY 
                    if (thisPerm != null)
                    { 
                        PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); 
                        if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted)
                        { 
                            pset.m_permSet.SetItem( i, thisPerm.Copy() );
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                        }
                    } 
                }
                else 
                { 
#if FEATURE_CAS_POLICY
                    if (thisElem != null) 
                        thisPerm = this.CreatePermission(thisElem, i);
                    if (otherElem != null)
                        otherPerm = other.CreatePermission(otherElem, i);
#endif // FEATURE_CAS_POLICY 

                    IPermission unionPerm; 
                    if(thisPerm == null) 
                        unionPerm = otherPerm;
                    else if(otherPerm == null) 
                        unionPerm = thisPerm;
                    else
                        unionPerm = thisPerm.Union( otherPerm );
                    pset.m_permSet.SetItem( i, unionPerm ); 
                    Contract.Assert( unionPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                } 
            } 

            return pset; 
        }

        // Treating the current permission set as a grant set, and the input set as
        // a set of permissions to be denied, try to cancel out as many permissions 
        // from both sets as possible. For a first cut, any granted permission that
        // is a safe subset of the corresponding denied permission can result in 
        // that permission being removed from both sides. 

        internal void MergeDeniedSet(PermissionSet denied) 
        {
            if (denied == null || denied.FastIsEmpty() || this.FastIsEmpty())
                return;
 
            m_CheckedForNonCas = false;
 
            // Check for the unrestricted case: FastIsEmpty() will return false if the PSet is unrestricted, but has no items 
            if (this.m_permSet == null || denied.m_permSet == null)
                return; //nothing can be removed 

            int maxIndex = denied.m_permSet.GetMaxUsedIndex() > this.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : denied.m_permSet.GetMaxUsedIndex();
            for (int i = 0; i <= maxIndex; ++i) {
                IPermission deniedPerm = denied.m_permSet.GetItem(i) as IPermission; 
                if (deniedPerm == null)
                    continue; 
 
                IPermission thisPerm = this.m_permSet.GetItem(i) as IPermission;
 
                if (thisPerm == null && !this.m_Unrestricted) {
                    denied.m_permSet.SetItem(i, null);
                    continue;
                } 

                if (thisPerm != null && deniedPerm != null) { 
                    if (thisPerm.IsSubsetOf(deniedPerm)) { 
                        this.m_permSet.SetItem(i, null);
                        denied.m_permSet.SetItem(i, null); 
                    }
                }
            }
        } 

        // Returns true if perm is contained in this 
        internal bool Contains(IPermission perm) 
        {
            if (perm == null) 
                return true;
            if (m_Unrestricted)
                return true;
            if (FastIsEmpty()) 
                return false;
 
            PermissionToken token = PermissionToken.GetToken(perm); 
            Object thisObj = this.m_permSet.GetItem( token.m_index );
            if (thisObj == null) 
                return perm.IsSubsetOf( null );

            IPermission thisPerm = GetPermission(token.m_index);
            if (thisPerm != null) 
                return perm.IsSubsetOf( thisPerm );
            else 
                return perm.IsSubsetOf( null ); 
        }
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public override bool Equals( Object obj )
        {
            // Note: this method is designed to accept both PermissionSet and NamedPermissionSets. 
            // It will compare them based on the values in the base type, thereby ignoring the
            // name and description of the named permission set. 
 
            PermissionSet other = obj as PermissionSet;
 
            if (other == null)
                return false;

            if (this.m_Unrestricted != other.m_Unrestricted) 
                return false;
 
            CheckSet(); 
            other.CheckSet();
 
            DecodeAllPermissions();
            other.DecodeAllPermissions();

            int maxIndex = Math.Max( this.m_permSet.GetMaxUsedIndex(), other.m_permSet.GetMaxUsedIndex() ); 

            for (int i = 0; i <= maxIndex; ++i) 
            { 
                IPermission thisPerm = (IPermission)this.m_permSet.GetItem( i );
                IPermission otherPerm = (IPermission)other.m_permSet.GetItem( i ); 

                if (thisPerm == null && otherPerm == null)
                {
                    continue; 
                }
                else if (thisPerm == null) 
                { 
                    if (!otherPerm.IsSubsetOf( null ))
                        return false; 
                }
                else if (otherPerm == null)
                {
                    if (!thisPerm.IsSubsetOf( null )) 
                        return false;
                } 
                else 
                {
                    if (!thisPerm.Equals( otherPerm )) 
                        return false;
                }
            }
 
            return true;
        } 
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public override int GetHashCode() 
        {
            int accumulator;

            accumulator = this.m_Unrestricted ? -1 : 0; 

            if (this.m_permSet != null) 
            { 
                DecodeAllPermissions();
 
                int maxIndex = this.m_permSet.GetMaxUsedIndex();

                for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i)
                { 
                    IPermission perm = (IPermission)this.m_permSet.GetItem( i );
                    if (perm != null) 
                    { 
                        accumulator = accumulator ^ perm.GetHashCode();
                    } 
                }
            }

            return accumulator; 
        }
 
        // Mark this method as requiring a security object on the caller's frame 
        // so the caller won't be inlined (which would mess up stack crawling).
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [DynamicSecurityMethodAttribute()]
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public void Demand()
        { 
            if (this.FastIsEmpty())
                return;  // demanding the empty set always passes. 
 
            ContainsNonCodeAccessPermissions();
 
            if (m_ContainsCas)
            {
                StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
                CodeAccessSecurityEngine.Check(GetCasOnlySet(), ref stackMark); 
            }
            if (m_ContainsNonCas) 
            { 
                DemandNonCAS();
            } 
        }

        [System.Security.SecurityCritical]  // auto-generated
        internal void DemandNonCAS() 
        {
            ContainsNonCodeAccessPermissions(); 
 
            if (m_ContainsNonCas)
            { 
                if (this.m_permSet != null)
                {
                    CheckSet();
                    for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i) 
                    {
                        IPermission currPerm = GetPermission(i); 
                        if (currPerm != null && !(currPerm is CodeAccessPermission)) 
                            currPerm.Demand();
                    } 
                }
            }
        }
 
        // Metadata for this method should be flaged with REQ_SQ so that
        // EE can allocate space on the stack frame for FrameSecurityDescriptor 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [DynamicSecurityMethodAttribute()] 
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public void Assert()
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 
            SecurityRuntime.Assert(this, ref stackMark);
        } 
 
        // Metadata for this method should be flaged with REQ_SQ so that
        // EE can allocate space on the stack frame for FrameSecurityDescriptor 

        [System.Security.SecuritySafeCritical]  // auto-generated
        [DynamicSecurityMethodAttribute()]
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable 
        [Obsolete("Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
        public void Deny() 
        { 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            SecurityRuntime.Deny(this, ref stackMark); 
        }

        // Metadata for this method should be flaged with REQ_SQ so that
        // EE can allocate space on the stack frame for FrameSecurityDescriptor 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [DynamicSecurityMethodAttribute()] 
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public void PermitOnly() 
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            SecurityRuntime.PermitOnly(this, ref stackMark);
        } 

        internal IPermission GetFirstPerm() 
        { 
            IEnumerator enumerator = GetEnumerator();
            if(!enumerator.MoveNext()) 
                return null;
            return enumerator.Current as IPermission;
        }
 
        // Returns a deep copy
        public virtual PermissionSet Copy() 
        { 
            return new PermissionSet(this);
        } 

        internal PermissionSet CopyWithNoIdentityPermissions()
        {
            // Explicitly make a new PermissionSet, rather than copying, since we may have a 
            // ReadOnlyPermissionSet which cannot have identity permissions removed from it in a true copy.
            PermissionSet copy = new PermissionSet(this); 
 
            // There's no easy way to distinguish an identity permission from any other CodeAccessPermission,
            // so remove them directly. 
#if FEATURE_CAS_POLICY
            copy.RemovePermission(typeof(GacIdentityPermission));
#endif // FEATURE_CAS_POLICY
#if !FEATURE_PAL && FEATURE_X509 && FEATURE_CAS_POLICY 
            copy.RemovePermission(typeof(PublisherIdentityPermission));
#endif 
#if FEATURE_CAS_POLICY 
            copy.RemovePermission(typeof(StrongNameIdentityPermission));
            copy.RemovePermission(typeof(UrlIdentityPermission)); 
            copy.RemovePermission(typeof(ZoneIdentityPermission));
#endif // FEATURE_CAS_POLICY

            return copy; 
        }
 
        public IEnumerator GetEnumerator() 
        {
            return GetEnumeratorImpl(); 
        }

        protected virtual IEnumerator GetEnumeratorImpl()
        { 
            return new PermissionSetEnumerator(this);
        } 
 
        internal PermissionSetEnumeratorInternal GetEnumeratorInternal()
        { 
            return new PermissionSetEnumeratorInternal(this);
        }

#if FEATURE_CAS_POLICY 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public override String ToString() 
        { 
            return ToXml().ToString();
        } 
#endif // FEATURE_CAS_POLICY

        private void NormalizePermissionSet()
        { 
            // This function guarantees that all the permissions are placed at
            // the proper index within the token based sets.  This becomes necessary 
            // since these indices are dynamically allocated based on usage order. 

            PermissionSet permSetTemp = new PermissionSet(false); 

            permSetTemp.m_Unrestricted = this.m_Unrestricted;

            // Move all the normal permissions to the new permission set 

            if (this.m_permSet != null) 
            { 
                for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i)
                { 
                    Object obj = this.m_permSet.GetItem(i);
                    IPermission perm = obj as IPermission;
#if FEATURE_CAS_POLICY
                    ISecurityElementFactory elem = obj as ISecurityElementFactory; 

                    if (elem != null) 
                        perm = CreatePerm( elem ); 
#endif // FEATURE_CAS_POLICY
                    if (perm != null) 
                        permSetTemp.SetPermission( perm );
                }
            }
 
            this.m_permSet = permSetTemp.m_permSet;
        } 
 
#if FEATURE_CAS_POLICY
        private bool DecodeXml(byte[] data, HostProtectionResource fullTrustOnlyResources, HostProtectionResource inaccessibleResources ) 
        {
            if (data != null && data.Length > 0)
            {
                FromXml( new Parser( data, Tokenizer.ByteTokenEncoding.UnicodeTokens ).GetTopElement() ); 
            }
 
            FilterHostProtectionPermissions(fullTrustOnlyResources, inaccessibleResources); 

            // We call this method from unmanaged to code a set we are going to use declaratively.  In 
            // this case, all the lazy evaluation for partial policy resolution is wasted since we'll
            // need to decode all of these shortly to make the demand for whatever.  Therefore, we
            // pay that price now so that we can calculate whether all the permissions in the set
            // implement the IUnrestrictedPermission interface (the common case) for use in some 
            // unmanaged optimizations.
 
            DecodeAllPermissions(); 

            return true; 
        }
#endif // FEATURE_CAS_POLICY

        private void DecodeAllPermissions() 
        {
            if (m_permSet == null) 
            { 
                m_allPermissionsDecoded = true;
                return; 
            }

            int maxIndex = m_permSet.GetMaxUsedIndex();
            for (int i = 0; i <= maxIndex; ++i) 
            {
                // GetPermission has the side-effect of decoding the permission in the slot 
                GetPermission(i); 
            }
 
            m_allPermissionsDecoded = true;
        }

        internal void FilterHostProtectionPermissions(HostProtectionResource fullTrustOnly, HostProtectionResource inaccessible) 
        {
            HostProtectionPermission.protectedResources = fullTrustOnly; 
            HostProtectionPermission hpp = (HostProtectionPermission)GetPermission(HostProtectionPermission.GetTokenIndex()); 
            if(hpp == null)
                return; 

            HostProtectionPermission newHpp = (HostProtectionPermission)hpp.Intersect(new HostProtectionPermission(fullTrustOnly));
            if (newHpp == null)
            { 
#if FEATURE_CAS_POLICY
                RemovePermission(typeof(HostProtectionPermission)); 
#else // !FEATURE_CAS_POLICY 
                RemovePermission(HostProtectionPermission.GetTokenIndex());
#endif // FEATURE_CAS_POLICY 
            }
            else if (newHpp.Resources != hpp.Resources)
            {
                SetPermission(newHpp); 
            }
        } 
 
#if FEATURE_CAS_POLICY
        public virtual void FromXml( SecurityElement et ) 
        {
            FromXml( et, false, false );
        }
 
        internal static bool IsPermissionTag( String tag, bool allowInternalOnly )
        { 
            if (tag.Equals( s_str_Permission ) || 
                tag.Equals( s_str_IPermission ))
            { 
                return true;
            }

            if (allowInternalOnly && 
                (tag.Equals( s_str_PermissionUnion ) ||
                 tag.Equals( s_str_PermissionIntersection ) || 
                 tag.Equals( s_str_PermissionUnrestrictedIntersection ) || 
                 tag.Equals( s_str_PermissionUnrestrictedUnion)))
            { 
                return true;
            }

            return false; 
        }
 
        internal virtual void FromXml( SecurityElement et, bool allowInternalOnly, bool ignoreTypeLoadFailures ) 
        {
            if (et == null) 
                throw new ArgumentNullException("et");

            if (!et.Tag.Equals(s_str_PermissionSet))
                throw new ArgumentException(String.Format( null, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PermissionSet", this.GetType().FullName) ); 
            Contract.EndContractBlock();
 
            Reset(); 
            m_ignoreTypeLoadFailures = ignoreTypeLoadFailures;
            m_allPermissionsDecoded = false; 
            m_Unrestricted = XMLUtil.IsUnrestricted( et );

            if (et.InternalChildren != null)
            { 
                int childCount = et.InternalChildren.Count;
                for (int i = 0; i < childCount; ++i) 
                { 
                    SecurityElement elem = (SecurityElement)et.Children[i];
 
                    if (IsPermissionTag( elem.Tag, allowInternalOnly ))
                    {
                        String className = elem.Attribute( "class" );
 
                        PermissionToken token;
                        Object objectToInsert; 
 
                        if (className != null)
                        { 
                            token = PermissionToken.GetToken( className );
                            if (token == null)
                            {
                                objectToInsert = CreatePerm( elem ); 
#if _DEBUG
                                PermissionToken tokenDebug = PermissionToken.GetToken( (IPermission)objectToInsert ); 
                                Contract.Assert( tokenDebug != null && (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins" ); 
#endif
                                if (objectToInsert != null) 
                                {
                                    Contract.Assert( objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(),
                                        "PermissionToken.GetToken returned null for non-mscorlib permission" );
                                    token = PermissionToken.GetToken( (IPermission)objectToInsert ); 
                                    Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance" );
                                } 
                            } 
                            else
                            { 
                                objectToInsert = elem;
                            }
                        }
                        else 
                        {
                            IPermission ip = CreatePerm( elem ); 
                            if (ip == null) 
                            {
                                token = null; 
                                objectToInsert = null;
                            }
                            else
                            { 
                                token = PermissionToken.GetToken( ip );
                                Contract.Assert( PermissionToken.IsTokenProperlyAssigned( ip, token ), 
                                                 "PermissionToken was improperly assigned" ); 
                                objectToInsert = ip;
                            } 
                        }

                        if (token != null && objectToInsert != null)
                        { 
                            if (m_permSet == null)
                                m_permSet = new TokenBasedSet(); 
 
                            if (this.m_permSet.GetItem( token.m_index ) != null)
                            { 
                                // If there is already something in that slot, let's union them
                                // together.

                                IPermission permInSlot; 

                                if (this.m_permSet.GetItem( token.m_index ) is IPermission) 
                                    permInSlot = (IPermission)this.m_permSet.GetItem( token.m_index ); 
                                else
                                    permInSlot = CreatePerm( (SecurityElement)this.m_permSet.GetItem( token.m_index ) ); 

                                if (objectToInsert is IPermission)
                                    objectToInsert = ((IPermission)objectToInsert).Union( permInSlot );
                                else 
                                    objectToInsert = CreatePerm( (SecurityElement)objectToInsert ).Union( permInSlot );
                            } 
 
                            if(m_Unrestricted && objectToInsert is IPermission)
                                objectToInsert = null; 

                            this.m_permSet.SetItem( token.m_index, objectToInsert );
                        }
                    } 
                }
            } 
        } 

        internal virtual void FromXml( SecurityDocument doc, int position, bool allowInternalOnly ) 
        {
            if (doc == null)
                throw new ArgumentNullException("doc");
            Contract.EndContractBlock(); 

            if (!doc.GetTagForElement( position ).Equals(s_str_PermissionSet)) 
                throw new ArgumentException(String.Format( null, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PermissionSet", this.GetType().FullName) ); 

            Reset(); 
            m_allPermissionsDecoded = false;
            Exception savedException = null;
            String strUnrestricted = doc.GetAttributeForElement( position, "Unrestricted" );
            if (strUnrestricted != null) 
                m_Unrestricted = strUnrestricted.Equals( "True" ) || strUnrestricted.Equals( "true" ) || strUnrestricted.Equals( "TRUE" );
            else 
                m_Unrestricted = false; 

            ArrayList childrenIndices = doc.GetChildrenPositionForElement( position ); 
            int childCount = childrenIndices.Count;
            for (int i = 0; i < childCount; ++i)
            {
                int childIndex = (int)childrenIndices[i]; 
                if (IsPermissionTag( doc.GetTagForElement( childIndex ), allowInternalOnly ))
                { 
                    try 
                    {
                        String className = doc.GetAttributeForElement( childIndex, "class" ); 

                        PermissionToken token;
                        Object objectToInsert;
 
                        if (className != null)
                        { 
                            token = PermissionToken.GetToken( className ); 
                            if (token == null)
                            { 
                                objectToInsert = CreatePerm( doc.GetElement( childIndex, true ) );

                                if (objectToInsert != null)
                                { 
#if _DEBUG
                                    PermissionToken tokenDebug = PermissionToken.GetToken( (IPermission)objectToInsert ); 
                                    Contract.Assert((tokenDebug != null), "PermissionToken.GetToken returned null "); 
                                    Contract.Assert( (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins" );
#endif 
                                    Contract.Assert( objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(),
                                        "PermissionToken.GetToken returned null for non-mscorlib permission" );
                                    token = PermissionToken.GetToken( (IPermission)objectToInsert );
                                    Contract.Assert((token != null), "PermissionToken.GetToken returned null "); 
                                    Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance" );
                                } 
                            } 
                            else
                            { 
                                objectToInsert = ((ISecurityElementFactory)new SecurityDocumentElement(doc, childIndex)).CreateSecurityElement();
                            }
                        }
                        else 
                        {
                            IPermission ip = CreatePerm( doc.GetElement( childIndex, true ) ); 
                            if (ip == null) 
                            {
                                token = null; 
                                objectToInsert = null;
                            }
                            else
                            { 
                                token = PermissionToken.GetToken( ip );
                                Contract.Assert( PermissionToken.IsTokenProperlyAssigned( ip, token ), 
                                                 "PermissionToken was improperly assigned" ); 
                                objectToInsert = ip;
                            } 
                        }

                        if (token != null && objectToInsert != null)
                        { 
                            if (m_permSet == null)
                                m_permSet = new TokenBasedSet(); 
 
                            IPermission permInSlot = null;
                            if (this.m_permSet.GetItem( token.m_index ) != null) 
                            {
                                // If there is already something in that slot, let's union them
                                // together.
 
                                if (this.m_permSet.GetItem( token.m_index ) is IPermission)
                                    permInSlot = (IPermission)this.m_permSet.GetItem( token.m_index ); 
                                else 
                                    permInSlot = CreatePerm( this.m_permSet.GetItem( token.m_index ) );
                            } 

                            if (permInSlot != null)
                            {
                                if (objectToInsert is IPermission) 
                                    objectToInsert = permInSlot.Union((IPermission)objectToInsert);
                                else 
                                    objectToInsert = permInSlot.Union(CreatePerm( objectToInsert )); 
                            }
 
                            if(m_Unrestricted && objectToInsert is IPermission)
                                objectToInsert = null;

                            this.m_permSet.SetItem( token.m_index, objectToInsert ); 
                        }
                    } 
                    catch (Exception e) 
                    {
#if _DEBUG 
                        if (debug)
                            DEBUG_WRITE( "error while decoding permission set =\n" + e.ToString() );
#endif
                        if (savedException == null) 
                            savedException = e;
 
                    } 
                }
            } 

            if (savedException != null)
                throw savedException;
 
        }
 
        private  IPermission CreatePerm(Object obj) 
        {
            return CreatePerm(obj, m_ignoreTypeLoadFailures); 
        }

        internal static IPermission CreatePerm(Object obj, bool ignoreTypeLoadFailures)
        { 
            SecurityElement el = obj as SecurityElement;
            ISecurityElementFactory isf = obj as ISecurityElementFactory; 
            if (el == null && isf != null) 
            {
                el = isf.CreateSecurityElement(); 
            }

            IEnumerator enumerator;
            IPermission finalPerm = null; 

            switch (el.Tag) 
            { 
            case s_str_PermissionUnion:
                enumerator = el.Children.GetEnumerator(); 
                while (enumerator.MoveNext())
                {
                    IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
 
                    if (finalPerm != null)
                        finalPerm = finalPerm.Union( tempPerm ); 
                    else 
                        finalPerm = tempPerm;
                } 
                break;

            case s_str_PermissionIntersection:
                enumerator = el.Children.GetEnumerator(); 
                while (enumerator.MoveNext())
                { 
                    IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures); 

                    if (finalPerm != null) 
                        finalPerm = finalPerm.Intersect( tempPerm );
                    else
                        finalPerm = tempPerm;
 
                    if (finalPerm == null)
                        return null; 
                } 
                break;
 
            case s_str_PermissionUnrestrictedUnion:
                enumerator = el.Children.GetEnumerator();
                bool first = true;
                while (enumerator.MoveNext()) 
                {
                    IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures ); 
 
                    if (tempPerm == null)
                        continue; 

                    PermissionToken token = PermissionToken.GetToken( tempPerm );

                    Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already" ); 

                    if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) 
                    { 
                        finalPerm = XMLUtil.CreatePermission( GetPermissionElement((SecurityElement)enumerator.Current), PermissionState.Unrestricted, ignoreTypeLoadFailures );
                        first = false; 
                        break;
                    }
                    else
                    { 
                        Contract.Assert( tempPerm != null, "We should only come here if we have a real permission" );
                        if (first) 
                            finalPerm = tempPerm; 
                        else
                            finalPerm = tempPerm.Union( finalPerm ); 
                        first = false;
                    }
                }
                break; 

            case s_str_PermissionUnrestrictedIntersection: 
                enumerator = el.Children.GetEnumerator(); 
                while (enumerator.MoveNext())
                { 
                    IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures );

                    if (tempPerm == null)
                        return null; 

                    PermissionToken token = PermissionToken.GetToken( tempPerm ); 
 
                    Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already" );
 
                    if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
                    {
                        if (finalPerm != null)
                            finalPerm = tempPerm.Intersect( finalPerm ); 
                        else
                            finalPerm = tempPerm; 
                    } 
                    else
                    { 
                        finalPerm = null;
                    }

                    if (finalPerm == null) 
                        return null;
                } 
                break; 

            case "IPermission": 
            case "Permission":
                finalPerm = el.ToPermission(ignoreTypeLoadFailures);
                break;
 
            default:
                Contract.Assert( false, "Unrecognized case found during permission creation" ); 
                break; 
            }
 
            return finalPerm;
        }

        internal IPermission CreatePermission(Object obj, int index) 
        {
            IPermission perm = CreatePerm(obj); 
            if(perm == null) 
                return null;
 
            // See if the PermissionSet.m_Unrestricted flag covers this permission
            if(m_Unrestricted)
                perm = null;
 
            // Store the decoded result
            CheckSet(); 
            m_permSet.SetItem(index, perm); 

            // Do some consistency checks 
            Contract.Assert(perm == null || PermissionToken.IsTokenProperlyAssigned( perm, PermissionToken.GetToken( perm ) ), "PermissionToken was improperly assigned");
            if (perm != null)
            {
                PermissionToken permToken = PermissionToken.GetToken(perm); 
                if (permToken != null && permToken.m_index != index)
                    throw new ArgumentException( Environment.GetResourceString( "Argument_UnableToGeneratePermissionSet")); 
            } 

 
            return perm;
        }

        private static SecurityElement GetPermissionElement( SecurityElement el ) 
        {
            switch (el.Tag) 
            { 
            case "IPermission":
            case "Permission": 
                return el;
            }
            IEnumerator enumerator = el.Children.GetEnumerator();
            if (enumerator.MoveNext()) 
                return GetPermissionElement((SecurityElement)enumerator.Current);
            Contract.Assert( false, "No Permission or IPermission tag found" ); 
            return null; 
        }
 
        internal static SecurityElement CreateEmptyPermissionSetXml()
        {

            SecurityElement elTrunk = new SecurityElement("PermissionSet"); 
            elTrunk.AddAttribute( "class", "System.Security.PermissionSet" );
 
            elTrunk.AddAttribute( "version", "1" ); 
            return elTrunk;
 
        }
        // internal helper which takes in the hardcoded permission name to avoid lookup at runtime
        // can be called from classes that derive from PermissionSet
        internal SecurityElement ToXml(String permName) 
        {
            SecurityElement elTrunk = new SecurityElement("PermissionSet"); 
            elTrunk.AddAttribute( "class", permName ); 

            elTrunk.AddAttribute( "version", "1" ); 

            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);

            if (m_Unrestricted) 
            {
                elTrunk.AddAttribute(s_str_Unrestricted, "true" ); 
            } 

            while (enumerator.MoveNext()) 
            {
                IPermission perm = (IPermission)enumerator.Current;

                if (!m_Unrestricted) 
                    elTrunk.AddChild( perm.ToXml() );
            } 
            return elTrunk; 
        }
 
        internal SecurityElement InternalToXml()
        {
            SecurityElement elTrunk = new SecurityElement("PermissionSet");
            elTrunk.AddAttribute( "class", this.GetType().FullName); 
            elTrunk.AddAttribute( "version", "1" );
 
            if (m_Unrestricted) 
            {
                elTrunk.AddAttribute(s_str_Unrestricted, "true" ); 
            }

            if (this.m_permSet != null)
            { 
                int maxIndex = this.m_permSet.GetMaxUsedIndex();
 
                for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i) 
                {
                    Object obj = this.m_permSet.GetItem( i ); 
                    if (obj != null)
                    {
                        if (obj is IPermission)
                        { 
                            if (!m_Unrestricted)
                                elTrunk.AddChild( ((IPermission)obj).ToXml() ); 
                        } 
                        else
                        { 
                            elTrunk.AddChild( (SecurityElement)obj );
                        }
                    }
 
                }
            } 
            return elTrunk ; 
        }
 
        public virtual SecurityElement ToXml()
        {
            // If you hit this assert then most likely you are trying to change the name of this class.
            // This is ok as long as you change the hard coded string above and change the assert below. 
            Contract.Assert( this.GetType().FullName.Equals( "System.Security.PermissionSet" ), "Class name changed! Was: System.Security.PermissionSet Should be:" +  this.GetType().FullName);
 
            return ToXml("System.Security.PermissionSet"); 
        }
#endif // FEATURE_CAS_POLICY 

#if FEATURE_CAS_POLICY && FEATURE_SERIALIZATION
        internal
        byte[] EncodeXml() 
        {
            MemoryStream ms = new MemoryStream(); 
            BinaryWriter writer = new BinaryWriter( ms, Encoding.Unicode ); 
            writer.Write( this.ToXml().ToString() );
            writer.Flush(); 

            // The BinaryWriter is going to place
            // two bytes indicating a Unicode stream.
            // We want to chop those off before returning 
            // the bytes out.
 
            ms.Position = 2; 
            int countBytes = (int)ms.Length - 2;
            byte[] retval = new byte[countBytes]; 
            ms.Read( retval, 0, retval.Length );
            return retval;
        }
 
        /// 
        [Obsolete("This method is obsolete and shoud no longer be used.")] 
        public static byte[] ConvertPermissionSet(String inFormat, byte[] inData, String outFormat) 
        {
            // Since this method has shipped and is public, we cannot remove it without being a breaking change 
            throw new NotImplementedException();
        }
#endif
 
        // Determines whether the permission set contains any non-code access
        // security permissions. 
        public bool ContainsNonCodeAccessPermissions() 
        {
            if (m_CheckedForNonCas) 
                return m_ContainsNonCas;

            lock (this)
            { 
                if (m_CheckedForNonCas)
                    return m_ContainsNonCas; 
 
                m_ContainsCas = false;
                m_ContainsNonCas = false; 

                if (IsUnrestricted())
                    m_ContainsCas = true;
 
                if (this.m_permSet != null)
                { 
                    PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this); 

                    while (enumerator.MoveNext() && (!m_ContainsCas || !m_ContainsNonCas)) 
                    {
                        IPermission perm = enumerator.Current as IPermission;

                        if (perm != null) 
                        {
                            if (perm is CodeAccessPermission) 
                                m_ContainsCas = true; 
                            else
                                m_ContainsNonCas = true; 
                        }
                    }
                }
 
                m_CheckedForNonCas = true;
            } 
 
            return m_ContainsNonCas;
        } 

        // Returns a permission set containing only CAS-permissions. If possible
        // this is just the input set, otherwise a new set is allocated.
        private PermissionSet GetCasOnlySet() 
        {
            if (!m_ContainsNonCas) 
                return this; 

            if (IsUnrestricted()) 
                return this;

            PermissionSet pset = new PermissionSet(false);
 
            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
 
            while (enumerator.MoveNext()) 
            {
                IPermission perm = (IPermission)enumerator.Current; 

                if (perm is CodeAccessPermission)
                    pset.AddPermission(perm);
            } 

            pset.m_CheckedForNonCas = true; 
            pset.m_ContainsCas = !pset.IsEmpty(); 
            pset.m_ContainsNonCas = false;
 
            return pset;
        }

#if FEATURE_CAS_POLICY 
        private const String s_str_PermissionSet = "PermissionSet";
        private const String s_str_Permission    = "Permission"; 
        private const String s_str_IPermission    = "IPermission"; 
        private const String s_str_Unrestricted  = "Unrestricted";
        private const String s_str_PermissionUnion = "PermissionUnion"; 
        private const String s_str_PermissionIntersection = "PermissionIntersection";
        private const String s_str_PermissionUnrestrictedUnion = "PermissionUnrestrictedUnion";
        private const String s_str_PermissionUnrestrictedIntersection = "PermissionUnrestrictedIntersection";
 
        // This method supports v1.x security attrbutes only - we'll require legacy CAS policy mode
        // to be enabled for that to work. 
#pragma warning disable 618 
        // Internal routine used to setup a special security context
        // for creating and manipulated security custom attributes 
        // that we use when the Runtime is hosted.
        [System.Security.SecurityCritical]  // auto-generated
        private static void SetupSecurity()
        { 
            PolicyLevel level = PolicyLevel.CreateAppDomainLevel();
 
            CodeGroup rootGroup = new UnionCodeGroup( new AllMembershipCondition(), level.GetNamedPermissionSet( "Execution" ) ); 

            StrongNamePublicKeyBlob microsoftBlob = new StrongNamePublicKeyBlob( AssemblyRef.MicrosoftPublicKeyFull ); 
            CodeGroup microsoftGroup = new UnionCodeGroup( new StrongNameMembershipCondition( microsoftBlob, null, null ), level.GetNamedPermissionSet( "FullTrust" ) );

            StrongNamePublicKeyBlob ecmaBlob = new StrongNamePublicKeyBlob( AssemblyRef.EcmaPublicKeyFull );
            CodeGroup ecmaGroup = new UnionCodeGroup( new StrongNameMembershipCondition( ecmaBlob, null, null ), level.GetNamedPermissionSet( "FullTrust" ) ); 

            CodeGroup gacGroup = new UnionCodeGroup( new GacMembershipCondition(), level.GetNamedPermissionSet( "FullTrust" ) ); 
 
            rootGroup.AddChild( microsoftGroup );
            rootGroup.AddChild( ecmaGroup ); 
            rootGroup.AddChild( gacGroup );

            level.RootCodeGroup = rootGroup;
 
            try
            { 
                AppDomain.CurrentDomain.SetAppDomainPolicy( level ); 
            }
            catch (PolicyException) 
            {
            }
        }
#endif 
#pragma warning restore 618
 
        // Internal routine used by CreateSerialized to add a permission to the set 
        private static void MergePermission(IPermission perm, bool separateCasFromNonCas, ref PermissionSet casPset, ref PermissionSet nonCasPset)
        { 
            Contract.Assert(casPset == null || !casPset.IsReadOnly);
            Contract.Assert(nonCasPset == null || !nonCasPset.IsReadOnly);

            if (perm == null) 
                return;
 
            if (!separateCasFromNonCas || perm is CodeAccessPermission) 
            {
                if(casPset == null) 
                    casPset = new PermissionSet(false);
                IPermission oldPerm = casPset.GetPermission(perm);
                IPermission unionPerm = casPset.AddPermission(perm);
                if (oldPerm != null && !oldPerm.IsSubsetOf( unionPerm )) 
                    throw new NotSupportedException( Environment.GetResourceString( "NotSupported_DeclarativeUnion" ) );
            } 
            else 
            {
                if(nonCasPset == null) 
                    nonCasPset = new PermissionSet(false);
                IPermission oldPerm = nonCasPset.GetPermission(perm);
                IPermission unionPerm = nonCasPset.AddPermission( perm );
                if (oldPerm != null && !oldPerm.IsSubsetOf( unionPerm )) 
                    throw new NotSupportedException( Environment.GetResourceString( "NotSupported_DeclarativeUnion" ) );
            } 
        } 

        // Converts an array of SecurityAttributes to a PermissionSet 
        [ResourceExposure(ResourceScope.Machine)]  // Reading these attributes can load files.
        [ResourceConsumption(ResourceScope.Machine)]
        private static byte[] CreateSerialized(Object[] attrs,
                                               bool serialize, 
                                               ref byte[] nonCasBlob,
                                               out PermissionSet casPset, 
                                               HostProtectionResource fullTrustOnlyResources, 
                                               bool allowEmptyPermissionSets)
        { 
            // Create two new (empty) sets.
            casPset = null;
            PermissionSet nonCasPset = null;
 
            // Most security attributes generate a single permission. The
            // PermissionSetAttribute class generates an entire permission set we 
            // need to merge, however. 
            for (int i = 0; i < attrs.Length; i++)
            { 
                Contract.Assert(i == 0 || ((SecurityAttribute)attrs[i]).m_action == ((SecurityAttribute)attrs[i - 1]).m_action, "Mixed SecurityActions");
                if (attrs[i] is PermissionSetAttribute)
                {
                    PermissionSet pset = ((PermissionSetAttribute)attrs[i]).CreatePermissionSet(); 
                    if (pset == null)
                        throw new ArgumentException( Environment.GetResourceString( "Argument_UnableToGeneratePermissionSet" ) ); 
 
                    PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(pset);
 
                    while (enumerator.MoveNext())
                    {
                        IPermission perm = (IPermission)enumerator.Current;
                        MergePermission(perm, serialize, ref casPset, ref nonCasPset); 
                    }
 
                    if(casPset == null) 
                        casPset = new PermissionSet(false);
                    if (pset.IsUnrestricted()) 
                        casPset.SetUnrestricted(true);
                }
                else
                { 
                    IPermission perm = ((SecurityAttribute)attrs[i]).CreatePermission();
                    MergePermission(perm, serialize, ref casPset, ref nonCasPset); 
                } 
            }
            Contract.Assert(serialize || nonCasPset == null, "We shouldn't separate nonCAS permissions unless fSerialize is true"); 

            //
            // Filter HostProtection permission.  In the VM, some optimizations are done based upon these
            // declarative permission sets being NULL if they do not exist.  When filtering the permission 
            // set if we end up with an empty set, we can the permission set NULL rather than returning the
            // empty set in order to enable those optimizations. 
            // 

            if(casPset != null) 
            {
                casPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None);
                casPset.ContainsNonCodeAccessPermissions(); // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code
                if (allowEmptyPermissionSets && casPset.IsEmpty()) 
                    casPset = null;
            } 
            if(nonCasPset != null) 
            {
                nonCasPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None); 
                nonCasPset.ContainsNonCodeAccessPermissions(); // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code
                if (allowEmptyPermissionSets && nonCasPset.IsEmpty())
                    nonCasPset = null;
            } 

            // Serialize the set(s). 
            byte[] casBlob = null; 
            nonCasBlob = null;
#if FEATURE_CAS_POLICY 
            if(serialize)
            {
                if(casPset != null)
                    casBlob = casPset.EncodeXml(); 
                if(nonCasPset != null)
                    nonCasBlob = nonCasPset.EncodeXml(); 
            } 
#else // FEATURE_CAS_POLICY
            Contract.Assert(!serialize, "Cannot serialize permission sets on CoreCLR"); 
#endif // FEATURE_CAS_POLICY

            return casBlob;
        } 

#if FEATURE_SERIALIZATION 
        ///  
        void IDeserializationCallback.OnDeserialization(Object sender)
        { 
            NormalizePermissionSet();
            m_CheckedForNonCas = false;
        }
#endif 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable 
        public static void RevertAssert()
        { 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            SecurityRuntime.RevertAssert(ref stackMark);
        }
 
        internal static PermissionSet RemoveRefusedPermissionSet(PermissionSet assertSet, PermissionSet refusedSet, out bool bFailedToCompress)
        { 
            Contract.Assert((assertSet == null || !assertSet.IsUnrestricted()), "Cannot be unrestricted here"); 
            PermissionSet retPs = null;
            bFailedToCompress = false; 
            if (assertSet == null)
                return null;
            if (refusedSet != null)
            { 
                if (refusedSet.IsUnrestricted())
                    return null; // we're refusing everything...cannot assert anything now. 
 
                PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(refusedSet);
                while (enumerator.MoveNext()) 
                {
                    CodeAccessPermission refusedPerm = (CodeAccessPermission)enumerator.Current;
                    int i = enumerator.GetCurrentIndex();
                    if (refusedPerm != null) 
                    {
                        CodeAccessPermission perm 
                            = (CodeAccessPermission)assertSet.GetPermission(i); 
                        try
                        { 
                            if (refusedPerm.Intersect(perm) != null)
                            {
                                if (refusedPerm.Equals(perm))
                                { 
                                    if (retPs == null)
                                        retPs = assertSet.Copy(); 
 
                                    retPs.RemovePermission(i);
                                } 
                                else
                                {
                                    // Asserting a permission, part of which is already denied/refused
                                    // cannot compress this assert 
                                    bFailedToCompress = true;
                                    return assertSet; 
                                } 
                            }
                        } 
                        catch (ArgumentException)
                        {
                            // Any exception during removing a refused set from assert set => we play it safe and not assert that perm
                            if (retPs == null) 
                                retPs = assertSet.Copy();
                            retPs.RemovePermission(i); 
                        } 
                    }
                } 
            }
            if (retPs != null)
                return retPs;
            return assertSet; 
        }
 
        internal static void RemoveAssertedPermissionSet(PermissionSet demandSet, PermissionSet assertSet, out PermissionSet alteredDemandSet) 
        {
            Contract.Assert(!assertSet.IsUnrestricted(), "Cannot call this function if assertSet is unrestricted"); 
            alteredDemandSet = null;

            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(demandSet);
            while (enumerator.MoveNext()) 
            {
                CodeAccessPermission demandDerm = (CodeAccessPermission)enumerator.Current; 
                int i = enumerator.GetCurrentIndex(); 
                if (demandDerm != null)
                { 
                    CodeAccessPermission assertPerm
                        = (CodeAccessPermission)assertSet.GetPermission(i);
                    try
                    { 
                        if (demandDerm.CheckAssert(assertPerm))
                        { 
                            if (alteredDemandSet == null) 
                                alteredDemandSet = demandSet.Copy();
 
                            alteredDemandSet.RemovePermission(i);
                        }
                    }
                    catch (ArgumentException) 
                    {
                    } 
                } 
            }
            return; 
        }

        internal static bool IsIntersectingAssertedPermissions(PermissionSet assertSet1, PermissionSet assertSet2)
        { 
            bool isIntersecting = false;
            if (assertSet1 != null && assertSet2 != null) 
            { 
                PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(assertSet2);
                while (enumerator.MoveNext()) 
                {
                    CodeAccessPermission perm2 = (CodeAccessPermission)enumerator.Current;
                    int i = enumerator.GetCurrentIndex();
                    if (perm2 != null) 
                    {
                        CodeAccessPermission perm1 
                            = (CodeAccessPermission)assertSet1.GetPermission(i); 
                        try
                        { 
                            if (perm1 != null && !perm1.Equals(perm2))
                            {
                                isIntersecting = true; // Same type of permission, but with different flags or something - cannot union them
                            } 
                        }
                        catch (ArgumentException) 
                        { 
                            isIntersecting = true; //assume worst case
                        } 
                    }
                }
            }
            return isIntersecting; 

        } 
 
        // This is a hack so that SQL can operate under default policy without actually
        // granting permissions in assemblies that they disallow.  @ 


        internal bool IgnoreTypeLoadFailures
        { 
            set { m_ignoreTypeLoadFailures = value; }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// ==++== 
//
//   Copyright (c) Microsoft Corporation.  All rights reserved.
//
// ==--== 
// [....]
// 
 
namespace System.Security {
    using System; 
    using System.Threading;
    using System.Security.Util;
    using System.Collections;
    using System.IO; 
    using System.Security.Permissions;
    using System.Runtime.CompilerServices; 
    using System.Security.Policy; 
#if FEATURE_SERIALIZATION
    using System.Runtime.Serialization.Formatters.Binary; 
#endif // FEATURE_SERIALIZATION
    using BindingFlags = System.Reflection.BindingFlags;
    using System.Runtime.Serialization;
    using System.Text; 
    using System.Globalization;
    using System.Runtime.Versioning; 
    using System.Diagnostics.Contracts; 

    [Serializable] 
    internal enum SpecialPermissionSetFlag
    {
        // These also appear in clr/src/vm/permset.h
        Regular = 0, 
        NoSet = 1,
        EmptySet = 2, 
        SkipVerification = 3 
    }
 
    [Serializable]
    [StrongNameIdentityPermissionAttribute(SecurityAction.InheritanceDemand, Name = "mscorlib", PublicKey = "0x" + AssemblyRef.EcmaPublicKeyFull)]
[System.Runtime.InteropServices.ComVisible(true)]
    public class PermissionSet : ISecurityEncodable, ICollection, IStackWalk, IDeserializationCallback 
    {
    #if _DEBUG 
        internal static readonly bool debug; 
    #endif
 
        [System.Diagnostics.Conditional( "_DEBUG" )]
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
        private static void DEBUG_WRITE(String str) { 
        #if _DEBUG
            if (debug) Console.WriteLine(str); 
        #endif 
         }
 
        [System.Diagnostics.Conditional( "_DEBUG" )]
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
        private static void DEBUG_COND_WRITE(bool exp, String str) 
        {
        #if _DEBUG 
            if (debug && (exp)) Console.WriteLine(str); 
        #endif
        } 

        [System.Diagnostics.Conditional( "_DEBUG" )]
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Process, ResourceScope.Process)] 
        private static void DEBUG_PRINTSTACK(Exception e)
        { 
        #if _DEBUG 
            if (debug) Console.Error.WriteLine((e).StackTrace);
        #endif 
        }

        // These members are accessed from EE using their hardcoded offset.
        // Please update the PermissionSetObject in object.h if you make any changes 
        // to the fields here. !dumpobj will show the field layout
 
        // First the fields that are serialized x-appdomain (for perf reasons) 
        private bool m_Unrestricted;
        [OptionalField(VersionAdded = 2)] 
        private bool m_allPermissionsDecoded = false;

        [OptionalField(VersionAdded = 2)]
        internal TokenBasedSet m_permSet = null; 

        // This is a hack so that SQL can operate under default policy without actually 
        // granting permissions in assemblies that they disallow.  @ 

 
        [OptionalField(VersionAdded = 2)]
        private bool m_ignoreTypeLoadFailures = false;

        // This field will be populated only for non X-AD scenarios where we create a XML-ised string of the PermissionSet 
        [OptionalField(VersionAdded = 2)]
        private String m_serializedPermissionSet; 
 
        [NonSerialized] private bool m_CheckedForNonCas;
        [NonSerialized] private bool m_ContainsCas; 
        [NonSerialized] private bool m_ContainsNonCas;

        // only used during non X-AD serialization to save the m_permSet value (which we dont want serialized)
        [NonSerialized] private TokenBasedSet m_permSetSaved; 

        // Following 4 fields are used only for serialization compat purposes: DO NOT USE THESE EVER! 
#pragma warning disable 169 
        private bool readableonly;
        private TokenBasedSet m_unrestrictedPermSet; 
        private TokenBasedSet m_normalPermSet;

        [OptionalField(VersionAdded = 2)]
        private bool m_canUnrestrictedOverride; 
#pragma warning restore 169
        // END: Serialization-only fields 
 
        internal static readonly PermissionSet s_fullTrust = new PermissionSet( true );
 
#if FEATURE_REMOTING
        [OnDeserializing]
        private void OnDeserializing(StreamingContext ctx)
        { 
            Reset();
        } 
 
        [OnDeserialized]
        private void OnDeserialized(StreamingContext ctx) 
        {
            if (m_serializedPermissionSet != null)
            {
                // Whidbey non X-AD case 
                FromXml(SecurityElement.FromString(m_serializedPermissionSet));
            } 
            else if (m_normalPermSet != null) 
            {
                // Everett non X-AD case 
                m_permSet = m_normalPermSet.SpecialUnion(m_unrestrictedPermSet);
            }
            else if (m_unrestrictedPermSet != null)
            { 
                // Everett non X-AD case
                m_permSet = m_unrestrictedPermSet.SpecialUnion(m_normalPermSet); 
            } 

            m_serializedPermissionSet = null; 
            m_normalPermSet = null;
            m_unrestrictedPermSet = null;

        } 

        [OnSerializing] 
        private void OnSerializing(StreamingContext ctx) 
        {
 
            if ((ctx.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
            {
                m_serializedPermissionSet = ToString(); // For v2.x and beyond
                if (m_permSet != null) 
                    m_permSet.SpecialSplit(ref m_unrestrictedPermSet, ref m_normalPermSet, m_ignoreTypeLoadFailures);
                m_permSetSaved = m_permSet; 
                m_permSet = null; 
            }
        } 
#endif // !FEATURE_REMOTING

#if FEATURE_REMOTING || _DEBUG
        [OnSerialized] 
        private void OnSerialized(StreamingContext context)
        { 
#if FEATURE_REMOTING 
            if ((context.State & ~(StreamingContextStates.Clone|StreamingContextStates.CrossAppDomain)) != 0)
            { 
                m_serializedPermissionSet = null;
                m_permSet = m_permSetSaved;
                m_permSetSaved = null;
                m_unrestrictedPermSet = null; 
                m_normalPermSet = null;
            } 
#else // !FEATURE_REMOTING 
            Contract.Assert(false, "PermissionSet does not support serialization on CoreCLR");
#endif // !FEATURE_REMOTING 
        }
#endif // FEATURE_REMOTING || _DEBUG

        internal PermissionSet() 
        {
            Reset(); 
            m_Unrestricted = true; 
        }
 
        internal PermissionSet(bool fUnrestricted)
            : this()
        {
            SetUnrestricted(fUnrestricted); 
        }
 
        public PermissionSet(PermissionState state) 
            : this()
        { 
            if (state == PermissionState.Unrestricted)
            {
                SetUnrestricted( true );
            } 
            else if (state == PermissionState.None)
            { 
                SetUnrestricted( false ); 
            }
            else 
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_InvalidPermissionState"));
            }
        } 

        public PermissionSet(PermissionSet permSet) 
            : this() 
        {
            if (permSet == null) 
            {
                Reset();
                return;
            } 

            m_Unrestricted = permSet.m_Unrestricted; 
            m_CheckedForNonCas = permSet.m_CheckedForNonCas; 
            m_ContainsCas = permSet.m_ContainsCas;
            m_ContainsNonCas = permSet.m_ContainsNonCas; 
            m_ignoreTypeLoadFailures = permSet.m_ignoreTypeLoadFailures;

            if (permSet.m_permSet != null)
            { 
                m_permSet = new TokenBasedSet(permSet.m_permSet);
 
                // now deep copy all permissions in set 
                for (int i = m_permSet.GetStartingIndex(); i <= m_permSet.GetMaxUsedIndex(); i++)
                { 
                    Object obj = m_permSet.GetItem(i);
                    IPermission perm = obj as IPermission;
#if FEATURE_CAS_POLICY
                    ISecurityElementFactory elem = obj as ISecurityElementFactory; 
#endif // FEATURE_CAS_POLICY
                    if (perm != null) 
                    { 
                        m_permSet.SetItem(i, perm.Copy());
                    } 
#if FEATURE_CAS_POLICY
                    else if (elem != null)
                    {
                        m_permSet.SetItem(i, elem.Copy()); 
                    }
#endif // FEATURE_CAS_POLICY 
                } 
            }
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        public virtual void CopyTo(Array array, int index)
        { 
            if (array == null)
                throw new ArgumentNullException( "array" ); 
            Contract.EndContractBlock(); 

            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this); 

            while (enumerator.MoveNext())
            {
                array.SetValue(enumerator.Current , index++ ); 
            }
        } 
 

        // private constructor that doesn't create any token based sets 
        private PermissionSet( Object trash, Object junk )
        {
            m_Unrestricted = false;
        } 

 
        // Returns an object appropriate for synchronizing access to this 
        // Array.
        public virtual Object SyncRoot 
        {  get { return this; } }

        // Is this Array synchronized (i.e., thread-safe)?  If you want a synchronized
        // collection, you can use SyncRoot as an object to synchronize your 
        // collection with.  You could also call GetSynchronized()
        // to get a synchronized wrapper around the Array. 
        public virtual bool IsSynchronized 
        {  get { return false; } }
 
        // Is this Collection ReadOnly?
        public virtual bool IsReadOnly
        {  get {return false; } }
 
        // Reinitializes all state in PermissionSet - DO NOT null-out m_serializedPermissionSet
        internal void Reset() 
        { 
            m_Unrestricted = false;
            m_allPermissionsDecoded = true; 
            m_permSet = null;

            m_ignoreTypeLoadFailures = false;
 
            m_CheckedForNonCas = false;
            m_ContainsCas = false; 
            m_ContainsNonCas = false; 
            m_permSetSaved = null;
 

        }

        internal void CheckSet() 
        {
            if (this.m_permSet == null) 
                this.m_permSet = new TokenBasedSet(); 
        }
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public bool IsEmpty()
        {
            if (m_Unrestricted) 
                return false;
 
            if (m_permSet == null || m_permSet.FastIsEmpty()) 
                return true;
 
            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);

            while (enumerator.MoveNext())
            { 
                IPermission perm = (IPermission)enumerator.Current;
 
                if (!perm.IsSubsetOf( null )) 
                {
                    return false; 
                }
            }

            return true; 
        }
 
        internal bool FastIsEmpty() 
        {
            if (m_Unrestricted) 
                return false;

            if (m_permSet == null || m_permSet.FastIsEmpty())
                return true; 

            return false; 
        } 

        public virtual int Count 
        {
            get
            {
                int count = 0; 

                if (m_permSet != null) 
                    count += m_permSet.GetCount(); 

                return count; 
            }
        }

        internal IPermission GetPermission(int index) 
        {
            if (m_permSet == null) 
                return null; 
            Object obj = m_permSet.GetItem( index );
            if (obj == null) 
                return null;
            IPermission perm = obj as IPermission;
            if (perm != null)
                return perm; 
#if FEATURE_CAS_POLICY
            perm = CreatePermission(obj, index); 
#endif // FEATURE_CAS_POLICY 
            if (perm == null)
                return null; 
            Contract.Assert( PermissionToken.IsTokenProperlyAssigned( perm, PermissionToken.GetToken( perm ) ),
                             "PermissionToken was improperly assigned" );
            Contract.Assert( PermissionToken.GetToken( perm ).m_index == index,
                             "Assigning permission to incorrect index in tokenbasedset" ); 
            return perm;
        } 
 
        internal IPermission GetPermission(PermissionToken permToken)
        { 
            if (permToken == null)
                return null;

            return GetPermission( permToken.m_index ); 
        }
 
        internal IPermission GetPermission( IPermission perm ) 
        {
            if (perm == null) 
                return null;

            return GetPermission(PermissionToken.GetToken( perm ));
        } 

#if FEATURE_CAS_POLICY 
        public IPermission GetPermission(Type permClass) 
        {
            return GetPermissionImpl(permClass); 
        }

        protected virtual IPermission GetPermissionImpl(Type permClass)
        { 
            if (permClass == null)
                return null; 
 
            return GetPermission(PermissionToken.FindToken(permClass));
        } 
#endif // FEATURE_CAS_POLICY

        public IPermission SetPermission(IPermission perm)
        { 
            return SetPermissionImpl(perm);
        } 
 
        // SetPermission overwrites a permission in a permissionset.
        protected virtual IPermission SetPermissionImpl(IPermission perm) 
        {
            // can't get token if perm is null
            if (perm == null)
                return null; 

            PermissionToken permToken = PermissionToken.GetToken(perm); 
 
            if ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0)
            { 
                // SetPermission Makes the Permission "Restricted"
                m_Unrestricted = false;
            }
 
            CheckSet();
 
            IPermission currPerm = GetPermission( permToken.m_index ); 

            m_CheckedForNonCas = false; 

            // Should we copy here?
            m_permSet.SetItem( permToken.m_index, perm );
            return perm; 
        }
 
        public IPermission AddPermission(IPermission perm) 
        {
            return AddPermissionImpl(perm); 
        }

        [System.Security.SecuritySafeCritical]  // auto-generated
        protected virtual IPermission AddPermissionImpl(IPermission perm) 
        {
            // can't get token if perm is null 
            if (perm == null) 
                return null;
 
            m_CheckedForNonCas = false;

            // If the permission set is unrestricted, then return an unrestricted instance
            // of perm. 

            PermissionToken permToken = PermissionToken.GetToken(perm); 
 
            if (this.IsUnrestricted() && ((permToken.m_type & PermissionTokenType.IUnrestricted) != 0))
            { 
                Type perm_type = perm.GetType();
                Object[] objs = new Object[1];
                objs[0] = PermissionState.Unrestricted;
                return (IPermission) Activator.CreateInstance(perm_type, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public, null, objs, null ); 
            }
 
            CheckSet(); 
            IPermission currPerm = GetPermission(permToken.m_index);
 
            // If a Permission exists in this slot, then union it with perm
            // Otherwise, just add perm.

            if (currPerm != null) { 
                IPermission ip_union = currPerm.Union(perm);
                m_permSet.SetItem( permToken.m_index, ip_union ); 
                return ip_union; 
            } else {
                // Should we copy here? 
                m_permSet.SetItem( permToken.m_index, perm );
                return perm;
            }
 
        }
 
        private IPermission RemovePermission( int index ) 
        {
            IPermission perm = GetPermission(index); 
            if (perm == null)
                return null;
            return (IPermission)m_permSet.RemoveItem( index ); // this cast is safe because the call to GetPermission will guarantee it is an IPermission
        } 

#if FEATURE_CAS_POLICY 
        public IPermission RemovePermission(Type permClass) 
        {
            return RemovePermissionImpl(permClass); 
        }

        protected virtual IPermission RemovePermissionImpl(Type permClass)
        { 
            if (permClass == null)
            { 
                return null; 
            }
 
            PermissionToken permToken = PermissionToken.FindToken(permClass);
            if (permToken == null)
            {
                return null; 
            }
 
            return RemovePermission(permToken.m_index); 
        }
#endif // FEATURE_CAS_POLICY 

        // Make this internal soon.
        internal void SetUnrestricted(bool unrestricted)
        { 
            m_Unrestricted = unrestricted;
            if (unrestricted) 
            { 
                // if this is to be an unrestricted permset, null the m_permSet member
                m_permSet = null; 
            }
        }

        public bool IsUnrestricted() 
        {
            return m_Unrestricted; 
        } 

        internal enum IsSubsetOfType 
        {
            Normal,
            CheckDemand,
            CheckPermitOnly, 
            CheckAssertion,
        } 
 
        internal bool IsSubsetOfHelper(PermissionSet target, IsSubsetOfType type, out IPermission firstPermThatFailed, bool ignoreNonCas)
        { 
    #if _DEBUG
            if (debug)
                DEBUG_WRITE("IsSubsetOf\n" +
                            "Other:\n" + 
                            (target == null ? "" : target.ToString()) +
                            "\nMe:\n" + 
                            ToString()); 
    #endif
 
            firstPermThatFailed = null;
            if (target == null || target.FastIsEmpty())
            {
                if(this.IsEmpty()) 
                    return true;
                else 
                { 
                    firstPermThatFailed = GetFirstPerm();
                    return false; 
                }
            }
            else if (this.IsUnrestricted() && !target.IsUnrestricted())
                return false; 
            else if (this.m_permSet == null)
                return true; 
            else 
            {
                target.CheckSet(); 

                for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i)
                {
                    IPermission thisPerm = this.GetPermission(i); 
                    if (thisPerm == null || thisPerm.IsSubsetOf(null))
                        continue; 
 
                    IPermission targetPerm = target.GetPermission(i);
#if _DEBUG 
                    PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
                    Contract.Assert(targetPerm == null || (token.m_type & PermissionTokenType.DontKnow) == 0, "Token not properly initialized");
#endif
 
                    if (target.m_Unrestricted)
                        continue; 
 
                    // targetPerm can be null here, but that is fine since it thisPerm is a subset
                    // of empty/null then we can continue in the loop. 
                    CodeAccessPermission cap = thisPerm as CodeAccessPermission;
                    if(cap == null)
                    {
                        if (!ignoreNonCas && !thisPerm.IsSubsetOf( targetPerm )) 
                        {
                            firstPermThatFailed = thisPerm; 
                            return false; 
                        }
                    } 
                    else
                    {
                        firstPermThatFailed = thisPerm;
                        switch(type) 
                        {
                        case IsSubsetOfType.Normal: 
                            if (!thisPerm.IsSubsetOf( targetPerm )) 
                                return false;
                            break; 
                        case IsSubsetOfType.CheckDemand:
                            if (!cap.CheckDemand( (CodeAccessPermission)targetPerm ))
                                return false;
                            break; 
                        case IsSubsetOfType.CheckPermitOnly:
                            if (!cap.CheckPermitOnly( (CodeAccessPermission)targetPerm )) 
                                return false; 
                            break;
                        case IsSubsetOfType.CheckAssertion: 
                            if (!cap.CheckAssert( (CodeAccessPermission)targetPerm ))
                                return false;
                            break;
                        } 
                        firstPermThatFailed = null;
                    } 
                } 
            }
 
            return true;
        }

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public bool IsSubsetOf(PermissionSet target)
        { 
            IPermission perm; 
            return IsSubsetOfHelper(target, IsSubsetOfType.Normal, out perm, false);
        } 

        internal bool CheckDemand(PermissionSet target, out IPermission firstPermThatFailed)
        {
            return IsSubsetOfHelper(target, IsSubsetOfType.CheckDemand, out firstPermThatFailed, true); 
        }
 
        internal bool CheckPermitOnly(PermissionSet target, out IPermission firstPermThatFailed) 
        {
            return IsSubsetOfHelper(target, IsSubsetOfType.CheckPermitOnly, out firstPermThatFailed, true); 
        }

        internal bool CheckAssertion(PermissionSet target)
        { 
            IPermission perm;
            return IsSubsetOfHelper(target, IsSubsetOfType.CheckAssertion, out perm, true); 
        } 

        internal bool CheckDeny(PermissionSet deniedSet, out IPermission firstPermThatFailed) 
        {
            firstPermThatFailed = null;
            if (deniedSet == null || deniedSet.FastIsEmpty() || this.FastIsEmpty())
                return true; 

            if(this.m_Unrestricted && deniedSet.m_Unrestricted) 
                return false; 

            CodeAccessPermission permThis, permThat; 
            PermissionSetEnumeratorInternal enumThis = new PermissionSetEnumeratorInternal(this);

            while (enumThis.MoveNext())
            { 
                permThis = enumThis.Current as CodeAccessPermission;
                if(permThis == null || permThis.IsSubsetOf(null)) 
                    continue; // ignore non-CAS permissions in the grant set. 
                if (deniedSet.m_Unrestricted)
                { 
                    firstPermThatFailed = permThis;
                    return false;
                }
                permThat = (CodeAccessPermission)deniedSet.GetPermission(enumThis.GetCurrentIndex()); 
                if (!permThis.CheckDeny(permThat))
                { 
                    firstPermThatFailed = permThis; 
                    return false;
                } 
            }
            if(this.m_Unrestricted)
            {
                PermissionSetEnumeratorInternal enumThat = new PermissionSetEnumeratorInternal(deniedSet); 
                while (enumThat.MoveNext())
                { 
                    if(enumThat.Current is IPermission) 
                        return false;
                } 
            }
            return true;
        }
 
        internal void CheckDecoded( CodeAccessPermission demandedPerm, PermissionToken tokenDemandedPerm )
        { 
            Contract.Assert( demandedPerm != null, "Expected non-null value" ); 

            if (this.m_allPermissionsDecoded || this.m_permSet == null) 
                return;

            if (tokenDemandedPerm == null)
                tokenDemandedPerm = PermissionToken.GetToken( demandedPerm ); 

            Contract.Assert( tokenDemandedPerm != null, "Unable to find token for demanded permission" ); 
 
            CheckDecoded( tokenDemandedPerm.m_index );
        } 

        internal void CheckDecoded( int index )
        {
            if (this.m_allPermissionsDecoded || this.m_permSet == null) 
                return;
 
            GetPermission(index); 
        }
 
        internal void CheckDecoded(PermissionSet demandedSet)
        {
            Contract.Assert(demandedSet != null, "Expected non-null value");
 
            if (this.m_allPermissionsDecoded || this.m_permSet == null)
                return; 
 
            PermissionSetEnumeratorInternal enumerator = demandedSet.GetEnumeratorInternal();
 
            while (enumerator.MoveNext())
            {
                CheckDecoded(enumerator.GetCurrentIndex());
            } 
        }
 
#if FEATURE_CAS_POLICY 
        static internal void SafeChildAdd( SecurityElement parent, ISecurityElementFactory child, bool copy )
        { 
            if (child == parent)
                return;
            if (child.GetTag().Equals( "IPermission" ) || child.GetTag().Equals( "Permission" ))
            { 
                parent.AddChild( child );
            } 
            else if (parent.Tag.Equals( child.GetTag() )) 
            {
                Contract.Assert( child is SecurityElement, "SecurityElement expected" ); 
                SecurityElement elChild = (SecurityElement)child;
                Contract.Assert( elChild.InternalChildren != null,
                    "Non-permission elements should have children" );
 
                for (int i = 0; i < elChild.InternalChildren.Count; ++i)
                { 
                    ISecurityElementFactory current = (ISecurityElementFactory)elChild.InternalChildren[i]; 
                    Contract.Assert( !current.GetTag().Equals( parent.Tag ),
                        "Illegal to insert a like-typed element" ); 
                    parent.AddChildNoDuplicates( current );
                }
            }
            else 
            {
                parent.AddChild( (ISecurityElementFactory)(copy ? child.Copy() : child) ); 
            } 
        }
#endif // FEATURE_CAS_POLICY 

        internal void InplaceIntersect( PermissionSet other )
        {
            Exception savedException = null; 

            m_CheckedForNonCas = false; 
 
            if (this == other)
                return; 

            if (other == null || other.FastIsEmpty())
            {
                // If the other is empty or null, make this empty. 
                Reset();
                return; 
            } 

            if (this.FastIsEmpty()) 
                return;

            int maxMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex();
            int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex(); 

            if (this.IsUnrestricted() && maxMax < otherMax) 
            { 
                maxMax = otherMax;
                this.CheckSet(); 
            }

            if (other.IsUnrestricted())
            { 
                other.CheckSet();
            } 
 
            for (int i = 0; i <= maxMax; ++i)
            { 
                Object thisObj = this.m_permSet.GetItem( i );
                IPermission thisPerm = thisObj as IPermission;
#if FEATURE_CAS_POLICY
                ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory; 
#endif // FEATURE_CAS_POLICY
 
                Object otherObj = other.m_permSet.GetItem( i ); 
                IPermission otherPerm = otherObj as IPermission;
#if FEATURE_CAS_POLICY 
                ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY

                if (thisObj == null && otherObj == null) 
                    continue;
 
#if FEATURE_CAS_POLICY 
                if (thisElem != null && otherElem != null)
                { 
                    // If we already have an intersection node, just add another child
                    if (thisElem.GetTag().Equals( s_str_PermissionIntersection ) ||
                        thisElem.GetTag().Equals( s_str_PermissionUnrestrictedIntersection ))
                    { 
                        Contract.Assert( thisElem is SecurityElement, "SecurityElement expected" );
                        SafeChildAdd( (SecurityElement)thisElem, otherElem, true ); 
                    } 
                    // If either set is unrestricted, intersect the nodes unrestricted
                    else 
                    {
                        bool copyOther = true;
                        if (this.IsUnrestricted())
                        { 
                            SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
                            newElemUU.AddAttribute( "class", thisElem.Attribute( "class" ) ); 
                            SafeChildAdd( newElemUU, thisElem, false ); 
                            thisElem = newElemUU;
                        } 
                        if (other.IsUnrestricted())
                        {
                            SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
                            newElemUU.AddAttribute( "class", otherElem.Attribute( "class" ) ); 
                            SafeChildAdd( newElemUU, otherElem, true );
                            otherElem = newElemUU; 
                            copyOther = false; 
                        }
 
                        SecurityElement newElem = new SecurityElement( s_str_PermissionIntersection );
                        newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );

                        SafeChildAdd( newElem, thisElem, false ); 
                        SafeChildAdd( newElem, otherElem, copyOther );
                        this.m_permSet.SetItem( i, newElem ); 
                    } 
                }
                else 
#endif // FEATURE_CAS_POLICY
                if (thisObj == null)
                {
                    // There is no object in , so intersection is empty except for IUnrestrictedPermissions 
                    if (this.IsUnrestricted())
                    { 
#if FEATURE_CAS_POLICY 
                        if (otherElem != null)
                        { 
                            SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
                            newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
                            SafeChildAdd( newElem, otherElem, true );
                            this.m_permSet.SetItem( i, newElem ); 
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                        } 
                        else 
#endif // FEATURE_CAS_POLICY
                        { 
                            PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
                            if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
                            {
                                this.m_permSet.SetItem( i, otherPerm.Copy() ); 
                                Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                            } 
                        } 
                    }
                } 
                else if (otherObj == null)
                {
                    if (other.IsUnrestricted())
                    { 
#if FEATURE_CAS_POLICY
                        if (thisElem != null) 
                        { 
                            SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
                            newElem.AddAttribute( "class", thisElem.Attribute( "class" ) ); 
                            SafeChildAdd( newElem, thisElem, false );
                            this.m_permSet.SetItem( i, newElem );
                        }
                        else 
#endif // FEATURE_CAS_POLICY
                        { 
                            PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); 
                            if ((token.m_type & PermissionTokenType.IUnrestricted) == 0)
                                this.m_permSet.SetItem( i, null ); 
                        }
                    }
                    else
                    { 
                        this.m_permSet.SetItem( i, null );
                    } 
                } 
                else
                { 
#if FEATURE_CAS_POLICY
                    if (thisElem != null)
                        thisPerm = this.CreatePermission(thisElem, i);
                    if (otherElem != null) 
                        otherPerm = other.CreatePermission(otherElem, i);
#endif // FEATURE_CAS_POLICY 
 
                    try
                    { 
                        IPermission intersectPerm;
                        if (thisPerm == null)
                            intersectPerm = otherPerm;
                        else if(otherPerm == null) 
                            intersectPerm = thisPerm;
                        else 
                            intersectPerm = thisPerm.Intersect( otherPerm ); 
                        this.m_permSet.SetItem( i, intersectPerm );
                    } 
                    catch (Exception e)
                    {
                        if (savedException == null)
                            savedException = e; 
                    }
                } 
            } 

            this.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted; 

            if (savedException != null)
                throw savedException;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        public PermissionSet Intersect(PermissionSet other) 
        {
            if (other == null || other.FastIsEmpty() || this.FastIsEmpty()) 
            {
                return null;
            }
 
            int thisMax = this.m_permSet == null ? -1 : this.m_permSet.GetMaxUsedIndex();
            int otherMax = other.m_permSet == null ? -1 : other.m_permSet.GetMaxUsedIndex(); 
            int minMax = thisMax < otherMax ? thisMax : otherMax; 

            if (this.IsUnrestricted() && minMax < otherMax) 
            {
                minMax = otherMax;
                this.CheckSet();
            } 

            if (other.IsUnrestricted() && minMax < thisMax) 
            { 
                minMax = thisMax;
                other.CheckSet(); 
            }

            PermissionSet pset = new PermissionSet( false );
 
            if (minMax > -1)
            { 
                pset.m_permSet = new TokenBasedSet(); 
            }
 
            for (int i = 0; i <= minMax; ++i)
            {
                Object thisObj = this.m_permSet.GetItem( i );
                IPermission thisPerm = thisObj as IPermission; 
#if FEATURE_CAS_POLICY
                ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory; 
#endif // FEATURE_CAS_POLICY 

                Object otherObj = other.m_permSet.GetItem( i ); 
                IPermission otherPerm = otherObj as IPermission;
#if FEATURE_CAS_POLICY
                ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY 

                if (thisObj == null && otherObj == null) 
                    continue; 

#if FEATURE_CAS_POLICY 
                if (thisElem != null && otherElem != null)
                {
                    bool copyOther = true;
                    bool copyThis = true; 
                    SecurityElement newElem = new SecurityElement( s_str_PermissionIntersection );
                    newElem.AddAttribute( "class", otherElem.Attribute( "class" ) ); 
                    if (this.IsUnrestricted()) 
                    {
                        SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion ); 
                        newElemUU.AddAttribute( "class", thisElem.Attribute( "class" ) );
                        SafeChildAdd( newElemUU, thisElem, true );
                        copyThis = false;
                        thisElem = newElemUU; 
                    }
                    if (other.IsUnrestricted()) 
                    { 
                        SecurityElement newElemUU = new SecurityElement( s_str_PermissionUnrestrictedUnion );
                        newElemUU.AddAttribute( "class", otherElem.Attribute( "class" ) ); 
                        SafeChildAdd( newElemUU, otherElem, true );
                        copyOther = false;
                        otherElem = newElemUU;
                    } 

                    SafeChildAdd( newElem, otherElem, copyOther ); 
                    SafeChildAdd( newElem, thisElem, copyThis ); 
                    pset.m_permSet.SetItem( i, newElem );
                } 
                else
#endif // FEATURE_CAS_POLICY
                if (thisObj == null)
                { 
                    if (this.m_Unrestricted)
                    { 
#if FEATURE_CAS_POLICY 
                        if (otherElem != null)
                        { 
                            SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection );
                            newElem.AddAttribute( "class", otherElem.Attribute( "class" ) );
                            SafeChildAdd( newElem, otherElem, true );
                            pset.m_permSet.SetItem( i, newElem ); 
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                        } 
                        else 
#endif // FEATURE_CAS_POLICY
                        if (otherPerm != null) 
                        {
                            PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
                            if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
                            { 
                                pset.m_permSet.SetItem( i, otherPerm.Copy() );
                                Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); 
                            } 
                        }
                    } 
                }
                else if (otherObj == null)
                {
                    if (other.m_Unrestricted) 
                    {
#if FEATURE_CAS_POLICY 
                        if (thisElem != null) 
                        {
                            SecurityElement newElem = new SecurityElement( s_str_PermissionUnrestrictedIntersection ); 
                            newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
                            SafeChildAdd( newElem, thisElem, true );
                            pset.m_permSet.SetItem( i, newElem );
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); 
                        }
                        else 
#endif // FEATURE_CAS_POLICY 
                        if (thisPerm != null)
                        { 
                            PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i );
                            if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
                            {
                                pset.m_permSet.SetItem( i, thisPerm.Copy() ); 
                                Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                            } 
                        } 
                    }
                } 
                else
                {
#if FEATURE_CAS_POLICY
                    if (thisElem != null) 
                        thisPerm = this.CreatePermission(thisElem, i);
                    if (otherElem != null) 
                        otherPerm = other.CreatePermission(otherElem, i); 
#endif // FEATURE_CAS_POLICY
 
                    IPermission intersectPerm;
                    if (thisPerm == null)
                        intersectPerm = otherPerm;
                    else if(otherPerm == null) 
                        intersectPerm = thisPerm;
                    else 
                        intersectPerm = thisPerm.Intersect( otherPerm ); 
                    pset.m_permSet.SetItem( i, intersectPerm );
                    Contract.Assert( intersectPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); 
                }
            }

            pset.m_Unrestricted = this.m_Unrestricted && other.m_Unrestricted; 
            if (pset.FastIsEmpty())
                return null; 
            else 
                return pset;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        internal void InplaceUnion( PermissionSet other )
        { 
            // Unions the "other" PermissionSet into this one.  It can be optimized to do less copies than
            // need be done by the traditional union (and we don't have to create a new PermissionSet). 
 
            if (this == other)
                return; 

            // Quick out conditions, union doesn't change this PermissionSet
            if (other == null || other.FastIsEmpty())
                return; 

 
            m_CheckedForNonCas = false; 

 


            this.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
 
            if (this.m_Unrestricted)
            { 
                // if the result of Union is unrestricted permset, null the m_permSet member 
                this.m_permSet = null;
                return; 
            }


            // If we reach here, result of Union is not unrestricted 
            // We have to union "normal" permission no matter what now.
            int maxMax = -1; 
            if (other.m_permSet != null) 
            {
                maxMax = other.m_permSet.GetMaxUsedIndex(); 
                this.CheckSet();
            }
            // Save exceptions until the end
            Exception savedException = null; 

            for (int i = 0; i <= maxMax; ++i) 
            { 
                Object thisObj = this.m_permSet.GetItem( i );
                IPermission thisPerm = thisObj as IPermission; 
#if FEATURE_CAS_POLICY
                ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY
 
                Object otherObj = other.m_permSet.GetItem( i );
                IPermission otherPerm = otherObj as IPermission; 
#if FEATURE_CAS_POLICY 
                ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY 

                if (thisObj == null && otherObj == null)
                    continue;
 
#if FEATURE_CAS_POLICY
                if (thisElem != null && otherElem != null) 
                { 
                    if (thisElem.GetTag().Equals( s_str_PermissionUnion ) ||
                        thisElem.GetTag().Equals( s_str_PermissionUnrestrictedUnion )) 
                    {
                        Contract.Assert( thisElem is SecurityElement, "SecurityElement expected" );
                        SafeChildAdd( (SecurityElement)thisElem, otherElem, true );
                    } 
                    else
                    { 
                        SecurityElement newElem; 
                        if (this.IsUnrestricted() || other.IsUnrestricted())
                            newElem = new SecurityElement( s_str_PermissionUnrestrictedUnion ); 
                        else
                            newElem = new SecurityElement( s_str_PermissionUnion );
                        newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
                        SafeChildAdd( newElem, thisElem, false ); 
                        SafeChildAdd( newElem, otherElem, true );
                        this.m_permSet.SetItem( i, newElem ); 
                    } 
                }
                else 
#endif // FEATURE_CAS_POLICY
                if (thisObj == null)
                {
#if FEATURE_CAS_POLICY 
                    if (otherElem != null)
                    { 
                        this.m_permSet.SetItem( i, otherElem.Copy() ); 
                    }
                    else 
#endif // FEATURE_CAS_POLICY
                    if (otherPerm != null)
                    {
                        PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); 
                        if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !this.m_Unrestricted)
                        { 
                            this.m_permSet.SetItem( i, otherPerm.Copy() ); 
                        }
                    } 
                }
                else if (otherObj == null)
                {
                    continue; 
                }
                else 
                { 
#if FEATURE_CAS_POLICY
                    if (thisElem != null) 
                        thisPerm = this.CreatePermission(thisElem, i);
                    if (otherElem != null)
                        otherPerm = other.CreatePermission(otherElem, i);
#endif // FEATURE_CAS_POLICY 

                    try 
                    { 
                        IPermission unionPerm;
                        if(thisPerm == null) 
                            unionPerm = otherPerm;
                        else if(otherPerm == null)
                            unionPerm = thisPerm;
                        else 
                            unionPerm = thisPerm.Union( otherPerm );
                        this.m_permSet.SetItem( i, unionPerm ); 
                    } 
                    catch (Exception e)
                    { 
                        if (savedException == null)
                            savedException = e;
                    }
                } 
            }
 
            if (savedException != null) 
                throw savedException;
        } 

        [System.Security.SecuritySafeCritical]  // auto-generated
        public PermissionSet Union(PermissionSet other)
        { 
            // if other is null or empty, return a clone of myself
            if (other == null || other.FastIsEmpty()) 
            { 
                return this.Copy();
            } 

            if (this.FastIsEmpty())
            {
                return other.Copy(); 
            }
 
            int maxMax = -1; 

            PermissionSet pset = new PermissionSet(); 
            pset.m_Unrestricted = this.m_Unrestricted || other.m_Unrestricted;
            if (pset.m_Unrestricted)
            {
                // if the result of Union is unrestricted permset, just return 
                return pset;
            } 
 
            // degenerate case where we look at both this.m_permSet and other.m_permSet
            this.CheckSet(); 
            other.CheckSet();
            maxMax = this.m_permSet.GetMaxUsedIndex() > other.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : other.m_permSet.GetMaxUsedIndex();
            pset.m_permSet = new TokenBasedSet();
 

 
            for (int i = 0; i <= maxMax; ++i) 
            {
                Object thisObj = this.m_permSet.GetItem( i ); 
                IPermission thisPerm = thisObj as IPermission;
#if FEATURE_CAS_POLICY
                ISecurityElementFactory thisElem = thisObj as ISecurityElementFactory;
#endif // FEATURE_CAS_POLICY 

                Object otherObj = other.m_permSet.GetItem( i ); 
                IPermission otherPerm = otherObj as IPermission; 
#if FEATURE_CAS_POLICY
                ISecurityElementFactory otherElem = otherObj as ISecurityElementFactory; 
#endif // FEATURE_CAS_POLICY

                if (thisObj == null && otherObj == null)
                    continue; 

#if FEATURE_CAS_POLICY 
                if (thisElem != null && otherElem != null) 
                {
                    SecurityElement newElem; 
                    if (this.IsUnrestricted() || other.IsUnrestricted())
                        newElem = new SecurityElement( s_str_PermissionUnrestrictedUnion );
                    else
                        newElem = new SecurityElement( s_str_PermissionUnion ); 
                    newElem.AddAttribute( "class", thisElem.Attribute( "class" ) );
                    SafeChildAdd( newElem, thisElem, true ); 
                    SafeChildAdd( newElem, otherElem, true ); 
                    pset.m_permSet.SetItem( i, newElem );
                } 
                else
#endif // FEATURE_CAS_POLICY
                if (thisObj == null)
                { 
#if FEATURE_CAS_POLICY
                    if (otherElem != null) 
                    { 
                        pset.m_permSet.SetItem( i, otherElem.Copy() );
                        Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" ); 
                    }
                    else
#endif // FEATURE_CAS_POLICY
                    if (otherPerm != null) 
                    {
                        PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); 
                        if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted) 
                        {
                            pset.m_permSet.SetItem( i, otherPerm.Copy() ); 
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                        }
                    }
                } 
                else if (otherObj == null)
                { 
#if FEATURE_CAS_POLICY 
                    if (thisElem != null)
                    { 
                        pset.m_permSet.SetItem( i, thisElem.Copy() );
                    }
                    else
#endif // FEATURE_CAS_POLICY 
                    if (thisPerm != null)
                    { 
                        PermissionToken token = (PermissionToken)PermissionToken.s_tokenSet.GetItem( i ); 
                        if (((token.m_type & PermissionTokenType.IUnrestricted) == 0) || !pset.m_Unrestricted)
                        { 
                            pset.m_permSet.SetItem( i, thisPerm.Copy() );
                            Contract.Assert( PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                        }
                    } 
                }
                else 
                { 
#if FEATURE_CAS_POLICY
                    if (thisElem != null) 
                        thisPerm = this.CreatePermission(thisElem, i);
                    if (otherElem != null)
                        otherPerm = other.CreatePermission(otherElem, i);
#endif // FEATURE_CAS_POLICY 

                    IPermission unionPerm; 
                    if(thisPerm == null) 
                        unionPerm = otherPerm;
                    else if(otherPerm == null) 
                        unionPerm = thisPerm;
                    else
                        unionPerm = thisPerm.Union( otherPerm );
                    pset.m_permSet.SetItem( i, unionPerm ); 
                    Contract.Assert( unionPerm == null || PermissionToken.s_tokenSet.GetItem( i ) != null, "PermissionToken should already be assigned" );
                } 
            } 

            return pset; 
        }

        // Treating the current permission set as a grant set, and the input set as
        // a set of permissions to be denied, try to cancel out as many permissions 
        // from both sets as possible. For a first cut, any granted permission that
        // is a safe subset of the corresponding denied permission can result in 
        // that permission being removed from both sides. 

        internal void MergeDeniedSet(PermissionSet denied) 
        {
            if (denied == null || denied.FastIsEmpty() || this.FastIsEmpty())
                return;
 
            m_CheckedForNonCas = false;
 
            // Check for the unrestricted case: FastIsEmpty() will return false if the PSet is unrestricted, but has no items 
            if (this.m_permSet == null || denied.m_permSet == null)
                return; //nothing can be removed 

            int maxIndex = denied.m_permSet.GetMaxUsedIndex() > this.m_permSet.GetMaxUsedIndex() ? this.m_permSet.GetMaxUsedIndex() : denied.m_permSet.GetMaxUsedIndex();
            for (int i = 0; i <= maxIndex; ++i) {
                IPermission deniedPerm = denied.m_permSet.GetItem(i) as IPermission; 
                if (deniedPerm == null)
                    continue; 
 
                IPermission thisPerm = this.m_permSet.GetItem(i) as IPermission;
 
                if (thisPerm == null && !this.m_Unrestricted) {
                    denied.m_permSet.SetItem(i, null);
                    continue;
                } 

                if (thisPerm != null && deniedPerm != null) { 
                    if (thisPerm.IsSubsetOf(deniedPerm)) { 
                        this.m_permSet.SetItem(i, null);
                        denied.m_permSet.SetItem(i, null); 
                    }
                }
            }
        } 

        // Returns true if perm is contained in this 
        internal bool Contains(IPermission perm) 
        {
            if (perm == null) 
                return true;
            if (m_Unrestricted)
                return true;
            if (FastIsEmpty()) 
                return false;
 
            PermissionToken token = PermissionToken.GetToken(perm); 
            Object thisObj = this.m_permSet.GetItem( token.m_index );
            if (thisObj == null) 
                return perm.IsSubsetOf( null );

            IPermission thisPerm = GetPermission(token.m_index);
            if (thisPerm != null) 
                return perm.IsSubsetOf( thisPerm );
            else 
                return perm.IsSubsetOf( null ); 
        }
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public override bool Equals( Object obj )
        {
            // Note: this method is designed to accept both PermissionSet and NamedPermissionSets. 
            // It will compare them based on the values in the base type, thereby ignoring the
            // name and description of the named permission set. 
 
            PermissionSet other = obj as PermissionSet;
 
            if (other == null)
                return false;

            if (this.m_Unrestricted != other.m_Unrestricted) 
                return false;
 
            CheckSet(); 
            other.CheckSet();
 
            DecodeAllPermissions();
            other.DecodeAllPermissions();

            int maxIndex = Math.Max( this.m_permSet.GetMaxUsedIndex(), other.m_permSet.GetMaxUsedIndex() ); 

            for (int i = 0; i <= maxIndex; ++i) 
            { 
                IPermission thisPerm = (IPermission)this.m_permSet.GetItem( i );
                IPermission otherPerm = (IPermission)other.m_permSet.GetItem( i ); 

                if (thisPerm == null && otherPerm == null)
                {
                    continue; 
                }
                else if (thisPerm == null) 
                { 
                    if (!otherPerm.IsSubsetOf( null ))
                        return false; 
                }
                else if (otherPerm == null)
                {
                    if (!thisPerm.IsSubsetOf( null )) 
                        return false;
                } 
                else 
                {
                    if (!thisPerm.Equals( otherPerm )) 
                        return false;
                }
            }
 
            return true;
        } 
 
        [System.Runtime.InteropServices.ComVisible(false)]
        public override int GetHashCode() 
        {
            int accumulator;

            accumulator = this.m_Unrestricted ? -1 : 0; 

            if (this.m_permSet != null) 
            { 
                DecodeAllPermissions();
 
                int maxIndex = this.m_permSet.GetMaxUsedIndex();

                for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i)
                { 
                    IPermission perm = (IPermission)this.m_permSet.GetItem( i );
                    if (perm != null) 
                    { 
                        accumulator = accumulator ^ perm.GetHashCode();
                    } 
                }
            }

            return accumulator; 
        }
 
        // Mark this method as requiring a security object on the caller's frame 
        // so the caller won't be inlined (which would mess up stack crawling).
        [System.Security.SecuritySafeCritical]  // auto-generated 
        [DynamicSecurityMethodAttribute()]
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public void Demand()
        { 
            if (this.FastIsEmpty())
                return;  // demanding the empty set always passes. 
 
            ContainsNonCodeAccessPermissions();
 
            if (m_ContainsCas)
            {
                StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller;
                CodeAccessSecurityEngine.Check(GetCasOnlySet(), ref stackMark); 
            }
            if (m_ContainsNonCas) 
            { 
                DemandNonCAS();
            } 
        }

        [System.Security.SecurityCritical]  // auto-generated
        internal void DemandNonCAS() 
        {
            ContainsNonCodeAccessPermissions(); 
 
            if (m_ContainsNonCas)
            { 
                if (this.m_permSet != null)
                {
                    CheckSet();
                    for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i) 
                    {
                        IPermission currPerm = GetPermission(i); 
                        if (currPerm != null && !(currPerm is CodeAccessPermission)) 
                            currPerm.Demand();
                    } 
                }
            }
        }
 
        // Metadata for this method should be flaged with REQ_SQ so that
        // EE can allocate space on the stack frame for FrameSecurityDescriptor 
 
        [System.Security.SecuritySafeCritical]  // auto-generated
        [DynamicSecurityMethodAttribute()] 
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public void Assert()
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; 
            SecurityRuntime.Assert(this, ref stackMark);
        } 
 
        // Metadata for this method should be flaged with REQ_SQ so that
        // EE can allocate space on the stack frame for FrameSecurityDescriptor 

        [System.Security.SecuritySafeCritical]  // auto-generated
        [DynamicSecurityMethodAttribute()]
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable 
        [Obsolete("Deny is obsolete and will be removed in a future release of the .NET Framework. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")]
        public void Deny() 
        { 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            SecurityRuntime.Deny(this, ref stackMark); 
        }

        // Metadata for this method should be flaged with REQ_SQ so that
        // EE can allocate space on the stack frame for FrameSecurityDescriptor 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [DynamicSecurityMethodAttribute()] 
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable
        public void PermitOnly() 
        {
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            SecurityRuntime.PermitOnly(this, ref stackMark);
        } 

        internal IPermission GetFirstPerm() 
        { 
            IEnumerator enumerator = GetEnumerator();
            if(!enumerator.MoveNext()) 
                return null;
            return enumerator.Current as IPermission;
        }
 
        // Returns a deep copy
        public virtual PermissionSet Copy() 
        { 
            return new PermissionSet(this);
        } 

        internal PermissionSet CopyWithNoIdentityPermissions()
        {
            // Explicitly make a new PermissionSet, rather than copying, since we may have a 
            // ReadOnlyPermissionSet which cannot have identity permissions removed from it in a true copy.
            PermissionSet copy = new PermissionSet(this); 
 
            // There's no easy way to distinguish an identity permission from any other CodeAccessPermission,
            // so remove them directly. 
#if FEATURE_CAS_POLICY
            copy.RemovePermission(typeof(GacIdentityPermission));
#endif // FEATURE_CAS_POLICY
#if !FEATURE_PAL && FEATURE_X509 && FEATURE_CAS_POLICY 
            copy.RemovePermission(typeof(PublisherIdentityPermission));
#endif 
#if FEATURE_CAS_POLICY 
            copy.RemovePermission(typeof(StrongNameIdentityPermission));
            copy.RemovePermission(typeof(UrlIdentityPermission)); 
            copy.RemovePermission(typeof(ZoneIdentityPermission));
#endif // FEATURE_CAS_POLICY

            return copy; 
        }
 
        public IEnumerator GetEnumerator() 
        {
            return GetEnumeratorImpl(); 
        }

        protected virtual IEnumerator GetEnumeratorImpl()
        { 
            return new PermissionSetEnumerator(this);
        } 
 
        internal PermissionSetEnumeratorInternal GetEnumeratorInternal()
        { 
            return new PermissionSetEnumeratorInternal(this);
        }

#if FEATURE_CAS_POLICY 
        [System.Security.SecuritySafeCritical]  // auto-generated
        public override String ToString() 
        { 
            return ToXml().ToString();
        } 
#endif // FEATURE_CAS_POLICY

        private void NormalizePermissionSet()
        { 
            // This function guarantees that all the permissions are placed at
            // the proper index within the token based sets.  This becomes necessary 
            // since these indices are dynamically allocated based on usage order. 

            PermissionSet permSetTemp = new PermissionSet(false); 

            permSetTemp.m_Unrestricted = this.m_Unrestricted;

            // Move all the normal permissions to the new permission set 

            if (this.m_permSet != null) 
            { 
                for (int i = m_permSet.GetStartingIndex(); i <= this.m_permSet.GetMaxUsedIndex(); ++i)
                { 
                    Object obj = this.m_permSet.GetItem(i);
                    IPermission perm = obj as IPermission;
#if FEATURE_CAS_POLICY
                    ISecurityElementFactory elem = obj as ISecurityElementFactory; 

                    if (elem != null) 
                        perm = CreatePerm( elem ); 
#endif // FEATURE_CAS_POLICY
                    if (perm != null) 
                        permSetTemp.SetPermission( perm );
                }
            }
 
            this.m_permSet = permSetTemp.m_permSet;
        } 
 
#if FEATURE_CAS_POLICY
        private bool DecodeXml(byte[] data, HostProtectionResource fullTrustOnlyResources, HostProtectionResource inaccessibleResources ) 
        {
            if (data != null && data.Length > 0)
            {
                FromXml( new Parser( data, Tokenizer.ByteTokenEncoding.UnicodeTokens ).GetTopElement() ); 
            }
 
            FilterHostProtectionPermissions(fullTrustOnlyResources, inaccessibleResources); 

            // We call this method from unmanaged to code a set we are going to use declaratively.  In 
            // this case, all the lazy evaluation for partial policy resolution is wasted since we'll
            // need to decode all of these shortly to make the demand for whatever.  Therefore, we
            // pay that price now so that we can calculate whether all the permissions in the set
            // implement the IUnrestrictedPermission interface (the common case) for use in some 
            // unmanaged optimizations.
 
            DecodeAllPermissions(); 

            return true; 
        }
#endif // FEATURE_CAS_POLICY

        private void DecodeAllPermissions() 
        {
            if (m_permSet == null) 
            { 
                m_allPermissionsDecoded = true;
                return; 
            }

            int maxIndex = m_permSet.GetMaxUsedIndex();
            for (int i = 0; i <= maxIndex; ++i) 
            {
                // GetPermission has the side-effect of decoding the permission in the slot 
                GetPermission(i); 
            }
 
            m_allPermissionsDecoded = true;
        }

        internal void FilterHostProtectionPermissions(HostProtectionResource fullTrustOnly, HostProtectionResource inaccessible) 
        {
            HostProtectionPermission.protectedResources = fullTrustOnly; 
            HostProtectionPermission hpp = (HostProtectionPermission)GetPermission(HostProtectionPermission.GetTokenIndex()); 
            if(hpp == null)
                return; 

            HostProtectionPermission newHpp = (HostProtectionPermission)hpp.Intersect(new HostProtectionPermission(fullTrustOnly));
            if (newHpp == null)
            { 
#if FEATURE_CAS_POLICY
                RemovePermission(typeof(HostProtectionPermission)); 
#else // !FEATURE_CAS_POLICY 
                RemovePermission(HostProtectionPermission.GetTokenIndex());
#endif // FEATURE_CAS_POLICY 
            }
            else if (newHpp.Resources != hpp.Resources)
            {
                SetPermission(newHpp); 
            }
        } 
 
#if FEATURE_CAS_POLICY
        public virtual void FromXml( SecurityElement et ) 
        {
            FromXml( et, false, false );
        }
 
        internal static bool IsPermissionTag( String tag, bool allowInternalOnly )
        { 
            if (tag.Equals( s_str_Permission ) || 
                tag.Equals( s_str_IPermission ))
            { 
                return true;
            }

            if (allowInternalOnly && 
                (tag.Equals( s_str_PermissionUnion ) ||
                 tag.Equals( s_str_PermissionIntersection ) || 
                 tag.Equals( s_str_PermissionUnrestrictedIntersection ) || 
                 tag.Equals( s_str_PermissionUnrestrictedUnion)))
            { 
                return true;
            }

            return false; 
        }
 
        internal virtual void FromXml( SecurityElement et, bool allowInternalOnly, bool ignoreTypeLoadFailures ) 
        {
            if (et == null) 
                throw new ArgumentNullException("et");

            if (!et.Tag.Equals(s_str_PermissionSet))
                throw new ArgumentException(String.Format( null, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PermissionSet", this.GetType().FullName) ); 
            Contract.EndContractBlock();
 
            Reset(); 
            m_ignoreTypeLoadFailures = ignoreTypeLoadFailures;
            m_allPermissionsDecoded = false; 
            m_Unrestricted = XMLUtil.IsUnrestricted( et );

            if (et.InternalChildren != null)
            { 
                int childCount = et.InternalChildren.Count;
                for (int i = 0; i < childCount; ++i) 
                { 
                    SecurityElement elem = (SecurityElement)et.Children[i];
 
                    if (IsPermissionTag( elem.Tag, allowInternalOnly ))
                    {
                        String className = elem.Attribute( "class" );
 
                        PermissionToken token;
                        Object objectToInsert; 
 
                        if (className != null)
                        { 
                            token = PermissionToken.GetToken( className );
                            if (token == null)
                            {
                                objectToInsert = CreatePerm( elem ); 
#if _DEBUG
                                PermissionToken tokenDebug = PermissionToken.GetToken( (IPermission)objectToInsert ); 
                                Contract.Assert( tokenDebug != null && (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins" ); 
#endif
                                if (objectToInsert != null) 
                                {
                                    Contract.Assert( objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(),
                                        "PermissionToken.GetToken returned null for non-mscorlib permission" );
                                    token = PermissionToken.GetToken( (IPermission)objectToInsert ); 
                                    Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance" );
                                } 
                            } 
                            else
                            { 
                                objectToInsert = elem;
                            }
                        }
                        else 
                        {
                            IPermission ip = CreatePerm( elem ); 
                            if (ip == null) 
                            {
                                token = null; 
                                objectToInsert = null;
                            }
                            else
                            { 
                                token = PermissionToken.GetToken( ip );
                                Contract.Assert( PermissionToken.IsTokenProperlyAssigned( ip, token ), 
                                                 "PermissionToken was improperly assigned" ); 
                                objectToInsert = ip;
                            } 
                        }

                        if (token != null && objectToInsert != null)
                        { 
                            if (m_permSet == null)
                                m_permSet = new TokenBasedSet(); 
 
                            if (this.m_permSet.GetItem( token.m_index ) != null)
                            { 
                                // If there is already something in that slot, let's union them
                                // together.

                                IPermission permInSlot; 

                                if (this.m_permSet.GetItem( token.m_index ) is IPermission) 
                                    permInSlot = (IPermission)this.m_permSet.GetItem( token.m_index ); 
                                else
                                    permInSlot = CreatePerm( (SecurityElement)this.m_permSet.GetItem( token.m_index ) ); 

                                if (objectToInsert is IPermission)
                                    objectToInsert = ((IPermission)objectToInsert).Union( permInSlot );
                                else 
                                    objectToInsert = CreatePerm( (SecurityElement)objectToInsert ).Union( permInSlot );
                            } 
 
                            if(m_Unrestricted && objectToInsert is IPermission)
                                objectToInsert = null; 

                            this.m_permSet.SetItem( token.m_index, objectToInsert );
                        }
                    } 
                }
            } 
        } 

        internal virtual void FromXml( SecurityDocument doc, int position, bool allowInternalOnly ) 
        {
            if (doc == null)
                throw new ArgumentNullException("doc");
            Contract.EndContractBlock(); 

            if (!doc.GetTagForElement( position ).Equals(s_str_PermissionSet)) 
                throw new ArgumentException(String.Format( null, Environment.GetResourceString( "Argument_InvalidXMLElement" ), "PermissionSet", this.GetType().FullName) ); 

            Reset(); 
            m_allPermissionsDecoded = false;
            Exception savedException = null;
            String strUnrestricted = doc.GetAttributeForElement( position, "Unrestricted" );
            if (strUnrestricted != null) 
                m_Unrestricted = strUnrestricted.Equals( "True" ) || strUnrestricted.Equals( "true" ) || strUnrestricted.Equals( "TRUE" );
            else 
                m_Unrestricted = false; 

            ArrayList childrenIndices = doc.GetChildrenPositionForElement( position ); 
            int childCount = childrenIndices.Count;
            for (int i = 0; i < childCount; ++i)
            {
                int childIndex = (int)childrenIndices[i]; 
                if (IsPermissionTag( doc.GetTagForElement( childIndex ), allowInternalOnly ))
                { 
                    try 
                    {
                        String className = doc.GetAttributeForElement( childIndex, "class" ); 

                        PermissionToken token;
                        Object objectToInsert;
 
                        if (className != null)
                        { 
                            token = PermissionToken.GetToken( className ); 
                            if (token == null)
                            { 
                                objectToInsert = CreatePerm( doc.GetElement( childIndex, true ) );

                                if (objectToInsert != null)
                                { 
#if _DEBUG
                                    PermissionToken tokenDebug = PermissionToken.GetToken( (IPermission)objectToInsert ); 
                                    Contract.Assert((tokenDebug != null), "PermissionToken.GetToken returned null "); 
                                    Contract.Assert( (tokenDebug.m_type & PermissionTokenType.BuiltIn) != 0, "This should only be called for built-ins" );
#endif 
                                    Contract.Assert( objectToInsert.GetType().Module.Assembly == System.Reflection.Assembly.GetExecutingAssembly(),
                                        "PermissionToken.GetToken returned null for non-mscorlib permission" );
                                    token = PermissionToken.GetToken( (IPermission)objectToInsert );
                                    Contract.Assert((token != null), "PermissionToken.GetToken returned null "); 
                                    Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should always know the permission type when getting a token from an instance" );
                                } 
                            } 
                            else
                            { 
                                objectToInsert = ((ISecurityElementFactory)new SecurityDocumentElement(doc, childIndex)).CreateSecurityElement();
                            }
                        }
                        else 
                        {
                            IPermission ip = CreatePerm( doc.GetElement( childIndex, true ) ); 
                            if (ip == null) 
                            {
                                token = null; 
                                objectToInsert = null;
                            }
                            else
                            { 
                                token = PermissionToken.GetToken( ip );
                                Contract.Assert( PermissionToken.IsTokenProperlyAssigned( ip, token ), 
                                                 "PermissionToken was improperly assigned" ); 
                                objectToInsert = ip;
                            } 
                        }

                        if (token != null && objectToInsert != null)
                        { 
                            if (m_permSet == null)
                                m_permSet = new TokenBasedSet(); 
 
                            IPermission permInSlot = null;
                            if (this.m_permSet.GetItem( token.m_index ) != null) 
                            {
                                // If there is already something in that slot, let's union them
                                // together.
 
                                if (this.m_permSet.GetItem( token.m_index ) is IPermission)
                                    permInSlot = (IPermission)this.m_permSet.GetItem( token.m_index ); 
                                else 
                                    permInSlot = CreatePerm( this.m_permSet.GetItem( token.m_index ) );
                            } 

                            if (permInSlot != null)
                            {
                                if (objectToInsert is IPermission) 
                                    objectToInsert = permInSlot.Union((IPermission)objectToInsert);
                                else 
                                    objectToInsert = permInSlot.Union(CreatePerm( objectToInsert )); 
                            }
 
                            if(m_Unrestricted && objectToInsert is IPermission)
                                objectToInsert = null;

                            this.m_permSet.SetItem( token.m_index, objectToInsert ); 
                        }
                    } 
                    catch (Exception e) 
                    {
#if _DEBUG 
                        if (debug)
                            DEBUG_WRITE( "error while decoding permission set =\n" + e.ToString() );
#endif
                        if (savedException == null) 
                            savedException = e;
 
                    } 
                }
            } 

            if (savedException != null)
                throw savedException;
 
        }
 
        private  IPermission CreatePerm(Object obj) 
        {
            return CreatePerm(obj, m_ignoreTypeLoadFailures); 
        }

        internal static IPermission CreatePerm(Object obj, bool ignoreTypeLoadFailures)
        { 
            SecurityElement el = obj as SecurityElement;
            ISecurityElementFactory isf = obj as ISecurityElementFactory; 
            if (el == null && isf != null) 
            {
                el = isf.CreateSecurityElement(); 
            }

            IEnumerator enumerator;
            IPermission finalPerm = null; 

            switch (el.Tag) 
            { 
            case s_str_PermissionUnion:
                enumerator = el.Children.GetEnumerator(); 
                while (enumerator.MoveNext())
                {
                    IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures);
 
                    if (finalPerm != null)
                        finalPerm = finalPerm.Union( tempPerm ); 
                    else 
                        finalPerm = tempPerm;
                } 
                break;

            case s_str_PermissionIntersection:
                enumerator = el.Children.GetEnumerator(); 
                while (enumerator.MoveNext())
                { 
                    IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures); 

                    if (finalPerm != null) 
                        finalPerm = finalPerm.Intersect( tempPerm );
                    else
                        finalPerm = tempPerm;
 
                    if (finalPerm == null)
                        return null; 
                } 
                break;
 
            case s_str_PermissionUnrestrictedUnion:
                enumerator = el.Children.GetEnumerator();
                bool first = true;
                while (enumerator.MoveNext()) 
                {
                    IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures ); 
 
                    if (tempPerm == null)
                        continue; 

                    PermissionToken token = PermissionToken.GetToken( tempPerm );

                    Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already" ); 

                    if ((token.m_type & PermissionTokenType.IUnrestricted) != 0) 
                    { 
                        finalPerm = XMLUtil.CreatePermission( GetPermissionElement((SecurityElement)enumerator.Current), PermissionState.Unrestricted, ignoreTypeLoadFailures );
                        first = false; 
                        break;
                    }
                    else
                    { 
                        Contract.Assert( tempPerm != null, "We should only come here if we have a real permission" );
                        if (first) 
                            finalPerm = tempPerm; 
                        else
                            finalPerm = tempPerm.Union( finalPerm ); 
                        first = false;
                    }
                }
                break; 

            case s_str_PermissionUnrestrictedIntersection: 
                enumerator = el.Children.GetEnumerator(); 
                while (enumerator.MoveNext())
                { 
                    IPermission tempPerm = CreatePerm( (SecurityElement)enumerator.Current, ignoreTypeLoadFailures );

                    if (tempPerm == null)
                        return null; 

                    PermissionToken token = PermissionToken.GetToken( tempPerm ); 
 
                    Contract.Assert( (token.m_type & PermissionTokenType.DontKnow) == 0, "We should know the permission type already" );
 
                    if ((token.m_type & PermissionTokenType.IUnrestricted) != 0)
                    {
                        if (finalPerm != null)
                            finalPerm = tempPerm.Intersect( finalPerm ); 
                        else
                            finalPerm = tempPerm; 
                    } 
                    else
                    { 
                        finalPerm = null;
                    }

                    if (finalPerm == null) 
                        return null;
                } 
                break; 

            case "IPermission": 
            case "Permission":
                finalPerm = el.ToPermission(ignoreTypeLoadFailures);
                break;
 
            default:
                Contract.Assert( false, "Unrecognized case found during permission creation" ); 
                break; 
            }
 
            return finalPerm;
        }

        internal IPermission CreatePermission(Object obj, int index) 
        {
            IPermission perm = CreatePerm(obj); 
            if(perm == null) 
                return null;
 
            // See if the PermissionSet.m_Unrestricted flag covers this permission
            if(m_Unrestricted)
                perm = null;
 
            // Store the decoded result
            CheckSet(); 
            m_permSet.SetItem(index, perm); 

            // Do some consistency checks 
            Contract.Assert(perm == null || PermissionToken.IsTokenProperlyAssigned( perm, PermissionToken.GetToken( perm ) ), "PermissionToken was improperly assigned");
            if (perm != null)
            {
                PermissionToken permToken = PermissionToken.GetToken(perm); 
                if (permToken != null && permToken.m_index != index)
                    throw new ArgumentException( Environment.GetResourceString( "Argument_UnableToGeneratePermissionSet")); 
            } 

 
            return perm;
        }

        private static SecurityElement GetPermissionElement( SecurityElement el ) 
        {
            switch (el.Tag) 
            { 
            case "IPermission":
            case "Permission": 
                return el;
            }
            IEnumerator enumerator = el.Children.GetEnumerator();
            if (enumerator.MoveNext()) 
                return GetPermissionElement((SecurityElement)enumerator.Current);
            Contract.Assert( false, "No Permission or IPermission tag found" ); 
            return null; 
        }
 
        internal static SecurityElement CreateEmptyPermissionSetXml()
        {

            SecurityElement elTrunk = new SecurityElement("PermissionSet"); 
            elTrunk.AddAttribute( "class", "System.Security.PermissionSet" );
 
            elTrunk.AddAttribute( "version", "1" ); 
            return elTrunk;
 
        }
        // internal helper which takes in the hardcoded permission name to avoid lookup at runtime
        // can be called from classes that derive from PermissionSet
        internal SecurityElement ToXml(String permName) 
        {
            SecurityElement elTrunk = new SecurityElement("PermissionSet"); 
            elTrunk.AddAttribute( "class", permName ); 

            elTrunk.AddAttribute( "version", "1" ); 

            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);

            if (m_Unrestricted) 
            {
                elTrunk.AddAttribute(s_str_Unrestricted, "true" ); 
            } 

            while (enumerator.MoveNext()) 
            {
                IPermission perm = (IPermission)enumerator.Current;

                if (!m_Unrestricted) 
                    elTrunk.AddChild( perm.ToXml() );
            } 
            return elTrunk; 
        }
 
        internal SecurityElement InternalToXml()
        {
            SecurityElement elTrunk = new SecurityElement("PermissionSet");
            elTrunk.AddAttribute( "class", this.GetType().FullName); 
            elTrunk.AddAttribute( "version", "1" );
 
            if (m_Unrestricted) 
            {
                elTrunk.AddAttribute(s_str_Unrestricted, "true" ); 
            }

            if (this.m_permSet != null)
            { 
                int maxIndex = this.m_permSet.GetMaxUsedIndex();
 
                for (int i = m_permSet.GetStartingIndex(); i <= maxIndex; ++i) 
                {
                    Object obj = this.m_permSet.GetItem( i ); 
                    if (obj != null)
                    {
                        if (obj is IPermission)
                        { 
                            if (!m_Unrestricted)
                                elTrunk.AddChild( ((IPermission)obj).ToXml() ); 
                        } 
                        else
                        { 
                            elTrunk.AddChild( (SecurityElement)obj );
                        }
                    }
 
                }
            } 
            return elTrunk ; 
        }
 
        public virtual SecurityElement ToXml()
        {
            // If you hit this assert then most likely you are trying to change the name of this class.
            // This is ok as long as you change the hard coded string above and change the assert below. 
            Contract.Assert( this.GetType().FullName.Equals( "System.Security.PermissionSet" ), "Class name changed! Was: System.Security.PermissionSet Should be:" +  this.GetType().FullName);
 
            return ToXml("System.Security.PermissionSet"); 
        }
#endif // FEATURE_CAS_POLICY 

#if FEATURE_CAS_POLICY && FEATURE_SERIALIZATION
        internal
        byte[] EncodeXml() 
        {
            MemoryStream ms = new MemoryStream(); 
            BinaryWriter writer = new BinaryWriter( ms, Encoding.Unicode ); 
            writer.Write( this.ToXml().ToString() );
            writer.Flush(); 

            // The BinaryWriter is going to place
            // two bytes indicating a Unicode stream.
            // We want to chop those off before returning 
            // the bytes out.
 
            ms.Position = 2; 
            int countBytes = (int)ms.Length - 2;
            byte[] retval = new byte[countBytes]; 
            ms.Read( retval, 0, retval.Length );
            return retval;
        }
 
        /// 
        [Obsolete("This method is obsolete and shoud no longer be used.")] 
        public static byte[] ConvertPermissionSet(String inFormat, byte[] inData, String outFormat) 
        {
            // Since this method has shipped and is public, we cannot remove it without being a breaking change 
            throw new NotImplementedException();
        }
#endif
 
        // Determines whether the permission set contains any non-code access
        // security permissions. 
        public bool ContainsNonCodeAccessPermissions() 
        {
            if (m_CheckedForNonCas) 
                return m_ContainsNonCas;

            lock (this)
            { 
                if (m_CheckedForNonCas)
                    return m_ContainsNonCas; 
 
                m_ContainsCas = false;
                m_ContainsNonCas = false; 

                if (IsUnrestricted())
                    m_ContainsCas = true;
 
                if (this.m_permSet != null)
                { 
                    PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this); 

                    while (enumerator.MoveNext() && (!m_ContainsCas || !m_ContainsNonCas)) 
                    {
                        IPermission perm = enumerator.Current as IPermission;

                        if (perm != null) 
                        {
                            if (perm is CodeAccessPermission) 
                                m_ContainsCas = true; 
                            else
                                m_ContainsNonCas = true; 
                        }
                    }
                }
 
                m_CheckedForNonCas = true;
            } 
 
            return m_ContainsNonCas;
        } 

        // Returns a permission set containing only CAS-permissions. If possible
        // this is just the input set, otherwise a new set is allocated.
        private PermissionSet GetCasOnlySet() 
        {
            if (!m_ContainsNonCas) 
                return this; 

            if (IsUnrestricted()) 
                return this;

            PermissionSet pset = new PermissionSet(false);
 
            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(this);
 
            while (enumerator.MoveNext()) 
            {
                IPermission perm = (IPermission)enumerator.Current; 

                if (perm is CodeAccessPermission)
                    pset.AddPermission(perm);
            } 

            pset.m_CheckedForNonCas = true; 
            pset.m_ContainsCas = !pset.IsEmpty(); 
            pset.m_ContainsNonCas = false;
 
            return pset;
        }

#if FEATURE_CAS_POLICY 
        private const String s_str_PermissionSet = "PermissionSet";
        private const String s_str_Permission    = "Permission"; 
        private const String s_str_IPermission    = "IPermission"; 
        private const String s_str_Unrestricted  = "Unrestricted";
        private const String s_str_PermissionUnion = "PermissionUnion"; 
        private const String s_str_PermissionIntersection = "PermissionIntersection";
        private const String s_str_PermissionUnrestrictedUnion = "PermissionUnrestrictedUnion";
        private const String s_str_PermissionUnrestrictedIntersection = "PermissionUnrestrictedIntersection";
 
        // This method supports v1.x security attrbutes only - we'll require legacy CAS policy mode
        // to be enabled for that to work. 
#pragma warning disable 618 
        // Internal routine used to setup a special security context
        // for creating and manipulated security custom attributes 
        // that we use when the Runtime is hosted.
        [System.Security.SecurityCritical]  // auto-generated
        private static void SetupSecurity()
        { 
            PolicyLevel level = PolicyLevel.CreateAppDomainLevel();
 
            CodeGroup rootGroup = new UnionCodeGroup( new AllMembershipCondition(), level.GetNamedPermissionSet( "Execution" ) ); 

            StrongNamePublicKeyBlob microsoftBlob = new StrongNamePublicKeyBlob( AssemblyRef.MicrosoftPublicKeyFull ); 
            CodeGroup microsoftGroup = new UnionCodeGroup( new StrongNameMembershipCondition( microsoftBlob, null, null ), level.GetNamedPermissionSet( "FullTrust" ) );

            StrongNamePublicKeyBlob ecmaBlob = new StrongNamePublicKeyBlob( AssemblyRef.EcmaPublicKeyFull );
            CodeGroup ecmaGroup = new UnionCodeGroup( new StrongNameMembershipCondition( ecmaBlob, null, null ), level.GetNamedPermissionSet( "FullTrust" ) ); 

            CodeGroup gacGroup = new UnionCodeGroup( new GacMembershipCondition(), level.GetNamedPermissionSet( "FullTrust" ) ); 
 
            rootGroup.AddChild( microsoftGroup );
            rootGroup.AddChild( ecmaGroup ); 
            rootGroup.AddChild( gacGroup );

            level.RootCodeGroup = rootGroup;
 
            try
            { 
                AppDomain.CurrentDomain.SetAppDomainPolicy( level ); 
            }
            catch (PolicyException) 
            {
            }
        }
#endif 
#pragma warning restore 618
 
        // Internal routine used by CreateSerialized to add a permission to the set 
        private static void MergePermission(IPermission perm, bool separateCasFromNonCas, ref PermissionSet casPset, ref PermissionSet nonCasPset)
        { 
            Contract.Assert(casPset == null || !casPset.IsReadOnly);
            Contract.Assert(nonCasPset == null || !nonCasPset.IsReadOnly);

            if (perm == null) 
                return;
 
            if (!separateCasFromNonCas || perm is CodeAccessPermission) 
            {
                if(casPset == null) 
                    casPset = new PermissionSet(false);
                IPermission oldPerm = casPset.GetPermission(perm);
                IPermission unionPerm = casPset.AddPermission(perm);
                if (oldPerm != null && !oldPerm.IsSubsetOf( unionPerm )) 
                    throw new NotSupportedException( Environment.GetResourceString( "NotSupported_DeclarativeUnion" ) );
            } 
            else 
            {
                if(nonCasPset == null) 
                    nonCasPset = new PermissionSet(false);
                IPermission oldPerm = nonCasPset.GetPermission(perm);
                IPermission unionPerm = nonCasPset.AddPermission( perm );
                if (oldPerm != null && !oldPerm.IsSubsetOf( unionPerm )) 
                    throw new NotSupportedException( Environment.GetResourceString( "NotSupported_DeclarativeUnion" ) );
            } 
        } 

        // Converts an array of SecurityAttributes to a PermissionSet 
        [ResourceExposure(ResourceScope.Machine)]  // Reading these attributes can load files.
        [ResourceConsumption(ResourceScope.Machine)]
        private static byte[] CreateSerialized(Object[] attrs,
                                               bool serialize, 
                                               ref byte[] nonCasBlob,
                                               out PermissionSet casPset, 
                                               HostProtectionResource fullTrustOnlyResources, 
                                               bool allowEmptyPermissionSets)
        { 
            // Create two new (empty) sets.
            casPset = null;
            PermissionSet nonCasPset = null;
 
            // Most security attributes generate a single permission. The
            // PermissionSetAttribute class generates an entire permission set we 
            // need to merge, however. 
            for (int i = 0; i < attrs.Length; i++)
            { 
                Contract.Assert(i == 0 || ((SecurityAttribute)attrs[i]).m_action == ((SecurityAttribute)attrs[i - 1]).m_action, "Mixed SecurityActions");
                if (attrs[i] is PermissionSetAttribute)
                {
                    PermissionSet pset = ((PermissionSetAttribute)attrs[i]).CreatePermissionSet(); 
                    if (pset == null)
                        throw new ArgumentException( Environment.GetResourceString( "Argument_UnableToGeneratePermissionSet" ) ); 
 
                    PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(pset);
 
                    while (enumerator.MoveNext())
                    {
                        IPermission perm = (IPermission)enumerator.Current;
                        MergePermission(perm, serialize, ref casPset, ref nonCasPset); 
                    }
 
                    if(casPset == null) 
                        casPset = new PermissionSet(false);
                    if (pset.IsUnrestricted()) 
                        casPset.SetUnrestricted(true);
                }
                else
                { 
                    IPermission perm = ((SecurityAttribute)attrs[i]).CreatePermission();
                    MergePermission(perm, serialize, ref casPset, ref nonCasPset); 
                } 
            }
            Contract.Assert(serialize || nonCasPset == null, "We shouldn't separate nonCAS permissions unless fSerialize is true"); 

            //
            // Filter HostProtection permission.  In the VM, some optimizations are done based upon these
            // declarative permission sets being NULL if they do not exist.  When filtering the permission 
            // set if we end up with an empty set, we can the permission set NULL rather than returning the
            // empty set in order to enable those optimizations. 
            // 

            if(casPset != null) 
            {
                casPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None);
                casPset.ContainsNonCodeAccessPermissions(); // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code
                if (allowEmptyPermissionSets && casPset.IsEmpty()) 
                    casPset = null;
            } 
            if(nonCasPset != null) 
            {
                nonCasPset.FilterHostProtectionPermissions(fullTrustOnlyResources, HostProtectionResource.None); 
                nonCasPset.ContainsNonCodeAccessPermissions(); // make sure all declarative PermissionSets are checked for non-CAS so we can just check the flag from native code
                if (allowEmptyPermissionSets && nonCasPset.IsEmpty())
                    nonCasPset = null;
            } 

            // Serialize the set(s). 
            byte[] casBlob = null; 
            nonCasBlob = null;
#if FEATURE_CAS_POLICY 
            if(serialize)
            {
                if(casPset != null)
                    casBlob = casPset.EncodeXml(); 
                if(nonCasPset != null)
                    nonCasBlob = nonCasPset.EncodeXml(); 
            } 
#else // FEATURE_CAS_POLICY
            Contract.Assert(!serialize, "Cannot serialize permission sets on CoreCLR"); 
#endif // FEATURE_CAS_POLICY

            return casBlob;
        } 

#if FEATURE_SERIALIZATION 
        ///  
        void IDeserializationCallback.OnDeserialization(Object sender)
        { 
            NormalizePermissionSet();
            m_CheckedForNonCas = false;
        }
#endif 

        [System.Security.SecuritySafeCritical]  // auto-generated 
        [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable 
        public static void RevertAssert()
        { 
            StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
            SecurityRuntime.RevertAssert(ref stackMark);
        }
 
        internal static PermissionSet RemoveRefusedPermissionSet(PermissionSet assertSet, PermissionSet refusedSet, out bool bFailedToCompress)
        { 
            Contract.Assert((assertSet == null || !assertSet.IsUnrestricted()), "Cannot be unrestricted here"); 
            PermissionSet retPs = null;
            bFailedToCompress = false; 
            if (assertSet == null)
                return null;
            if (refusedSet != null)
            { 
                if (refusedSet.IsUnrestricted())
                    return null; // we're refusing everything...cannot assert anything now. 
 
                PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(refusedSet);
                while (enumerator.MoveNext()) 
                {
                    CodeAccessPermission refusedPerm = (CodeAccessPermission)enumerator.Current;
                    int i = enumerator.GetCurrentIndex();
                    if (refusedPerm != null) 
                    {
                        CodeAccessPermission perm 
                            = (CodeAccessPermission)assertSet.GetPermission(i); 
                        try
                        { 
                            if (refusedPerm.Intersect(perm) != null)
                            {
                                if (refusedPerm.Equals(perm))
                                { 
                                    if (retPs == null)
                                        retPs = assertSet.Copy(); 
 
                                    retPs.RemovePermission(i);
                                } 
                                else
                                {
                                    // Asserting a permission, part of which is already denied/refused
                                    // cannot compress this assert 
                                    bFailedToCompress = true;
                                    return assertSet; 
                                } 
                            }
                        } 
                        catch (ArgumentException)
                        {
                            // Any exception during removing a refused set from assert set => we play it safe and not assert that perm
                            if (retPs == null) 
                                retPs = assertSet.Copy();
                            retPs.RemovePermission(i); 
                        } 
                    }
                } 
            }
            if (retPs != null)
                return retPs;
            return assertSet; 
        }
 
        internal static void RemoveAssertedPermissionSet(PermissionSet demandSet, PermissionSet assertSet, out PermissionSet alteredDemandSet) 
        {
            Contract.Assert(!assertSet.IsUnrestricted(), "Cannot call this function if assertSet is unrestricted"); 
            alteredDemandSet = null;

            PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(demandSet);
            while (enumerator.MoveNext()) 
            {
                CodeAccessPermission demandDerm = (CodeAccessPermission)enumerator.Current; 
                int i = enumerator.GetCurrentIndex(); 
                if (demandDerm != null)
                { 
                    CodeAccessPermission assertPerm
                        = (CodeAccessPermission)assertSet.GetPermission(i);
                    try
                    { 
                        if (demandDerm.CheckAssert(assertPerm))
                        { 
                            if (alteredDemandSet == null) 
                                alteredDemandSet = demandSet.Copy();
 
                            alteredDemandSet.RemovePermission(i);
                        }
                    }
                    catch (ArgumentException) 
                    {
                    } 
                } 
            }
            return; 
        }

        internal static bool IsIntersectingAssertedPermissions(PermissionSet assertSet1, PermissionSet assertSet2)
        { 
            bool isIntersecting = false;
            if (assertSet1 != null && assertSet2 != null) 
            { 
                PermissionSetEnumeratorInternal enumerator = new PermissionSetEnumeratorInternal(assertSet2);
                while (enumerator.MoveNext()) 
                {
                    CodeAccessPermission perm2 = (CodeAccessPermission)enumerator.Current;
                    int i = enumerator.GetCurrentIndex();
                    if (perm2 != null) 
                    {
                        CodeAccessPermission perm1 
                            = (CodeAccessPermission)assertSet1.GetPermission(i); 
                        try
                        { 
                            if (perm1 != null && !perm1.Equals(perm2))
                            {
                                isIntersecting = true; // Same type of permission, but with different flags or something - cannot union them
                            } 
                        }
                        catch (ArgumentException) 
                        { 
                            isIntersecting = true; //assume worst case
                        } 
                    }
                }
            }
            return isIntersecting; 

        } 
 
        // This is a hack so that SQL can operate under default policy without actually
        // granting permissions in assemblies that they disallow.  @ 


        internal bool IgnoreTypeLoadFailures
        { 
            set { m_ignoreTypeLoadFailures = value; }
        } 
    } 
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK