/// <summary>
        /// Creates a SearchResultDone packet.
        /// </summary>
        /// <param name="context">The user context which contains message ID.</param>
        /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param>
        /// <param name="matchedDn">Matched DN.</param>
        /// <param name="errorMessage">Error message for result code. Required.</param>
        /// <param name="referral">Referral. Optional.</param>
        /// <returns>The packet that contains the response.</returns>
        internal override AdtsSearchResultDonePacket CreateSearchResultDone(
            AdtsLdapContext context,
            MsLdap.ResultCode resultCode,
            string matchedDn,
            string errorMessage,
            string[] referral)
        {
            SearchResultDone searchResultDone = new SearchResultDone(
                new LDAPResult_resultCode((long)resultCode),
                new LDAPDN(matchedDn ?? string.Empty),
                new LDAPString(errorMessage ?? string.Empty),
                CreateReferral(referral));

            LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp();
            operation.SetData(LDAPMessage_protocolOp.searchResDone, searchResultDone);

            LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null);
            AdtsSearchResultDonePacket packet = new AdtsSearchResultDonePacket();
            packet.ldapMessagev3 = message;
            packet.messageId = context.MessageId;

            return packet;
        }
        /// <summary>
        /// Creates a SicilyBindResponse packet.
        /// </summary>
        /// <param name="context">The user context which contains message ID.</param>
        /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param>
        /// <param name="serverCredentials">Server credentials, optional for normal and sicily bind.</param>
        /// <param name="errorMessage">Error message for result code. Required.</param>
        /// <returns>The packet that contains the response.</returns>
        internal override AdtsSicilyBindResponsePacket CreateSicilyBindResponse(
            AdtsLdapContext context,
            MsLdap.ResultCode resultCode,
            byte[] serverCredentials,
            string errorMessage)
        {
            SicilyBindResponse sicilyBindResponse = new SicilyBindResponse(
                new SicilyBindResponse_resultCode((long)resultCode),
                new Asn1OctetString(serverCredentials ?? (new byte[0])),
                new LDAPString(errorMessage ?? string.Empty));

            LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp();
            operation.SetData(LDAPMessage_protocolOp.sicilybindResponse, sicilyBindResponse);

            LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null);
            AdtsSicilyBindResponsePacket packet = new AdtsSicilyBindResponsePacket();
            packet.ldapMessagev3 = message;
            packet.messageId = context.MessageId;

            return packet;
        }
        /// <summary>
        /// Creates a SearchRequest packet.
        /// </summary>
        /// <param name="context">The user context which contains message ID.</param>
        /// <param name="dn">The DN to be searched.</param>
        /// <param name="sizeLimit">Size limit.</param>
        /// <param name="timeLimit">Time limit, in seconds.</param>
        /// <param name="scope">Search scope. Base, single level, or subtree.</param>
        /// <param name="dereferenceAliases">Dereference aliase options.</param>
        /// <param name="filter">Search filter.</param>
        /// <param name="typesOnly">
        /// Specifies whether the search returns only the attribute names without the attribute values.
        /// </param>
        /// <param name="attributes">The attributes to be retrieved.</param>
        /// <returns>The packet that contains the request.</returns>
        internal override AdtsSearchRequestPacket CreateSearchRequest(
            AdtsLdapContext context,
            string dn,
            long sizeLimit,
            long timeLimit,
            MsLdap.SearchScope scope,
            MsLdap.DereferenceAlias dereferenceAliases,
            Asn1Choice filter,
            bool typesOnly,
            params string[] attributes)
        {
            int length = (attributes != null) ? attributes.Length : 0;

            AttributeDescription[] attributeDescriptionArray = new AttributeDescription[length];
            for (int i = 0; i < length; i++)
            {
                attributeDescriptionArray[i] = new AttributeDescription(attributes[i]);
            }
            AttributeDescriptionList attributeList = new AttributeDescriptionList(attributeDescriptionArray);

            SearchRequest searchRequest = new SearchRequest(
                new LDAPDN(dn ?? string.Empty),
                new SearchRequest_scope((long)scope),
                new SearchRequest_derefAliases((long)dereferenceAliases),
                new Asn1Integer(sizeLimit),
                new Asn1Integer(timeLimit),
                new Asn1Boolean(typesOnly),
                (Filter)filter,
                attributeList);

            LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp();
            operation.SetData(LDAPMessage_protocolOp.searchRequest, searchRequest);

            LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null);
            AdtsSearchRequestPacket packet = new AdtsSearchRequestPacket();
            packet.ldapMessagev3 = message;
            packet.messageId = context.MessageId;

            return packet;
        }
        /// <summary>
        /// Creates a BindResponse for normal bindings, SASL bindings and sicily bindings.
        /// </summary>
        /// <param name="context">The user context which contains message ID.</param>
        /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param>
        /// <param name="matchedDn">Matched DN. Required, but can be an empty string.</param>
        /// <param name="errorMessage">Error message for result code. Required.</param>
        /// <param name="referral">Referral. Optional and for LDAP v3 only.</param>
        /// <param name="serverCredentials">Server credentials, optional for normal bind.</param>
        /// <returns>The packet that contains the response.</returns>
        internal override AdtsBindResponsePacket CreateBindResponse(
            AdtsLdapContext context,
            MsLdap.ResultCode resultCode,
            string matchedDn,
            string errorMessage,
            string[] referral,
            byte[] serverCredentials)
        {
            BindResponse bindResponse = new BindResponse(
                new LDAPResult_resultCode((long)resultCode),
                new LDAPDN(matchedDn ?? string.Empty),
                new LDAPString(errorMessage ?? string.Empty),
                CreateReferral(referral),
                new Asn1OctetString(serverCredentials ?? (new byte[0])));

            LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp();
            operation.SetData(LDAPMessage_protocolOp.bindResponse, bindResponse);

            LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation, null);
            AdtsBindResponsePacket packet = new AdtsBindResponsePacket();
            packet.ldapMessagev3 = message;
            packet.messageId = context.MessageId;

            return packet;
        }
 /// <summary>
 /// Creates a SearchResultDone packet.  For LDAP v3 only.
 /// </summary>
 /// <param name="context">The user context which contains message ID.</param>
 /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param>
 /// <param name="matchedDn">Matched DN.</param>
 /// <param name="errorMessage">Error message for result code. Required.</param>
 /// <param name="referral">Referral. Optional.</param>
 /// <returns>The packet that contains the response.</returns>
 internal override AdtsSearchResultDonePacket CreateSearchResultDone(
     AdtsLdapContext context,
     MsLdap.ResultCode resultCode,
     string matchedDn,
     string errorMessage,
     string[] referral)
 {
     throw new NotSupportedException();
 }
        /// <summary>
        /// Creates a ModifyResponse packet.
        /// </summary>
        /// <param name="context">The user context which contains message ID.</param>
        /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param>
        /// <param name="matchedDn">Matched DN.</param>
        /// <param name="errorMessage">Error message for result code. Required.</param>
        /// <param name="referral">Referral. Optional. Used for LDAP v3 only.</param>
        /// <returns>The packet that contains the response.</returns>
        internal override AdtsModifyResponsePacket CreateModifyResponse(
            AdtsLdapContext context,
            MsLdap.ResultCode resultCode,
            string matchedDn,
            string errorMessage,
            string[] referral)
        {
            ModifyResponse modifyResponse = new ModifyResponse(
                new LDAPResult_resultCode((long)resultCode),
                new LDAPDN(matchedDn ?? string.Empty),
                new LDAPString(errorMessage ?? string.Empty));

            LDAPMessage_protocolOp operation = new LDAPMessage_protocolOp();
            operation.SetData(LDAPMessage_protocolOp.modifyResponse, modifyResponse);

            LDAPMessage message = new LDAPMessage(new MessageID(context.MessageId), operation);
            AdtsModifyResponsePacket packet = new AdtsModifyResponsePacket();
            packet.ldapMessagev2 = message;
            packet.messageId = context.MessageId;

            return packet;
        }
 /// <summary>
 /// Creates an ExtendedResponse packet. For LDAP v3 only.
 /// </summary>
 /// <param name="context">The user context which contains message ID.</param>
 /// <param name="resultCode">Result code of previous request, as specified in RFC 2251.</param>
 /// <param name="matchedDn">Matched DN.</param>
 /// <param name="errorMessage">Error message for result code. Required.</param>
 /// <param name="referral">Referral. Optional. Used for LDAP v3 only.</param>
 /// <returns>The packet that contains the response.</returns>
 internal override AdtsExtendedResponsePacket CreateExtendedResponse(
     AdtsLdapContext context,
     MsLdap.ResultCode resultCode,
     string matchedDn,
     string errorMessage,
     string[] referral)
 {
     throw new NotSupportedException();
 }