/// <summary>

        /// Converts the contents of the message into an array of bytes

        /// </summary>

        /// <returns>Array of bytes</returns>

        public override byte[] GetBytes()

        {
            List <byte> allBytes = new List <byte>();

            List <byte> messageBytes = new List <byte>();

            List <BinaryData> allBinaryData = new List <BinaryData>();



            allBinaryData.AddRange(this.binaryData);



            // additional sections

            messageBytes.AddRange(this.bytes);

            foreach (MessageSection section in this.sections)

            {
                messageBytes.AddRange(blankLineBytes);

                messageBytes.AddRange(section.GetBytes());

                allBinaryData.AddRange(section.BinaryData);
            }



            // encrypt message

            byte[] bytesToEncrypt = messageBytes.ToArray();

            EncryptionResult result = key.Encrypt(bytesToEncrypt);



            string encryptionInfo = DisplayName.Fetch(key.EncryptionAlgorithm);

            if (key.EncryptionAlgorithm != Cryptography.SymmetricAlgorithmType.PlainText)

            {
                string iv = Cryptography.HexEncode(result.IV);

                encryptionInfo = String.Format("{0}:{1}", encryptionInfo, iv);
            }



            string hashInfo = "";

            if (includeKeyHash)

            {
                string keyHash = key.KeyHash;

                string salt = key.Salt;

                hashInfo = String.Format(" {0}:{1}.{2}", DisplayName.Fetch(key.HashAlgorithm), keyHash, salt);
            }



            // start building message

            string s = String.Format("{0} {1}{2}", messageType, encryptionInfo, hashInfo);

            allBytes.AddRange(protocolHeaderBytes);

            allBytes.AddRange(GetStringBytes(s.ToUpper()));

            allBytes.AddRange(blankLineBytes);



            if (key.EncryptionAlgorithm != Cryptography.SymmetricAlgorithmType.PlainText)

            {
                /* use this to add the Length: header to the main section
                 *
                 * MessageSection lengthSection = new MessageSection();
                 *
                 * lengthSection.AddHeader(new Header(Header.RESOURCE_LENGTH, result.EncryptedBytes.Length.ToString()));
                 *
                 * lengthSection.AddBlankLine();
                 *
                 * allBytes.AddRange(lengthSection.GetBytes());
                 *
                 * */

                allBytes.AddRange(result.EncryptedBytes);

                allBytes.AddRange(blankLineBytes);
            }

            else

            {
                allBytes.AddRange(result.EncryptedBytes);
            }



            // handle binary resources

            foreach (BinaryData data in allBinaryData)

            {
                if (data != null && data.Data != null)

                {
                    // encrypt each resource, making sure to use the same IV

                    EncryptionResult er = key.Encrypt(data.Data, ref result.IV);



                    MessageSection section = new MessageSection();

                    section.AddBlankLine();

                    section.AddHeader(new Header(Header.RESOURCE_IDENTIFIER, data.ID));

                    section.AddHeader(new Header(Header.RESOURCE_LENGTH, er.EncryptedBytes.Length.ToString()));

                    section.AddBlankLine();

                    allBytes.AddRange(section.GetBytes());

                    allBytes.AddRange(er.EncryptedBytes);

                    allBytes.AddRange(blankLineBytes);
                }
            }

            allBytes.AddRange(blankLineBytes);



            return(allBytes.ToArray());
        }