public void CheckNegotiateContext <T>(T request, Smb2NegotiateResponsePacket response)
        {
            if (response.PayLoad.DialectRevision != DialectRevision.Smb311)
            {
                return;
            }

            if (request is Smb2NegotiateRequestPacket)
            {
                Smb2NegotiateRequestPacket smb2Request = request as Smb2NegotiateRequestPacket;
                // 3.3.5.4: if Dialect is "3.1.1" Then the server MUST build a NegotiateContextList for its negotiate response and check Including below:
                // 1. The server MUST add an SMB2_PREAUTH_INTEGRITY_CAPABILITIES negotiate context to the response's NegotiateContextList.
                if (response.NegotiateContext_PREAUTH == null)
                {
                    Site.Assert.Fail("The server MUST add an SMB2_PREAUTH_INTEGRITY_CAPABILITIES negotiate context to the response's NegotiateContextList.");
                }

                // 2. HashAlgorithmCount MUST be set to 1
                Site.Assert.AreEqual <int>(1, response.NegotiateContext_PREAUTH.Value.HashAlgorithmCount, "The response's SMB2_PREAUTH_INTEGRITY_CAPABILITIES.HashAlgorithmCount MUST be set to 1");

                // 3. SMB2_PREAUTH_INTEGRITY_CAPABILITIES Salt buffer length same as SaltLength
                Site.Assert.AreEqual <int>(response.NegotiateContext_PREAUTH.Value.SaltLength, response.NegotiateContext_PREAUTH.Value.Salt.Length, "The response's SMB2_PREAUTH_INTEGRITY_CAPABILITIES Salt buffer length must same as SaltLength");

                // 4. If client haven't send a negotiate context the server should not response except SMB2_PREAUTH_INTEGRITY_CAPABILITIES

                if ((smb2Request.NegotiateContext_ENCRYPTION == null) && (response.NegotiateContext_ENCRYPTION != null))
                {
                    Site.Assert.Fail("The server Should not response a SMB2_ENCRYPTION_CAPABILITIES as it's not sent in request.");
                }
                if ((smb2Request.NegotiateContext_COMPRESSION == null) && (response.NegotiateContext_COMPRESSION != null))
                {
                    Site.Assert.Fail("The server Should not response a SMB2_COMPRESSION_CAPABILITIES as it's not sent in request.");
                }
                if ((smb2Request.NegotiateContext_SIGNING == null) && (response.NegotiateContext_SIGNING != null))
                {
                    Site.Assert.Fail("The server Should not response a SMB2_SIGNING_CAPABILITIES as it's not sent in request.");
                }

                if (response.NegotiateContext_ENCRYPTION != null)
                {
                    Site.Assert.AreEqual <int>(1, response.NegotiateContext_ENCRYPTION.Value.CipherCount, "The response's SMB2_ENCRYPTION_CAPABILITIES.CipherCount MUST be set to 1");
                }
            }
            else if (request is SmbNegotiateRequestPacket)
            {
                Site.Assert.IsNull(response.NegotiateContext_ENCRYPTION, "The server Should not response a SMB2_ENCRYPTION_CAPABILITIES as request is SmbNegotiateRequestPacket.");
                Site.Assert.IsNull(response.NegotiateContext_COMPRESSION, "The server Should not response a SMB2_COMPRESSION_CAPABILITIES as request is SmbNegotiateRequestPacket.");
                Site.Assert.IsNull(response.NegotiateContext_SIGNING, "The server Should not response a SMB2_SIGNING_CAPABILITIES as request is SmbNegotiateRequestPacket.");
            }
        }
        /// <summary>
        /// Decode the message as smb2 single request packet
        /// </summary>
        /// <param name="messageBytes">The received packet</param>
        /// <param name="consumedLength">[OUT]The consumed length of the message</param>
        /// <param name="expectedLength">[OUT]The expected length</param>
        /// <returns>A Smb2Packet</returns>
        private static Smb2Packet DecodeSingleRequestPacket(byte[] messageBytes, out int consumedLength, out int expectedLength)
        {
            Packet_Header smb2Header;

            int offset = 0;
            smb2Header = TypeMarshal.ToStruct<Packet_Header>(messageBytes, ref offset);

            if (smb2Header.Command == Smb2Command.OPLOCK_BREAK)
            {
                ushort structureSize = TypeMarshal.ToStruct<ushort>(messageBytes, ref offset);
            }

            Smb2Packet packet = null;

            switch (smb2Header.Command)
            {

                case Smb2Command.NEGOTIATE:
                    packet = new Smb2NegotiateRequestPacket();
                    break;
                default:
                    throw new InvalidOperationException("Received an unknown packet! the type of the packet is "
                        + smb2Header.Command.ToString());
            }

            packet.FromBytes(messageBytes, out consumedLength, out expectedLength);

            return packet;
        }