//
        internal void ValidateCreateContext(
                                            string package,
                                            bool isServer,
                                            NetworkCredential credential,
                                            string servicePrincipalName,
                                            ChannelBinding channelBinding,
                                            ProtectionLevel         protectionLevel,
                                            TokenImpersonationLevel impersonationLevel
                                            )
        {

            if (_Exception != null && !_CanRetryAuthentication) {
                throw _Exception;
            }

            if (_Context != null && _Context.IsValidContext) {
                throw new InvalidOperationException(SR.GetString(SR.net_auth_reauth));
            }

            if (credential == null) {
                throw new ArgumentNullException("credential");
            }

            if (servicePrincipalName == null) {
                throw new ArgumentNullException("servicePrincipalName");
            }

            if (impersonationLevel != TokenImpersonationLevel.Identification &&
                impersonationLevel != TokenImpersonationLevel.Impersonation &&
                impersonationLevel != TokenImpersonationLevel.Delegation)
            {
                throw new ArgumentOutOfRangeException("impersonationLevel", impersonationLevel.ToString(), SR.GetString(SR.net_auth_supported_impl_levels));
            }

            if (_Context != null && IsServer != isServer) {
                throw new InvalidOperationException(SR.GetString(SR.net_auth_client_server));
            }

            _Exception = null;
            _RemoteOk = false;
            _Framer = new StreamFramer(_InnerStream);
            _Framer.WriteHeader.MessageId = FrameHeader.HandshakeId;

            _ExpectedProtectionLevel    = protectionLevel;
            _ExpectedImpersonationLevel = isServer? impersonationLevel: TokenImpersonationLevel.None;
            _WriteSequenceNumber        = 0;
            _ReadSequenceNumber         = 0;

            ContextFlags flags = ContextFlags.Connection;

            // A workaround for the client when talking to Win9x on the server side
            if (protectionLevel == ProtectionLevel.None && !isServer)
            {
                package = NegotiationInfoClass.NTLM;
            }

            else if (protectionLevel == ProtectionLevel.EncryptAndSign)
            {
                flags |= ContextFlags.Confidentiality;
            }
            else if (protectionLevel == ProtectionLevel.Sign)
            {
                // Assuming user expects NT4 SP4 and above
                flags |= ContextFlags.ReplayDetect | ContextFlags.SequenceDetect | ContextFlags.InitIntegrity;
            }

            if (isServer)
            {
                if (_ExtendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported) { flags |= ContextFlags.AllowMissingBindings; }
                if (_ExtendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never &&
                    _ExtendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    flags |= ContextFlags.ProxyBindings;
                }
            }
            else
            {
                // According to lzhu server side should not request any of these flags
                if (protectionLevel != ProtectionLevel.None)                        {flags |= ContextFlags.MutualAuth;}
                if (impersonationLevel == TokenImpersonationLevel.Identification)   {flags |= ContextFlags.InitIdentify;}
                if (impersonationLevel == TokenImpersonationLevel.Delegation)       {flags |= ContextFlags.Delegate;}
            }
            

            _CanRetryAuthentication = false;

            //
            // Security: We used to rely on NetworkCredential class to demand permission
            //           Switched over to explicit ControlPrincipalPermission demand (except for DefaultCredential case)
            //           The mitigated attack is brute-force pasword guessing through SSPI.
            if (!(credential is SystemNetworkCredential))
                ExceptionHelper.ControlPrincipalPermission.Demand();

            try {
                //
                _Context = new NTAuthentication(isServer, package, credential, servicePrincipalName, flags, channelBinding);
            }
            catch (Win32Exception e)
            {
                throw new AuthenticationException(SR.GetString(SR.net_auth_SSPI), e);
            }
        }
 internal void ValidateCreateContext(string package, bool isServer, NetworkCredential credential, string servicePrincipalName, ChannelBinding channelBinding, ProtectionLevel protectionLevel, TokenImpersonationLevel impersonationLevel)
 {
     if ((this._Exception != null) && !this._CanRetryAuthentication)
     {
         throw this._Exception;
     }
     if ((this._Context != null) && this._Context.IsValidContext)
     {
         throw new InvalidOperationException(SR.GetString("net_auth_reauth"));
     }
     if (credential == null)
     {
         throw new ArgumentNullException("credential");
     }
     if (servicePrincipalName == null)
     {
         throw new ArgumentNullException("servicePrincipalName");
     }
     if (ComNetOS.IsWin9x && (protectionLevel != ProtectionLevel.None))
     {
         throw new NotSupportedException(SR.GetString("net_auth_no_protection_on_win9x"));
     }
     if (((impersonationLevel != TokenImpersonationLevel.Identification) && (impersonationLevel != TokenImpersonationLevel.Impersonation)) && (impersonationLevel != TokenImpersonationLevel.Delegation))
     {
         throw new ArgumentOutOfRangeException("impersonationLevel", impersonationLevel.ToString(), SR.GetString("net_auth_supported_impl_levels"));
     }
     if ((this._Context != null) && (this.IsServer != isServer))
     {
         throw new InvalidOperationException(SR.GetString("net_auth_client_server"));
     }
     this._Exception = null;
     this._RemoteOk = false;
     this._Framer = new StreamFramer(this._InnerStream);
     this._Framer.WriteHeader.MessageId = 0x16;
     this._ExpectedProtectionLevel = protectionLevel;
     this._ExpectedImpersonationLevel = isServer ? impersonationLevel : TokenImpersonationLevel.None;
     this._WriteSequenceNumber = 0;
     this._ReadSequenceNumber = 0;
     ContextFlags connection = ContextFlags.Connection;
     if ((protectionLevel == ProtectionLevel.None) && !isServer)
     {
         package = "NTLM";
     }
     else if (protectionLevel == ProtectionLevel.EncryptAndSign)
     {
         connection |= ContextFlags.Confidentiality;
     }
     else if (protectionLevel == ProtectionLevel.Sign)
     {
         connection |= ContextFlags.AcceptStream | ContextFlags.SequenceDetect | ContextFlags.ReplayDetect;
     }
     if (isServer)
     {
         if (this._ExtendedProtectionPolicy.PolicyEnforcement == PolicyEnforcement.WhenSupported)
         {
             connection |= ContextFlags.AllowMissingBindings;
         }
         if ((this._ExtendedProtectionPolicy.PolicyEnforcement != PolicyEnforcement.Never) && (this._ExtendedProtectionPolicy.ProtectionScenario == ProtectionScenario.TrustedProxy))
         {
             connection |= ContextFlags.ProxyBindings;
         }
     }
     else
     {
         if (protectionLevel != ProtectionLevel.None)
         {
             connection |= ContextFlags.MutualAuth;
         }
         if (impersonationLevel == TokenImpersonationLevel.Identification)
         {
             connection |= ContextFlags.AcceptIntegrity;
         }
         if (impersonationLevel == TokenImpersonationLevel.Delegation)
         {
             connection |= ContextFlags.Delegate;
         }
     }
     this._CanRetryAuthentication = false;
     if (!(credential is SystemNetworkCredential))
     {
         ExceptionHelper.ControlPrincipalPermission.Demand();
     }
     try
     {
         this._Context = new NTAuthentication(isServer, package, credential, servicePrincipalName, connection, channelBinding);
     }
     catch (Win32Exception exception)
     {
         throw new AuthenticationException(SR.GetString("net_auth_SSPI"), exception);
     }
 }