/// <summary>
        /// Assembles the StreamMetadataBody object from byte array
        /// </summary>
        /// <param name="reader">BinaryReader to deserialize from</param>
        /// <returns>StreamMetadataBody object</returns>
        public StreamMetadataBody Read(BinaryReader reader)
        {
            var metadataKind          = (StreamMetadataKind)reader.ReadInt32();
            StreamMetadataBody result = null;

            switch (metadataKind)
            {
            case StreamMetadataKind.ReceiveSequenceNumber:
            case StreamMetadataKind.SendSequenceNumber:
            case StreamMetadataKind.DeleteSequenceNumber:
                result = StreamSequenceNumber.FromByteArray(reader);
                break;

            case StreamMetadataKind.OutboundStableParameters:
                result = OutboundStreamStableParameters.FromByteArray(reader);
                break;

            case StreamMetadataKind.InboundStableParameters:
                result = InboundStreamStableParameters.FromByteArray(reader);
                break;

            default:
                Diagnostics.Assert(false, "Unknown Stream MetadataKind in StreamMetadataBody.FromByteArray()");
                break;
            }

            return(result);
        }
        /// <summary>
        /// Assembles the StreamSequenceNumber object from byte array
        /// </summary>
        /// <param name="reader">BinaryReader to deserialize from</param>
        /// <returns>StreamSequenceNumber object</returns>
        public static StreamSequenceNumber FromByteArray(BinaryReader reader)
        {
            var metadataKind             = (StreamMetadataKind)reader.ReadInt32();
            var nextStreamSequenceNumber = reader.ReadInt64();

            StreamSequenceNumber result = null;

            // Assemble the right stream metadata
            switch (metadataKind)
            {
            case StreamMetadataKind.ReceiveSequenceNumber:
                result = new ReceiveStreamSequenceNumber(nextStreamSequenceNumber);
                break;

            case StreamMetadataKind.SendSequenceNumber:
                result = new SendStreamSequenceNumber(nextStreamSequenceNumber);
                break;

            case StreamMetadataKind.DeleteSequenceNumber:
                result = new DeleteStreamSequenceNumber(nextStreamSequenceNumber);
                break;
            }

            return(result);
        }