/// <summary>
        /// Check server response. Return the abstracted context type of response.
        /// </summary>
        private void CheckResponseContexts(
            Smb2CreateContextResponse[] serverCreateContexts,
            out DurableHandleResponseContext durableHandleResponseContext,
            out LeaseResponseContext leaseResponseContext)
        {
            durableHandleResponseContext = DurableHandleResponseContext.NONE;
            leaseResponseContext         = LeaseResponseContext.NONE;

            if (serverCreateContexts != null)
            {
                foreach (Smb2CreateContextResponse response in serverCreateContexts)
                {
                    if (response is Smb2CreateDurableHandleResponse)
                    {
                        durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE;
                    }
                    else if (response is Smb2CreateDurableHandleResponseV2)
                    {
                        durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2;
                        if ((response as Smb2CreateDurableHandleResponseV2).Flags.HasFlag(CREATE_DURABLE_HANDLE_RESPONSE_V2_Flags.DHANDLE_FLAG_PERSISTENT))
                        {
                            durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2_WITH_PERSISTENT;
                        }
                    }
                    else if (response is Smb2CreateResponseLease)
                    {
                        leaseResponseContext = LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE;
                    }
                    else if (response is Smb2CreateResponseLeaseV2)
                    {
                        leaseResponseContext = LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2;
                    }
                }
            }
        }
        /// <summary>
        /// Check server response. Return the abstracted context type of response.
        /// </summary>
        private void CheckResponseContexts(
            Smb2CreateContextResponse[] serverCreateContexts,
            out DurableHandleResponseContext durableHandleResponseContext,
            out LeaseResponseContext leaseResponseContext)
        {
            durableHandleResponseContext = DurableHandleResponseContext.NONE;
            leaseResponseContext = LeaseResponseContext.NONE;

            if (serverCreateContexts != null)
            {
                foreach (Smb2CreateContextResponse response in serverCreateContexts)
                {
                    if (response is Smb2CreateDurableHandleResponse)
                    {
                        durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE;
                    }
                    else if (response is Smb2CreateDurableHandleResponseV2)
                    {
                        durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2;
                        if ((response as Smb2CreateDurableHandleResponseV2).Flags.HasFlag(CREATE_DURABLE_HANDLE_RESPONSE_V2_Flags.DHANDLE_FLAG_PERSISTENT))
                            durableHandleResponseContext = DurableHandleResponseContext.SMB2_CREATE_DURABLE_HANDLE_RESPONSE_V2_WITH_PERSISTENT;
                    }
                    else if (response is Smb2CreateResponseLease)
                    {
                        leaseResponseContext = LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE;
                    }
                    else if (response is Smb2CreateResponseLeaseV2)
                    {
                        leaseResponseContext = LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2;
                    }
                }
            }
        }
        /// <summary>
        /// This method is used to verify the SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context
        /// The client is requesting a reconnect to an existing durable open
        /// Cover TD section: 3.3.5.9.7
        /// Return true means the message is handled by this function. 
        /// Return false means the message needs further processing.        
        /// </summary>
        private static bool Handling_SMB2_CREATE_DURABLE_HANDLE_RECONNECT_CreateContext(
            ModelSmb2Status status,
            ModelOpenFileRequest modelOpenFileRequest,
            LeaseResponseContext leaseResponseContext,
            HandleConfig c)
        {
            Condition.IsTrue(Config.Platform == c.Platform);

            ModelHelper.Log(LogType.Requirement, "3.3.5.9.7: Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context");

            if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist
                || modelOpenFileRequest.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If the create request also contains an SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 or SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 create context, " +
                    "the server SHOULD<267> fail the request with STATUS_INVALID_PARAMETER.");
                ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext);

                if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist)
                {
                    ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 is included.");
                }
                if (modelOpenFileRequest.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist)
                {
                    ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 is included.");
                }

                if (Config.Platform == Platform.WindowsServer2008 || Config.Platform == Platform.WindowsServer2008R2)
                {
                    ModelHelper.Log(LogType.Requirement, "<267> Section 3.3.5.9.7: Windows Vista SP1, Windows Server 2008, Windows 7 and Windows Server 2008 R2 ignore undefined create contexts.");
                    ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}.", Config.Platform);
                    Condition.IsTrue(leaseResponseContext == LeaseResponseContext.NONE);
                    return false;
                }
                else if (Config.Platform == Platform.NonWindows)
                {
                    ModelHelper.Log(LogType.TestInfo, "The SUT platform is NonWindows, so the server could return other error code.");
                    Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS);
                }
                else
                {
                    ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}", Config.Platform);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER);
                }

                return true;
            }

            ModelHelper.Log(LogType.Requirement,
                "The server MUST look up an existing open in the GlobalOpenTable by doing a lookup with the FileId.Persistent portion of the create context. ");

            if (Open == null)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If the lookup fails, the server SHOULD<268> fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9.");
                ModelHelper.Log(LogType.TestInfo, "The open does not exist and the SUT platform is {0}.", Config.Platform);
                ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier);

                if (Config.Platform == Platform.NonWindows)
                    Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS);
                else
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            if (Open.IsLeaseExisted && !modelOpenFileRequest.isSameClient)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If Open.Lease is not NULL and Open.ClientGuid is not equal to the ClientGuid of the connection that received this request, " +
                    "the server MUST fail the create request with STATUS_OBJECT_NAME_NOT_FOUND.");
                ModelHelper.Log(LogType.TestInfo, "Open.Lease is not NULL and Open.ClientGuid is not equal to the ClientGuid of the connection.");
                ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier);

                Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            if (NegotiateDialect != DialectRevision.Smb2002
                && !Open.IsLeaseExisted
                && (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 || modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2))
            {
                ModelHelper.Log(LogType.Requirement,
                    "If Open.Lease is NULL and the SMB2_CREATE_REQUEST_LEASE_V2 or the SMB2_CREATE_REQUEST_LEASE create context is present, " +
                    "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.");
                ModelHelper.Log(LogType.TestInfo,
                    "Open.Lease is NULL and {0} is present.",
                    modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 ? "SMB2_CREATE_REQUEST_LEASE" : "SMB2_CREATE_REQUEST_LEASE_V2");

                ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext);

                Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            if (!Open.IsDurable)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If Open.IsDurable is FALSE and Open.IsResilient is FALSE or unimplemented, " +
                    "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9");
                ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is FALSE and Open.IsResilient is FALSE.");

                ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext);
                Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            if (Open.IsSessionExisted)
            {
                ModelHelper.Log(LogType.Requirement, "If Open.Session is not NULL, the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.");
                ModelHelper.Log(LogType.TestInfo, "Open.Session is not NULL.");
                ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext);
                Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            // workaround for SE bug
            Condition.IsTrue(Config.IsLeasingSupported == c.IsLeasingSupported);
            Condition.IsTrue(Config.IsDirectoryLeasingSupported == c.IsDirectoryLeasingSupported);

            if (Open.IsLeaseExisted
                && modelOpenFileRequest.oplockLeaseType != OplockLeaseType.LeaseV1
                && modelOpenFileRequest.oplockLeaseType != OplockLeaseType.LeaseV2)
            {
                ModelHelper.Log(LogType.Requirement,
                    "3. If Open.Lease is not NULL and the SMB2_CREATE_REQUEST_LEASE_V2 or the SMB2_CREATE_REQUEST_LEASE create context is not present, " +
                    "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.");
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext);
                Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            if (!Open.IsLeaseExisted
                && (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1
                || modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2))
            {
                ModelHelper.Log(LogType.Requirement,
                    "4. If Open.Lease is NULL and the SMB2_CREATE_REQUEST_LEASE_V2 or the SMB2_CREATE_REQUEST_LEASE create context is present, " +
                    "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.");
                ModelHelper.Log(LogType.TestInfo,
                    "Open.Lease is NULL and {0} is present.",
                    modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1 ? "SMB2_CREATE_REQUEST_LEASE" : "SMB2_CREATE_REQUEST_LEASE_V2");
                ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext);
                Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2
                && ModelUtility.IsSmb3xFamily(NegotiateDialect)
                && Config.IsDirectoryLeasingSupported
                && Open.IsLeaseExisted
                && !modelOpenFileRequest.isSameLeaseKey)
            {
                ModelHelper.Log(LogType.Requirement,
                    "7. If an SMB2_CREATE_REQUEST_LEASE_V2 create context is also present in the request, Connection.Dialect belongs to the SMB 3.x dialect family, " +
                    "the server supports directory leasing, Open.Lease is not NULL, and Open.Lease.LeaseKey does not match the LeaseKey provided in the SMB2_CREATE_REQUEST_LEASE_V2 create context, " +
                    "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9.");
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1
                && (NegotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(NegotiateDialect))
                && Config.IsLeasingSupported
                && Open.IsLeaseExisted
                && !modelOpenFileRequest.isSameLeaseKey)
            {
                ModelHelper.Log(LogType.Requirement,
                    "8. If an SMB2_CREATE_REQUEST_LEASE create context is also present in the request, Connection.Dialect is \"2.100\" or belongs to the SMB 3.x dialect family, " +
                    "the server supports leasing, Open.Lease is not NULL, and Open.Lease.LeaseKey does not match the LeaseKey provided in the SMB2_CREATE_REQUEST_LEASE create context, " +
                    "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9.");
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                return true;
            }

            if (ModelUtility.IsSmb3xFamily(NegotiateDialect)
                && Config.IsDirectoryLeasingSupported
                && Open.IsLeaseExisted
                && Open.LeaseVersion == 2)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If Connection.Dialect belongs to the SMB 3.x dialect family, the server supports directory leasing, Open.Lease is not NULL, " +
                    "and Lease.Version is 2, then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE_V2 create context");
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So the create response should contain SMB2_CREATE_RESPONSE_LEASE_V2 create context.");
                Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2);
            }

            if (ModelUtility.IsSmb3xFamily(NegotiateDialect)
                && Config.IsLeasingSupported
                && Open.IsLeaseExisted
                && Open.LeaseVersion == 1)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If Connection.Dialect belongs to the SMB 3.x dialect family, the server supports leasing, Open.Lease is not NULL, and Lease.Version is 1, " +
                    "then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE Create Context");
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So the create response should contain SMB2_CREATE_RESPONSE_LEASE create context.");
                Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE);
            }

            if (NegotiateDialect == DialectRevision.Smb21
                && Config.IsLeasingSupported
                && Open.IsLeaseExisted)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If Connection.Dialect is \"2.100\", the server supports leasing, and Open.Lease is not NULL, " +
                        "then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE create context");
                ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So the create response should contain SMB2_CREATE_RESPONSE_LEASE create context.");
                if (Open.LeaseVersion == 1)
                    Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE);
                else if (Open.LeaseVersion == 2)
                    Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2);
            }

            return false;
        }
        /// <summary>
        /// This method is used to verify the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context
        /// Cover TD section 3.3.5.9.12
        /// Return true means the message is handled by this function. 
        /// Return false means the message needs further processing.        
        /// </summary>
        private static bool Handling_SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2_CreateContext(
            ModelSmb2Status status,
            ModelOpenFileRequest modelOpenFileRequest,
            LeaseResponseContext leaseResponseContext,
            HandleConfig c)
        {
            ModelHelper.Log(LogType.Requirement, "3.3.5.9.12: Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context");

            if (modelOpenFileRequest.durableV1RequestContext == DurableV1RequestContext.DurableV1RequestContextExist
                || modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextExist
                || modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If the create request also contains SMB2_CREATE_DURABLE_HANDLE_REQUEST context or SMB2_CREATE_DURABLE_HANDLE_RECONNECT context or " +
                    "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 context, the server MUST fail the request with STATUS_INVALID_PARAMETER.");
                ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedContext);

                if (modelOpenFileRequest.durableV1RequestContext == DurableV1RequestContext.DurableV1RequestContextExist)
                {
                    ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_REQUEST is included.");
                }
                if (modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextExist)
                {
                    ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_RECONNECT is included.");
                }
                if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist)
                {
                    ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 is included.");
                }
                Condition.IsTrue(status == ModelSmb2Status.STATUS_INVALID_PARAMETER);
                return true;
            }

            ModelHelper.Log(LogType.Requirement,
                "The server MUST look up an existing open in the GlobalOpenTable by doing a lookup with the FileId.Persistent portion of the create context.");
            ModelHelper.Log(LogType.TestInfo, "Open {0}.", Open != null ? "exists" : "does not exist");

            Condition.IsTrue(Config.Platform == c.Platform);

            if (Open == null)
            {
                ModelHelper.Log(LogType.Requirement,
                    "If the lookup fails, the server SHOULD<276> fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9.");
                ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier);

                if (Config.Platform == Platform.NonWindows)
                {
                    ModelHelper.Log(LogType.TestInfo, "The SUT platform is NonWindows, so the server could fail the request with other error code.");
                    Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS);
                }
                else if (Config.Platform == Platform.WindowsServer2012
                    && modelOpenFileRequest.durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextExistWithPersistent)
                {
                    // Windows 2012 fails the request, but the error code is not a fixed one.
                    Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS);
                }
                else
                {
                    ModelHelper.Log(LogType.TestInfo, "The SUT platform is {0}.", Config.Platform);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                }

                return true;
            }
            else
            {
                // Workaround to resolve SE bug
                Condition.IsTrue(Config.IsLeasingSupported == c.IsLeasingSupported);
                Condition.IsTrue(Config.IsDirectoryLeasingSupported == c.IsDirectoryLeasingSupported);

                if (Open.IsLeaseExisted && !modelOpenFileRequest.isSameClient)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.Lease is not NULL and Open.ClientGuid is not equal to the ClientGuid of the connection that received this request, " +
                        "the server MUST fail the create request with STATUS_OBJECT_NAME_NOT_FOUND.");
                    ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                    ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                    return true;
                }

                // TDI 72308
                if (Open.IsPersistent && modelOpenFileRequest.durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextExistWithoutPersistent)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.IsPersistent is TRUE and the SMB2_DHANDLE_FLAG_PERSISTENT bit is not set in the Flags field of the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context, " +
                        "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.");
                    ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                    ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                    return true;
                }

                if (!modelOpenFileRequest.isSameCreateGuid)
                {
                    if (Config.Platform == Platform.WindowsServer2012
                        && modelOpenFileRequest.durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextExistWithPersistent)
                    {
                        // Windows 2012 fails the request, but the error code is not a fixed one.
                        Condition.IsTrue(status != ModelSmb2Status.STATUS_SUCCESS);
                    }
                    else
                    {
                        ModelHelper.Log(LogType.Requirement,
                            "If Open.CreateGuid is not equal to the CreateGuid in the request, the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.");
                        ModelHelper.Log(LogType.TestInfo, "Open.CreateGuid is not equal to the CreateGuid in the request.");
                        ModelHelper.Log(LogType.TestTag, TestTag.InvalidIdentifier);
                        Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                    }
                    return true;
                }

                if (!Open.IsDurable)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.IsDurable is FALSE and Open.IsResilient is FALSE or unimplemented, " +
                        "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9.");
                    ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is FALSE and Open.IsResilient is FALSE.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                    return true;
                }

                // TDI, if Open.IsPersistent is true, then when reconnecting, if Open.Session is not NULL, the reconnect can still succeed.
                if (!Open.IsPersistent && Open.IsSessionExisted)
                {
                    ModelHelper.Log(LogType.Requirement, "If Open.Session is not NULL, the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND. ");
                    ModelHelper.Log(LogType.TestInfo, "Open.Session is not NULL.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                    return true;
                }

                if ((!Open.IsLeaseExisted
                        && (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1
                            || modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2))
                    || (Open.IsLeaseExisted
                        && modelOpenFileRequest.oplockLeaseType != OplockLeaseType.LeaseV1
                        && modelOpenFileRequest.oplockLeaseType != OplockLeaseType.LeaseV2))
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If Open.Lease is NULL and the SMB2_CREATE_REQUEST_LEASE or SMB2_CREATE_REQUEST_LEASE_V2 create context is present, " +
                        "or if Open.Lease is NOT NULL and the SMB2_CREATE_REQUEST_LEASE or SMB2_CREATE_REQUEST_LEASE_V2 create context is not present, " +
                        "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND.");
                    ModelHelper.Log(LogType.TestInfo, "Open.Lease is{0} NULL.", Open.IsLeaseExisted ? " not" : "");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1)
                    {
                        ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_REQUEST_LEASE is present.");
                    }
                    else if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2)
                    {
                        ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_REQUEST_LEASE_V2 is present.");
                    }
                    else
                    {
                        ModelHelper.Log(LogType.TestInfo, "SMB2_CREATE_REQUEST_LEASE or SMB2_CREATE_REQUEST_LEASE_V2 create context is not present.");
                    }
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                    return true;
                }

                if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2
                    && Config.IsDirectoryLeasingSupported
                    && Open.IsLeaseExisted
                    && !modelOpenFileRequest.isSameLeaseKey)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If an SMB2_CREATE_REQUEST_LEASE_V2 create context is also present in the request, " +
                        "the server supports directory leasing, and Open.Lease.LeaseKey does not match the LeaseKey provided in the SMB2_CREATE_REQUEST_LEASE_V2 create context, " +
                        "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9.");
                    ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                    return true;
                }

                if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1
                    && Config.IsLeasingSupported
                    && Open.IsLeaseExisted
                    && !modelOpenFileRequest.isSameLeaseKey)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If an SMB2_CREATE_REQUEST_LEASE create context is also present in the request, the server supports leasing, " +
                        "and Open.Lease.LeaseKey does not match the LeaseKey provided in the SMB2_CREATE_REQUEST_LEASE create context, " +
                        "the server MUST fail the request with STATUS_OBJECT_NAME_NOT_FOUND and proceed as specified in \"Failed Open Handling\" in section 3.3.5.9.");
                    ModelHelper.Log(LogType.TestInfo, "All the above conditions are met.");
                    ModelHelper.Log(LogType.TestTag, TestTag.UnexpectedFields);
                    Condition.IsTrue(status == ModelSmb2Status.STATUS_OBJECT_NAME_NOT_FOUND);
                    return true;
                }

                ModelHelper.Log(LogType.Requirement, "In the \"Response Construction\" phase:");

                // TDI 71165
                if (Config.IsDirectoryLeasingSupported
                    && modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV2)
                {
                    ModelHelper.Log(LogType.Requirement, "If the server supports directory leasing, and the request contains SMB2_CREATE_REQUEST_LEASE_V2 Create Context, " +
                        "then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE_V2 Create Context");
                    ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So create response should contain an SMB2_CREATE_RESPONSE_LEASE_V2 Create Context.");
                    if (Open.LeaseVersion == 1)
                        Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE);
                    else if (Open.LeaseVersion == 2)
                        Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2);
                }

                // TDI 71165
                if (modelOpenFileRequest.oplockLeaseType == OplockLeaseType.LeaseV1
                    && Config.IsLeasingSupported
                    && Open.IsLeaseExisted)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If the request contains an SMB2_CREATE_REQUEST_LEASE Create Context, " +
                        "the server supports leasing and Open.Lease is not NULL, then the server MUST construct an SMB2_CREATE_RESPONSE_LEASE create context");
                    ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So create response should contain an SMB2_CREATE_RESPONSE_LEASE Create Context.");

                    if (Open.LeaseVersion == 1)
                        Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE);
                    else if (Open.LeaseVersion == 2)
                        Condition.IsTrue(leaseResponseContext == LeaseResponseContext.SMB2_CREATE_RESPONSE_LEASE_V2);
                }
            }

            return false;
        }
        public static void OpenResponse(
            ModelSmb2Status status,
            DurableHandleResponseContext durableHandleResponseContext,
            LeaseResponseContext leaseResponseContext,
            HandleConfig c)
        {
            Condition.IsNotNull(Request);

            ModelOpenFileRequest modelOpenFileRequest = ModelHelper.RetrieveOutstandingRequest<ModelOpenFileRequest>(ref Request);

            if (ModelUtility.IsSmb3xFamily(NegotiateDialect)
                && modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextNotExist
                && modelOpenFileRequest.durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextNotExist)
            {
                ModelHelper.Log(LogType.Requirement,
                    "3.3.5.9: If Connection.Dialect belongs to the SMB 3.x dialect family and " +
                    "the request does not contain SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context or SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context, " +
                    "the server MUST look up an existing open in the GlobalOpenTable where Open.FileName matches the file name in the Buffer field of the request. ");
                ModelHelper.Log(LogType.TestInfo,
                    "Connection.Dialect is {0} and the request does not contain SMB2_CREATE_DURABLE_HANDLE_RECONNECT or SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context.",
                    NegotiateDialect);

                if (Open != null
                    && !modelOpenFileRequest.isSameClient
                    && Open.IsPersistent
                    && !Open.IsConnectionExisted
                    && !Open.IsBatchOplockExisted
                    && !Open.IsLeaseExisted)
                {
                    ModelHelper.Log(LogType.Requirement,
                        "If an Open entry is found, and if all the following conditions are satisfied, " +
                        "the server MUST fail the request with STATUS_FILE_NOT_AVAILABLE.");
                    ModelHelper.Log(LogType.Requirement, "\tOpen.IsPersistent is TRUE");
                    ModelHelper.Log(LogType.Requirement, "\tOpen.Connection is NULL");
                    ModelHelper.Log(LogType.Requirement, "\tOpen.OplockLevel is not equal to SMB2_OPLOCK_LEVEL_BATCH");
                    ModelHelper.Log(LogType.Requirement, "\tOpen.OplockLevel is not equal to SMB2_OPLOCK_LEVEL_LEASE or Open.Lease.LeaseState does not include SMB2_LEASE_HANDLE_CACHING");

                    ModelHelper.Log(LogType.TestInfo, "The Open is found, and all the conditions are satisfied.");
                    ModelHelper.Log(LogType.TestTag, TestTag.Compatibility);

                    Condition.IsTrue(status == ModelSmb2Status.STATUS_FILE_NOT_AVAILABLE);
                    return;
                }
            }

            // TD section 3.3.5.9.6: Handling the SMB2_CREATE_DURABLE_HANDLE_REQUEST Create Context
            if (modelOpenFileRequest.durableV1RequestContext == DurableV1RequestContext.DurableV1RequestContextExist)
            {
                if (Handling_SMB2_CREATE_DURABLE_HANDLE_REQUEST_CreateContext(status, modelOpenFileRequest, durableHandleResponseContext, c))
                    return;
            }

            // TD section 3.3.5.9.7: Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT Create Context
            if (modelOpenFileRequest.durableV1ReconnectContext == DurableV1ReconnectContext.DurableV1ReconnectContextExist)
            {
                if (Handling_SMB2_CREATE_DURABLE_HANDLE_RECONNECT_CreateContext(status, modelOpenFileRequest, leaseResponseContext, c))
                    return;
            }

            // TD section 3.3.5.9.10: Handling the SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2 Create Context
            if (modelOpenFileRequest.durableV2RequestContext != DurableV2RequestContext.DurableV2RequestContextNotExist)
            {
                if (Handling_SMB2_CREATE_DURABLE_HANDLE_REQUEST_V2_CreateContext(status, modelOpenFileRequest, durableHandleResponseContext))
                    return;
            }

            // TD section 3.3.5.9.12: Handling the SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2 Create Context
            if (modelOpenFileRequest.durableV2ReconnectContext != DurableV2ReconnectContext.DurableV2ReconnectContextNotExist)
            {
                if (Handling_SMB2_CREATE_DURABLE_HANDLE_RECONNECT_V2_CreateContext(status, modelOpenFileRequest, leaseResponseContext, c))
                    return;
            }

            Condition.IsTrue(status == Smb2Status.STATUS_SUCCESS);
        }