internal void Undo(Thread currentThread)
        {
            //
            // Don't use an uninitialized switcher, or one that's already been used.
            //
            if (thread == null)
                return; // Don't do anything

            Contract.Assert(currentThread == this.thread);

            // 
            // Restore the HostExecutionContext before restoring the ExecutionContext.
            //
#if FEATURE_CAS_POLICY                
            if (hecsw != null)
                HostExecutionContextSwitcher.Undo(hecsw);
#endif // FEATURE_CAS_POLICY

            //
            // restore the saved Execution Context.  Note that this will also restore the 
            // SynchronizationContext, Logical/IllogicalCallContext, etc.
            //
#if !FEATURE_PAL && FEATURE_IMPERSONATION
            ExecutionContext.Reader innerEC = currentThread.GetExecutionContextReader();
#endif
            currentThread.SetExecutionContext(outerEC, outerECBelongsToScope);

#if !MONO && DEBUG
            try
            {
                currentThread.ForbidExecutionContextMutation = true;
#endif
                //
                // Tell the SecurityContext to do the side-effects of restoration.
                //
#if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK
                if (scsw.currSC != null)
                {
                    // Any critical failure inside scsw will cause FailFast
                    scsw.Undo();
                }
#endif // #if FEATURE_IMPERSONATION || FEATURE_COMPRESSEDSTACK

#if !FEATURE_PAL && FEATURE_IMPERSONATION
                if (wiIsValid)
                    SecurityContext.RestoreCurrentWI(outerEC, innerEC, wi, cachedAlwaysFlowImpersonationPolicy);
#endif

                thread = null; // this will prevent the switcher object being used again
#if !MONO && DEBUG
            }
            finally
            {
                currentThread.ForbidExecutionContextMutation = false;
            }
#endif
        }
        static internal void EstablishCopyOnWriteScope(Thread currentThread, bool knownNullWindowsIdentity, ref ExecutionContextSwitcher ecsw)
        {
            Contract.Assert(currentThread == Thread.CurrentThread);

            ecsw.outerEC = currentThread.GetExecutionContextReader();
            ecsw.outerECBelongsToScope = currentThread.ExecutionContextBelongsToCurrentScope;

#if !FEATURE_PAL && FEATURE_IMPERSONATION
            ecsw.cachedAlwaysFlowImpersonationPolicy = SecurityContext.AlwaysFlowImpersonationPolicy;
            if (knownNullWindowsIdentity)
                Contract.Assert(SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy) == null);
            else
                ecsw.wi = SecurityContext.GetCurrentWI(ecsw.outerEC, ecsw.cachedAlwaysFlowImpersonationPolicy);
            ecsw.wiIsValid = true;
#endif
            currentThread.ExecutionContextBelongsToCurrentScope = false;
            ecsw.thread = currentThread;
        }