void EncryptAndWriteHeader(MessageHeader plainTextHeader, string id, MemoryStream stream, XmlDictionaryWriter writer)
        {
            EncryptedHeader encryptedHeader = EncryptHeader(
                plainTextHeader,
                this.encryptingSymmetricAlgorithm, this.encryptionKeyIdentifier, this.Version,
                id, stream);

            encryptedHeader.WriteHeader(writer, this.Version);
        }
        private void ApplySecurityAndWriteHeader(MessageHeader header, string headerId, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
        {
            if ((!base.RequireMessageProtection && base.ShouldSignToHeader) && ((header.Name == System.ServiceModel.XD.AddressingDictionary.To.Value) && (header.Namespace == base.Message.Version.Addressing.Namespace)))
            {
                byte[] buffer;
                if (this.toHeaderHash != null)
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(System.ServiceModel.SR.GetString("TransportSecuredMessageHasMoreThanOneToHeader")));
                }
                headerId          = this.GetSignatureHash(header, headerId, prefixGenerator, writer, out buffer);
                this.toHeaderHash = buffer;
                this.toHeaderId   = headerId;
            }
            else
            {
                MemoryStream stream;
                string       str;
                switch (this.GetProtectionMode(header))
                {
                case MessagePartProtectionMode.None:
                    header.WriteHeader(writer, base.Version);
                    return;

                case MessagePartProtectionMode.Sign:
                    this.AddSignatureReference(header, headerId, prefixGenerator, writer);
                    return;

                case MessagePartProtectionMode.Encrypt:
                    this.AddEncryptionReference(header, headerId, prefixGenerator, false, out stream, out str);
                    this.EncryptAndWriteHeader(header, str, stream, writer);
                    return;

                case MessagePartProtectionMode.SignThenEncrypt:
                    this.AddEncryptionReference(header, headerId, prefixGenerator, true, out stream, out str);
                    this.EncryptAndWriteHeader(header, str, stream, writer);
                    this.hasSignedEncryptedMessagePart = true;
                    return;

                case MessagePartProtectionMode.EncryptThenSign:
                {
                    this.AddEncryptionReference(header, headerId, prefixGenerator, false, out stream, out str);
                    EncryptedHeader header2 = this.EncryptHeader(header, this.encryptingSymmetricAlgorithm, this.encryptionKeyIdentifier, base.Version, str, stream);
                    this.AddSignatureReference(header2, str, prefixGenerator, writer);
                    return;
                }
                }
            }
        }
        void ApplySecurityAndWriteHeader(MessageHeader header, string headerId, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator)
        {
            if (!this.RequireMessageProtection && this.ShouldSignToHeader)
            {
                if ((header.Name == XD.AddressingDictionary.To.Value) &&
                    (header.Namespace == this.Message.Version.Addressing.Namespace))
                {
                    if (this.toHeaderHash == null)
                    {
                        byte[] headerHash;
                        headerId          = GetSignatureHash(header, headerId, prefixGenerator, writer, out headerHash);
                        this.toHeaderHash = headerHash;
                        this.toHeaderId   = headerId;
                    }
                    else
                    {
                        // More than one 'To' header is specified in the message.
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TransportSecuredMessageHasMoreThanOneToHeader)));
                    }

                    return;
                }
            }

            MessagePartProtectionMode protectionMode = GetProtectionMode(header);
            MemoryStream plainTextStream;
            string       encryptedDataId;

            switch (protectionMode)
            {
            case MessagePartProtectionMode.None:
                header.WriteHeader(writer, this.Version);
                return;

            case MessagePartProtectionMode.Sign:
                AddSignatureReference(header, headerId, prefixGenerator, writer);
                return;

            case MessagePartProtectionMode.SignThenEncrypt:
                AddEncryptionReference(header, headerId, prefixGenerator, true, out plainTextStream, out encryptedDataId);
                EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer);
                this.hasSignedEncryptedMessagePart = true;
                return;

            case MessagePartProtectionMode.Encrypt:
                AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId);
                EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer);
                return;

            case MessagePartProtectionMode.EncryptThenSign:
                AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId);
                EncryptedHeader encryptedHeader = EncryptHeader(
                    header, this.encryptingSymmetricAlgorithm, this.encryptionKeyIdentifier, this.Version, encryptedDataId, plainTextStream);
                AddSignatureReference(encryptedHeader, encryptedDataId, prefixGenerator, writer);
                return;

            default:
                Fx.Assert("Invalid MessagePartProtectionMode");
                return;
            }
        }