#![allow(
    clippy::cast_possible_truncation,
    clippy::cast_possible_wrap,
    clippy::cast_precision_loss,
    clippy::cast_sign_loss,
    clippy::float_cmp,
    clippy::needless_pass_by_value,
    clippy::too_many_lines
)]

// Exact fixture provenance at LibreMetaverse 2aa70bb68513b39795da5d13c88f31b86e85a3ba:
// HelpersZeroCodingTests.cs aa6d3b654e50c4128c5d21e16a74c589a020b8d9273af1a6c22b9b14caeedd7c
// MessageTests.cs           49fcbadbfd82ec0fb9b98944cf785e073976ddb85b05b7f52c50ff2b3e662fb7
// PacketTests.cs            0519e92ff9385d7be8b972331b14c8b522d1cae507f0c834408edd99c75513d8
// TypeTests.cs              ac07dba8b9db3a4a79143f27024e6074c84b7f3dbbe6179fa784c0f4184b1b0a
// Generated packet source links:
// SourceGenerators/PacketSourceGenerator/PacketSourceGenerator.cs
// data/message_template.msg

use libremetaverse::messages::linden::*;
use libremetaverse::packets::{
    DirPlacesReplyPacket, DirPlacesReplyPacketQueryDataBlock,
    DirPlacesReplyPacketQueryRepliesBlock, DirPlacesReplyPacketStatusDataBlock,
    InventoryDescendentsPacket, InventoryDescendentsPacketFolderDataBlock,
    InventoryDescendentsPacketItemDataBlock, Packet, PacketType, ParcelReturnObjectsPacket,
    ParcelReturnObjectsPacketOwnerIDsBlock, ScriptDialogPacket, ScriptDialogPacketOwnerDataBlock,
    TestMessagePacket,
};
use libremetaverse::{
    BitPack, GroupPowers, Helpers, InstantMessageDialog, InstantMessageOnline, LandingType,
    ParcelCategory, ParcelFlags, ParcelResult, ParcelStatus, SimAccess, TeleportFlags,
};
use libremetaverse_structured_data::OSDParser;
use libremetaverse_types::compat::Uri;
use libremetaverse_types::{UUID, Utils, Vector3};
use std::fmt::Write as _;
use std::net::{IpAddr, Ipv4Addr};
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};

fn copy_uuid(value: &UUID) -> UUID {
    UUID::new_with_bytes_int32(value.get_bytes().expect("UUID bytes"), 0)
        .expect("UUID byte constructor")
}

fn random_uuid() -> UUID {
    UUID::random().expect("UUID Random")
}

fn assert_uuid_eq(actual: &UUID, expected: &UUID) {
    assert_eq!(
        actual.get_bytes().expect("actual UUID bytes"),
        expected.get_bytes().expect("expected UUID bytes")
    );
}

fn vector(text: &str) -> Vector3 {
    Vector3::parse(text.into()).expect("Vector3 Parse")
}

fn assert_vector_eq(actual: &Vector3, expected: &Vector3) {
    assert_eq!(
        [actual.x, actual.y, actual.z],
        [expected.x, expected.y, expected.z]
    );
}

fn utc(seconds: u64) -> SystemTime {
    UNIX_EPOCH + Duration::from_secs(seconds)
}

fn test_uri() -> Uri {
    Uri("https://sim3187.agni.lindenlab.com:12043/cap/6028fc44-c1e5-80a1-f902-19bde114458b".into())
}

fn test_ip() -> IpAddr {
    IpAddr::V4(Ipv4Addr::LOCALHOST)
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroDecode_ValidInput_DecodesCorrectly::test 62353da2b1afb7bfdf5142706d15d22086a5e1e8c55f39af3e64686dda4ea071 translated
#[test]
fn zero_decode_valid_input_decodes_correctly() {
    let src = [
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x03, 0xff, 0x00, 0x01, 0xaa,
    ];
    let mut dest = [0; 100];
    let len = Helpers::zero_decode(Some(&src), src.len() as i32, Some(&mut dest))
        .expect("Helpers ZeroDecode");
    assert_eq!(len, 12);
    assert_eq!(
        [
            dest[0], dest[5], dest[6], dest[7], dest[8], dest[9], dest[10], dest[11]
        ],
        [0x00, 0x05, 0x00, 0x00, 0x00, 0xff, 0x00, 0xaa]
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroDecode_NullSource_ThrowsArgumentNullException::test 50ebbd8ea35b87df18cccdea9a26534d5c142228e5b1698cf191b9fd2e9a9957 translated
#[test]
fn zero_decode_null_source_throws_argument_null() {
    let mut dest = [0; 100];
    let result = Helpers::zero_decode(None, 10, Some(&mut dest));
    assert!(
        matches!(&result, Err(libremetaverse::Error::ArgumentNull)),
        "expected ArgumentNull, got {result:?}"
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroDecode_NullDestination_ThrowsArgumentNullException::test 97197cffb02908653d831f3a62cdce2c1ddd52818343e9aacebc9b4c5ac1ee3e translated
#[test]
fn zero_decode_null_destination_throws_argument_null() {
    let src = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0xff];
    let result = Helpers::zero_decode(Some(&src), src.len() as i32, None);
    assert!(
        matches!(&result, Err(libremetaverse::Error::ArgumentNull)),
        "expected ArgumentNull, got {result:?}"
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroDecode_SrclenTooSmall_ThrowsArgumentException::test 8748294ccd1943938bdbb3dbe4550436e920db9a9210d55eca77e85f6d0b60fb translated
#[test]
fn zero_decode_source_length_too_small_throws_argument() {
    let src = [0x00, 0x01, 0x02];
    let mut dest = [0; 100];
    let result = Helpers::zero_decode(Some(&src), 3, Some(&mut dest));
    assert!(
        matches!(&result, Err(libremetaverse::Error::Argument)),
        "expected Argument, got {result:?}"
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroDecode_SrclenGreaterThanSrcLength_ThrowsArgumentException::test ef428c72c4c0abb15c07c5845a7228df3d8bad6aa2b9c7ac2969e5c9be08572b translated
#[test]
fn zero_decode_source_length_too_large_throws_argument() {
    let src = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05];
    let mut dest = [0; 100];
    let result = Helpers::zero_decode(Some(&src), 100, Some(&mut dest));
    assert!(
        matches!(&result, Err(libremetaverse::Error::Argument)),
        "expected Argument, got {result:?}"
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroDecode_DestinationTooSmall_ThrowsIndexOutOfRangeException::test 04b914171f3f11a98262463c29edb662a6e0f10a3e1c6e63c38d8caf63dcb5a0 translated
#[test]
fn zero_decode_destination_too_small_throws_index_out_of_range() {
    let src = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0xff];
    let mut dest = [0; 10];
    let result = Helpers::zero_decode(Some(&src), src.len() as i32, Some(&mut dest));
    assert!(
        matches!(&result, Err(libremetaverse::Error::IndexOutOfRange)),
        "expected IndexOutOfRange, got {result:?}"
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroDecode_ReadingZeroCountOutOfBounds_IsToleratedAsSingleZero::test 9bc5e127e69588a9d90a5b441b2ee401b6e9c370c7a30a5285f283bb24451bd0 translated
#[test]
fn zero_decode_trailing_marker_is_single_zero() {
    let src = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00];
    let mut dest = [0; 100];
    let len = Helpers::zero_decode(Some(&src), src.len() as i32, Some(&mut dest))
        .expect("Helpers ZeroDecode");
    assert_eq!(len, 7);
    assert_eq!(dest[6], 0);
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroEncode_ValidInput_EncodesCorrectly::test d3f546b602f78aacb18b53feddfc3b824f7a87f7318a661b23f1aedded520dec translated
#[test]
fn zero_encode_valid_input_encodes_correctly() {
    let src = [
        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00, 0xff, 0x00, 0xaa,
    ];
    let mut encoded = [0; 100];
    let encoded_len = Helpers::zero_encode(Some(&src), src.len() as i32, Some(&mut encoded))
        .expect("Helpers ZeroEncode");
    assert!(encoded_len > 0);
    let mut decoded = [0; 100];
    let decoded_len = Helpers::zero_decode(Some(&encoded), encoded_len, Some(&mut decoded))
        .expect("Helpers ZeroDecode");
    assert_eq!(decoded_len as usize, src.len());
    assert_eq!(&decoded[..src.len()], src);
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroEncode_255ConsecutiveZeros_HandlesOverflowCorrectly::test a642c8fab0b10ca777dc0090327054c501174a198b2d4f700c116937e11ad202 translated
#[test]
fn zero_encode_255_zeros_handles_overflow() {
    let mut src = [0; 262];
    src[..6].copy_from_slice(&[0, 1, 2, 3, 4, 5]);
    let mut encoded = [0; 500];
    let encoded_len = Helpers::zero_encode(Some(&src), src.len() as i32, Some(&mut encoded))
        .expect("Helpers ZeroEncode");
    assert!(encoded_len > 0);
    let mut decoded = [0; 500];
    let decoded_len = Helpers::zero_decode(Some(&encoded), encoded_len, Some(&mut decoded))
        .expect("Helpers ZeroDecode");
    assert_eq!(decoded_len as usize, src.len());
    assert_eq!(&decoded[..6], &src[..6]);
    assert!(decoded[6..src.len()].iter().all(|byte| *byte == 0));
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroEncode_NullSource_ThrowsArgumentNullException::test 9568ba89a96735a440fac426285d5eeca929c61bfd2cb674d54d3009e9924906 translated
#[test]
fn zero_encode_null_source_throws_argument_null() {
    let mut dest = [0; 100];
    let result = Helpers::zero_encode(None, 10, Some(&mut dest));
    assert!(
        matches!(&result, Err(libremetaverse::Error::ArgumentNull)),
        "expected ArgumentNull, got {result:?}"
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroEncode_NullDestination_ThrowsArgumentNullException::test e3d89a513638c467355f320983dd6ce8c36ccbeeab7b7853fdc5d9101fd8767d translated
#[test]
fn zero_encode_null_destination_throws_argument_null() {
    let src = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0xff];
    let result = Helpers::zero_encode(Some(&src), src.len() as i32, None);
    assert!(
        matches!(&result, Err(libremetaverse::Error::ArgumentNull)),
        "expected ArgumentNull, got {result:?}"
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroEncode_DestinationTooSmall_ThrowsIndexOutOfRangeException::test 3870f0680f25e8df8de54f27c153feae9d8398e38531d67d6e0255cc34d50966 translated
#[test]
fn zero_encode_destination_too_small_throws_index_out_of_range() {
    let mut src = [0xff; 100];
    src[..6].copy_from_slice(&[0, 1, 2, 3, 4, 5]);
    let mut dest = [0; 10];
    let result = Helpers::zero_encode(Some(&src), src.len() as i32, Some(&mut dest));
    assert!(
        matches!(&result, Err(libremetaverse::Error::IndexOutOfRange)),
        "expected IndexOutOfRange, got {result:?}"
    );
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroEncode_WithAppendedAcks_HandlesCorrectly::test 9803ec7bad46a1fd0f32c58d3ee08cf6a98b03a40a336ae231d1faf8211b273a translated
#[test]
fn zero_encode_with_appended_acks_preserves_count() {
    let src = [
        0x10, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01,
    ];
    let mut dest = [0; 100];
    let len = Helpers::zero_encode(Some(&src), src.len() as i32, Some(&mut dest))
        .expect("Helpers ZeroEncode");
    assert!(len > 0);
    assert_eq!(dest[len as usize - 1], 1);
}

// parity-case: LibreMetaverse.Tests/HelpersZeroCodingTests.cs::HelpersZeroCodingTests.ZeroEncodeAndDecode_RoundTrip_PreservesData::test 7847520873f87d798ea94fd1b6543db9d3606829a4bc3f4ec873e629fb6687eb translated
#[test]
fn zero_encode_decode_round_trip_preserves_patterns() {
    for case in [
        &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0xff, 0x00, 0xaa][..],
        &[
            0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xaa,
        ],
        &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0xff, 0xaa, 0xbb],
        &[0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00, 0x00],
    ] {
        let mut encoded = [0; 500];
        let encoded_len = Helpers::zero_encode(Some(case), case.len() as i32, Some(&mut encoded))
            .expect("Helpers ZeroEncode");
        assert!(encoded_len > 0);
        let mut decoded = [0; 500];
        let decoded_len = Helpers::zero_decode(Some(&encoded), encoded_len, Some(&mut decoded))
            .expect("Helpers ZeroDecode");
        assert_eq!(decoded_len as usize, case.len());
        assert_eq!(&decoded[..case.len()], case);
    }
}

// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.BitUnpacking::test 741470d770a0a71853d84e26abaf927fc7dc385dedf0d7de87f63e7a22cb4dd7 translated
#[test]
fn bit_unpacking() {
    let data = vec![0x80, 0x00, 0x0f, 0x50, 0x83, 0x7d];
    let mut bits = BitPack::new(data, 0).expect("BitPack constructor");
    assert_eq!(bits.unpack_bits(1).expect("UnpackBits"), 1);
    assert_eq!(bits.unpack_bits(1).expect("UnpackBits"), 0);
    let mut bits = BitPack::new(bits.data, 2).expect("BitPack constructor at byte 2");
    assert_eq!(bits.unpack_bits(4).expect("UnpackBits"), 0);
    assert_eq!(bits.unpack_bits(8).expect("UnpackBits"), 0xf5);
    assert_eq!(bits.unpack_bits(4).expect("UnpackBits"), 0);
    assert_eq!(bits.unpack_bits(10).expect("UnpackBits"), 0x0183);
}

// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.BitPacking::test fe3cac4216b588667d56b35496a803097dbc39f84c7a82fd95aa101836588948 translated
#[test]
fn bit_packing() {
    let mut bits = BitPack::new(vec![0; 12], 0).expect("BitPack constructor");
    bits.pack_bits_with_int32_int32(0x0abb_ccdd, 32)
        .expect("PackBits 32");
    bits.pack_bits_with_int32_int32(25, 5).expect("PackBits 5");
    bits.pack_float(123.321).expect("PackFloat");
    bits.pack_bits_with_int32_int32(1000, 16)
        .expect("PackBits 16");
    let mut bits = BitPack::new(bits.data, 0).expect("BitPack constructor");
    assert_eq!(bits.unpack_bits(32).expect("UnpackBits"), 0x0abb_ccdd);
    assert_eq!(bits.unpack_bits(5).expect("UnpackBits"), 25);
    assert_eq!(bits.unpack_float().expect("UnpackFloat"), 123.321);
    assert_eq!(bits.unpack_bits(16).expect("UnpackBits"), 1000);

    let mut bits = BitPack::new(vec![0], 0).expect("BitPack constructor");
    bits.pack_bit(true).expect("PackBit true");
    let mut bits = BitPack::new(bits.data, 0).expect("BitPack constructor");
    assert_eq!(bits.unpack_bits(1).expect("UnpackBits"), 1);

    let mut bits = BitPack::new(vec![u8::MAX], 0).expect("BitPack constructor");
    bits.pack_bit(false).expect("PackBit false");
    let mut bits = BitPack::new(bits.data, 0).expect("BitPack constructor");
    assert_eq!(bits.unpack_bits(1).expect("UnpackBits"), 0);
}

// parity-case: LibreMetaverse.Tests/PacketTests.cs::PacketTests.HeaderFlags::test 89d9955f4a2ccb1fe1de227df0d9dc43a8836145a625b07c69e92e3acdef4c8b translated
#[test]
fn packet_header_flags() {
    let mut packet =
        TestMessagePacket::new_with_constructor().expect("TestMessagePacket constructor");
    for value in [false, false, true, true, false] {
        packet.base.header.appended_acks = value;
        packet.base.header.reliable = value;
        packet.base.header.resent = value;
        packet.base.header.zerocoded = value;
        assert_eq!(packet.base.header.appended_acks, value);
        assert_eq!(packet.base.header.reliable, value);
        assert_eq!(packet.base.header.resent, value);
        assert_eq!(packet.base.header.zerocoded, value);
    }
}

// parity-case: LibreMetaverse.Tests/PacketTests.cs::PacketTests.ToBytesMultiple::test 0e0f06d2317de91147bab1e623bed35ee03015da1498a9b9837c91c144bf7da5 translated
#[test]
fn packet_to_bytes_multiple() {
    let test_id = UUID::random().expect("UUID Random");
    let mut big =
        DirPlacesReplyPacket::new_with_constructor().expect("DirPlacesReplyPacket constructor");
    big.base.header.zerocoded = false;
    big.base.header.sequence = 42;
    big.base.header.appended_acks = true;
    big.base.header.ack_list = Some((0..50).collect());
    big.agent_data.agent_id = copy_uuid(&test_id);
    big.query_data = (0..100)
        .map(|_| {
            let mut block = DirPlacesReplyPacketQueryDataBlock::new_with_constructor()
                .expect("QueryDataBlock constructor");
            block.query_id = copy_uuid(&test_id);
            block
        })
        .collect();
    big.query_replies = (0..100)
        .map(|i| {
            let mut block = DirPlacesReplyPacketQueryRepliesBlock::new_with_constructor()
                .expect("QueryRepliesBlock constructor");
            block.auction = i & 1 == 0;
            block.dwell = i as f32;
            block.for_sale = i & 1 == 0;
            block.name = Utils::string_to_bytes("DirPlacesReply Test String".into())
                .expect("Utils StringToBytes");
            block.parcel_id = copy_uuid(&test_id);
            block
        })
        .collect();
    big.status_data = (0..100)
        .map(|i| {
            let mut block = DirPlacesReplyPacketStatusDataBlock::new_with_constructor()
                .expect("StatusDataBlock constructor");
            block.status = i;
            block
        })
        .collect();
    let split_packets = big
        .to_bytes_multiple_with_method()
        .expect("DirPlacesReplyPacket ToBytesMultiple");
    let mut query_data_count = 0;
    let mut query_replies_count = 0;
    let mut status_data_count = 0;
    for packet_data in split_packets {
        let mut end = packet_data.len() as i32 - 1;
        let built = Packet::build_packet_with_bytes_int32_bytes(
            packet_data.clone(),
            &mut end,
            packet_data.clone(),
        )
        .expect("Packet BuildPacket");
        assert_eq!(built.type_, PacketType::DirPlacesReply);
        end = packet_data.len() as i32 - 1;
        let packet = DirPlacesReplyPacket::new_with_bytes_int32(packet_data, &mut end)
            .expect("DirPlacesReplyPacket byte constructor");
        assert_eq!(
            packet
                .agent_data
                .agent_id
                .get_bytes()
                .expect("agent UUID bytes"),
            big.agent_data
                .agent_id
                .get_bytes()
                .expect("agent UUID bytes")
        );
        for (offset, reply) in packet.query_replies.iter().enumerate() {
            assert!((reply.dwell - (query_replies_count + offset) as f32).abs() <= 0.1);
            assert_eq!(
                reply.parcel_id.get_bytes().expect("parcel UUID bytes"),
                test_id.get_bytes().expect("test UUID bytes")
            );
        }
        query_data_count += packet.query_data.len();
        query_replies_count += packet.query_replies.len();
        status_data_count += packet.status_data.len();
    }
    assert_eq!(query_data_count, big.query_data.len());
    assert_eq!(query_replies_count, big.query_data.len());
    assert_eq!(status_data_count, big.status_data.len());

    let mut script =
        ScriptDialogPacket::new_with_constructor().expect("ScriptDialogPacket constructor");
    script.data.chat_channel = 0;
    script.data.first_name = Utils::empty_bytes();
    script.data.image_id = UUID::zero();
    script.data.last_name = Utils::empty_bytes();
    script.data.message = Utils::empty_bytes();
    script.data.object_id = UUID::zero();
    script.data.object_name = Utils::empty_bytes();
    script.buttons.clear();
    let mut owner = ScriptDialogPacketOwnerDataBlock::new_with_constructor()
        .expect("OwnerDataBlock constructor");
    owner.owner_id = UUID::zero();
    script.owner_data = vec![owner];
    let split = script
        .to_bytes_multiple_with_method()
        .expect("ScriptDialogPacket ToBytesMultiple");
    assert_eq!(split.len(), 1);

    let mut returns = ParcelReturnObjectsPacket::new_with_constructor()
        .expect("ParcelReturnObjectsPacket constructor");
    returns.agent_data.agent_id = UUID::zero();
    returns.agent_data.session_id = UUID::zero();
    returns.parcel_data.local_id = 0;
    returns.parcel_data.return_type = 0;
    returns.task_i_ds.clear();
    let mut owner = ParcelReturnObjectsPacketOwnerIDsBlock::new_with_constructor()
        .expect("OwnerIDsBlock constructor");
    owner.owner_id = UUID::zero();
    returns.owner_i_ds = vec![owner];
    let split = returns
        .to_bytes_multiple_with_method()
        .expect("ParcelReturnObjectsPacket ToBytesMultiple");
    assert_eq!(split.len(), 1);

    let mut inventory = InventoryDescendentsPacket::new_with_constructor()
        .expect("InventoryDescendentsPacket constructor");
    let mut folder = InventoryDescendentsPacketFolderDataBlock::new_with_constructor()
        .expect("FolderDataBlock constructor");
    folder.name = Utils::empty_bytes();
    inventory.folder_data = vec![folder];
    inventory.item_data = (0..5)
        .map(|_| {
            let mut item = InventoryDescendentsPacketItemDataBlock::new_with_constructor()
                .expect("ItemDataBlock constructor");
            item.description = Utils::string_to_bytes("Unit Test Item Description".into())
                .expect("Utils StringToBytes");
            item.name =
                Utils::string_to_bytes("Unit Test Item Name".into()).expect("Utils StringToBytes");
            item
        })
        .collect();
    let split = inventory
        .to_bytes_multiple_with_method()
        .expect("InventoryDescendentsPacket ToBytesMultiple");
    assert_eq!(split.len(), 1);
    let mut start = 0;
    let mut end = split[0].len() as i32 - 1;
    inventory
        .from_bytes_with_bytes_int32_int32_bytes(split[0].clone(), &mut start, &mut end, None)
        .expect("InventoryDescendentsPacket FromBytes");
    assert_eq!(inventory.folder_data.len(), 1);
    assert_eq!(inventory.item_data.len(), 5);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.AgentGroupDataUpdateMessage::test 68645e0465ee9d08302326ce69e7f2137e34b62ee324230d4856efe18cb6cfa0 translated
#[test]
fn agent_group_data_update_message() {
    let mut source = AgentGroupDataUpdateMessage::new().expect("message constructor");
    source.agent_id = random_uuid();
    let mut first = AgentGroupDataUpdateMessageGroupData::new().expect("GroupData constructor");
    first.accept_notices = false;
    first.contribution = 1024;
    first.group_id = random_uuid();
    first.group_insignia_id = random_uuid();
    first.group_name = "Group Name Test 1".into();
    first.group_powers = GroupPowers(
        GroupPowers::ACCOUNTABLE.0 | GroupPowers::ALLOW_LANDMARK.0 | GroupPowers::ALLOW_SET_HOME.0,
    );
    let mut second = AgentGroupDataUpdateMessageGroupData::new().expect("GroupData constructor");
    second.accept_notices = false;
    second.contribution = 16;
    second.group_id = random_uuid();
    second.group_insignia_id = random_uuid();
    second.group_name = "Group Name Test 2".into();
    second.group_powers = GroupPowers(GroupPowers::CHANGE_ACTIONS.0 | GroupPowers::DEED_OBJECT.0);
    source.group_data_block = vec![first, second];
    let mut first =
        AgentGroupDataUpdateMessageNewGroupData::new().expect("NewGroupData constructor");
    first.list_in_profile = false;
    let mut second =
        AgentGroupDataUpdateMessageNewGroupData::new().expect("NewGroupData constructor");
    second.list_in_profile = true;
    source.new_group_data_block = vec![first, second];

    let map = source.serialize().expect("Serialize");
    let mut target = AgentGroupDataUpdateMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.agent_id, &source.agent_id);
    assert_eq!(target.group_data_block.len(), source.group_data_block.len());
    for (actual, expected) in target.group_data_block.iter().zip(&source.group_data_block) {
        assert_eq!(actual.accept_notices, expected.accept_notices);
        assert_eq!(actual.contribution, expected.contribution);
        assert_uuid_eq(&actual.group_id, &expected.group_id);
        assert_uuid_eq(&actual.group_insignia_id, &expected.group_insignia_id);
        assert_eq!(actual.group_name, expected.group_name);
        assert_eq!(actual.group_powers, expected.group_powers);
    }
    assert_eq!(
        target.new_group_data_block.len(),
        source.new_group_data_block.len()
    );
    for (actual, expected) in target
        .new_group_data_block
        .iter()
        .zip(&source.new_group_data_block)
    {
        assert_eq!(actual.list_in_profile, expected.list_in_profile);
    }
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.TeleportFinishMessage::test 082dbb6d8bcaebbeb26d7670730616860815fdfaa3c12d76324bbde982640343 translated
#[test]
fn teleport_finish_message() {
    let mut source = TeleportFinishMessage::new().expect("message constructor");
    source.agent_id = random_uuid();
    source.flags = TeleportFlags(TeleportFlags::VIA_LOCATION.0 | TeleportFlags::IS_FLYING.0);
    source.ip = test_ip();
    source.location_id = 32_767;
    source.port = 3000;
    source.region_handle = 1_106_108_697_797_888;
    source.seed_capability = test_uri();
    source.sim_access = SimAccess::MATURE;
    let map = source.serialize().expect("Serialize");
    let mut target = TeleportFinishMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.agent_id, &source.agent_id);
    assert_eq!(target.flags, source.flags);
    assert_eq!(target.ip, source.ip);
    assert_eq!(target.location_id, source.location_id);
    assert_eq!(target.port, source.port);
    assert_eq!(target.region_handle, source.region_handle);
    assert_eq!(target.seed_capability, source.seed_capability);
    assert_eq!(target.sim_access, source.sim_access);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.EstablishAgentCommunicationMessage::test cc808248d9f14d133d33fa071520d0f8a066a7d41bbf7651e3ee4c1d2ff03e3c translated
#[test]
fn establish_agent_communication_message() {
    let mut source = EstablishAgentCommunicationMessage::new().expect("message constructor");
    source.address = test_ip();
    source.agent_id = random_uuid();
    source.port = 3000;
    source.seed_capability = test_uri();
    let map = source.serialize().expect("Serialize");
    let mut target = EstablishAgentCommunicationMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.address, source.address);
    assert_uuid_eq(&target.agent_id, &source.agent_id);
    assert_eq!(target.port, source.port);
    assert_eq!(target.seed_capability, source.seed_capability);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ParcelObjectOwnersMessage::test 285a34b6c35b02d2666b6030973a0683d4e922fd09764db7eef8a0da12a0d10f translated
#[test]
fn parcel_object_owners_message() {
    let mut source = ParcelObjectOwnersReplyMessage::new().expect("message constructor");
    let mut first = ParcelObjectOwnersReplyMessagePrimOwner::new().expect("PrimOwner constructor");
    first.owner_id = random_uuid();
    first.count = 10;
    first.is_group_owned = true;
    first.online_status = false;
    first.time_stamp = utc(1_271_143_183);
    let mut second = ParcelObjectOwnersReplyMessagePrimOwner::new().expect("PrimOwner constructor");
    second.owner_id = random_uuid();
    second.count = 0;
    second.is_group_owned = false;
    second.online_status = false;
    second.time_stamp = utc(665_291_611);
    source.prim_owners_block = vec![first, second];
    let map = source.serialize().expect("Serialize");
    let mut target = ParcelObjectOwnersReplyMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(
        target.prim_owners_block.len(),
        source.prim_owners_block.len()
    );
    for (actual, expected) in target
        .prim_owners_block
        .iter()
        .zip(&source.prim_owners_block)
    {
        assert_eq!(actual.count, expected.count);
        assert_eq!(actual.is_group_owned, expected.is_group_owned);
        assert_eq!(actual.online_status, expected.online_status);
        assert_uuid_eq(&actual.owner_id, &expected.owner_id);
        assert_eq!(actual.time_stamp, expected.time_stamp);
    }
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ChatterBoxInvitationMessage::test 3b985fdd0228dc25ff3a6fb297d769b4cfe66ad8a8f8d730e35fef3ea89f907c translated
#[test]
fn chatter_box_invitation_message() {
    let mut source = ChatterBoxInvitationMessage::new().expect("message constructor");
    source.binary_bucket = Utils::empty_bytes();
    source.dialog = InstantMessageDialog::InventoryOffered;
    source.from_agent_id = random_uuid();
    source.from_agent_name = "Prokofy Neva".into();
    source.group_im = false;
    source.im_session_id = UUID::bitxor(copy_uuid(&source.from_agent_id), random_uuid());
    source.message = "Test Test Test".into();
    source.offline = InstantMessageOnline::Online;
    source.parent_estate_id = 1;
    source.position = Vector3::one();
    source.region_id = random_uuid();
    source.timestamp = SystemTime::now();
    source.to_agent_id = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = ChatterBoxInvitationMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.binary_bucket, source.binary_bucket);
    assert_eq!(target.dialog, source.dialog);
    assert_uuid_eq(&target.from_agent_id, &source.from_agent_id);
    assert_eq!(target.from_agent_name, source.from_agent_name);
    assert_eq!(target.group_im, source.group_im);
    assert_uuid_eq(&target.im_session_id, &source.im_session_id);
    assert_eq!(target.message, source.message);
    assert_eq!(target.offline, source.offline);
    assert_eq!(target.parent_estate_id, source.parent_estate_id);
    assert_vector_eq(&target.position, &source.position);
    assert_uuid_eq(&target.region_id, &source.region_id);
    assert_eq!(target.timestamp, source.timestamp);
    assert_uuid_eq(&target.to_agent_id, &source.to_agent_id);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ChatterboxSessionEventReplyMessage::test 7b2430bc8ed123a2f8bd494a1b8e2bd83497f30088aa7ba2b0e1996507a201b6 translated
#[test]
fn chatterbox_session_event_reply_message() {
    let mut source = ChatterboxSessionEventReplyMessage::new().expect("message constructor");
    source.session_id = random_uuid();
    source.success = true;
    let map = source.serialize().expect("Serialize");
    let mut target = ChatterboxSessionEventReplyMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.session_id, &source.session_id);
    assert_eq!(target.success, source.success);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ChatterBoxSessionStartReplyMessage::test d6152d668fa610fd43dc694851b760e334077119090c60e7278bd1e27515ca3a translated
#[test]
fn chatter_box_session_start_reply_message() {
    let mut source = ChatterBoxSessionStartReplyMessage::new().expect("message constructor");
    source.moderated_voice = true;
    source.session_id = random_uuid();
    source.session_name = "Test Session".into();
    source.success = true;
    source.temp_session_id = random_uuid();
    source.type_ = 1;
    source.voice_enabled = true;
    let map = source.serialize().expect("Serialize");
    let mut target = ChatterBoxSessionStartReplyMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.moderated_voice, source.moderated_voice);
    assert_uuid_eq(&target.session_id, &source.session_id);
    assert_eq!(target.session_name, source.session_name);
    assert_eq!(target.success, source.success);
    assert_uuid_eq(&target.temp_session_id, &source.temp_session_id);
    assert_eq!(target.type_, source.type_);
    assert_eq!(target.voice_enabled, source.voice_enabled);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ChatterBoxSessionAgentListUpdatesMessage::test 4f8fa0cbdfb12d38e9105036b779fc629663171a2c45bb1e9ea6d83fa80bc28c translated
#[test]
fn chatter_box_session_agent_list_updates_message() {
    let mut source = ChatterBoxSessionAgentListUpdatesMessage::new().expect("message constructor");
    source.session_id = random_uuid();
    let mut first = ChatterBoxSessionAgentListUpdatesMessageAgentUpdatesBlock::new()
        .expect("AgentUpdatesBlock constructor");
    first.agent_id = random_uuid();
    first.can_voice_chat = true;
    first.is_moderator = true;
    first.mute_text = true;
    first.mute_voice = true;
    first.transition = "ENTER".into();
    let mut second = ChatterBoxSessionAgentListUpdatesMessageAgentUpdatesBlock::new()
        .expect("AgentUpdatesBlock constructor");
    second.agent_id = random_uuid();
    second.can_voice_chat = true;
    second.is_moderator = true;
    second.mute_text = true;
    second.mute_voice = true;
    second.transition = "LEAVE".into();
    std::hint::black_box(second);
    source.updates = vec![first];
    let map = source.serialize().expect("Serialize");
    let mut target = ChatterBoxSessionAgentListUpdatesMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.session_id, &source.session_id);
    assert_eq!(target.updates.len(), source.updates.len());
    for (actual, expected) in target.updates.iter().zip(&source.updates) {
        assert_uuid_eq(&actual.agent_id, &expected.agent_id);
        assert_eq!(actual.can_voice_chat, expected.can_voice_chat);
        assert_eq!(actual.is_moderator, expected.is_moderator);
        assert_eq!(actual.mute_text, expected.mute_text);
        assert_eq!(actual.mute_voice, expected.mute_voice);
        assert_eq!(actual.transition, expected.transition);
    }
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ViewerStatsMessage::test 3c8a26da73e03101631292c7e22c5c0221e0bc65527081aace35a39640d25b3d translated
#[test]
fn viewer_stats_message() {
    let mut source = ViewerStatsMessage::new().expect("message constructor");
    source.agent_fps = 45.5;
    source.agents_in_view = 1;
    source.system_cpu = "Intel 80286".into();
    source.stats_dropped = 2;
    source.stats_failed_resends = 3;
    source.system_gpu = "Vesa VGA+".into();
    source.system_gpu_class = 4;
    source.system_gpu_vendor = "China".into();
    source.system_gpu_version = String::new();
    source.in_compressed_packets = 5000;
    source.in_kbytes = 6000.0;
    source.in_packets = 22_000.0;
    source.in_savings = 19.0;
    source.misc_int1 = 5;
    source.misc_int2 = 6;
    source.failures_invalid = 20;
    source.agent_language = "en".into();
    source.agent_memory_used = 12_878_728.0;
    source.meters_traveled = 9_999_123.0;
    source.object_kbytes = 70_001.0;
    source.failures_off_circuit = 201;
    source.system_os = "Palm OS 3.1".into();
    source.out_compressed_packets = 8000;
    source.out_kbytes = 9_000_999.0;
    source.out_packets = 21_000_210.0;
    source.out_savings = 181.0;
    source.agent_ping = 135_579.0;
    source.system_installed_ram = 4_000_000;
    source.regions_visited = 4579;
    source.failures_resent = 9;
    source.agent_runtime = 360_023.0;
    source.failures_send_packet = 565;
    source.session_id = random_uuid();
    source.simulator_fps = 454.0;
    source.agent_start_time = utc(96_009_813);
    source.misc_string1 = "Unused String".into();
    source.texture_kbytes = 9_367_498_382.0;
    source.agent_version = "1".into();
    source.misc_version = 1.0;
    source.vertex_buffers_enabled = true;
    source.world_kbytes = 232_344_439.0;
    let map = source.serialize().expect("Serialize");
    let mut target = ViewerStatsMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.agent_fps, source.agent_fps);
    assert_eq!(target.agents_in_view, source.agents_in_view);
    assert_eq!(target.system_cpu, source.system_cpu);
    assert_eq!(target.stats_dropped, source.stats_dropped);
    assert_eq!(target.stats_failed_resends, source.stats_failed_resends);
    assert_eq!(target.system_gpu, source.system_gpu);
    assert_eq!(target.system_gpu_class, source.system_gpu_class);
    assert_eq!(target.system_gpu_vendor, source.system_gpu_vendor);
    assert_eq!(target.system_gpu_version, source.system_gpu_version);
    assert_eq!(target.in_compressed_packets, source.in_compressed_packets);
    assert_eq!(target.in_kbytes, source.in_kbytes);
    assert_eq!(target.in_packets, source.in_packets);
    assert_eq!(target.in_savings, source.in_savings);
    assert_eq!(target.misc_int1, source.misc_int1);
    assert_eq!(target.misc_int2, source.misc_int2);
    assert_eq!(target.failures_invalid, source.failures_invalid);
    assert_eq!(target.agent_language, source.agent_language);
    assert_eq!(target.agent_memory_used, source.agent_memory_used);
    assert_eq!(target.meters_traveled, source.meters_traveled);
    assert_eq!(target.object_kbytes, source.object_kbytes);
    assert_eq!(target.failures_off_circuit, source.failures_off_circuit);
    assert_eq!(target.system_os, source.system_os);
    assert_eq!(target.out_compressed_packets, source.out_compressed_packets);
    assert_eq!(target.out_kbytes, source.out_kbytes);
    assert_eq!(target.out_packets, source.out_packets);
    assert_eq!(target.out_savings, source.out_savings);
    assert_eq!(target.agent_ping, source.agent_ping);
    assert_eq!(target.system_installed_ram, source.system_installed_ram);
    assert_eq!(target.regions_visited, source.regions_visited);
    assert_eq!(target.failures_resent, source.failures_resent);
    assert_eq!(target.agent_runtime, source.agent_runtime);
    assert_eq!(target.failures_send_packet, source.failures_send_packet);
    assert_uuid_eq(&target.session_id, &source.session_id);
    assert_eq!(target.simulator_fps, source.simulator_fps);
    assert_eq!(target.agent_start_time, source.agent_start_time);
    assert_eq!(target.misc_string1, source.misc_string1);
    assert_eq!(target.texture_kbytes, source.texture_kbytes);
    assert_eq!(target.agent_version, source.agent_version);
    assert_eq!(target.misc_version, source.misc_version);
    assert_eq!(target.vertex_buffers_enabled, source.vertex_buffers_enabled);
    assert_eq!(target.world_kbytes, source.world_kbytes);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ParcelVoiceInfoRequestMessage::test fdc91911ac13945b2d3b99963239e6d918522e117f99afe52c22d18db4adebad translated
#[test]
fn parcel_voice_info_request_message() {
    let mut source = ParcelVoiceInfoRequestMessage::new().expect("message constructor");
    source.sip_channel_uri = test_uri();
    source.parcel_id = 1;
    source.region_name = "Hooper".into();
    let map = source.serialize().expect("Serialize");
    let mut target = ParcelVoiceInfoRequestMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.sip_channel_uri, source.sip_channel_uri);
    assert_eq!(target.parcel_id, source.parcel_id);
    assert_eq!(target.region_name, source.region_name);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ScriptRunningReplyMessage::test 43531393898e44360eb94c88e6b7b5a79c882c2dea51b725d698d540275f3a0a translated
#[test]
fn script_running_reply_message() {
    let mut source = ScriptRunningReplyMessage::new().expect("message constructor");
    source.item_id = random_uuid();
    source.mono = true;
    source.running = true;
    source.object_id = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = ScriptRunningReplyMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.item_id, &source.item_id);
    assert_eq!(target.mono, source.mono);
    assert_uuid_eq(&target.object_id, &source.object_id);
    assert_eq!(target.running, source.running);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.MapLayerMessage::test 852d713c330b697c71f139fbcd4b2eec9fef3ea12b8cd4a3903a094692e9f021 translated
#[test]
fn map_layer_message() {
    let mut source = MapLayerReplyVariant::new().expect("message constructor");
    source.base.flags = 1;
    let mut aliased = MapLayerReplyVariantLayerData::new().expect("LayerData constructor");
    aliased.image_id = random_uuid();
    aliased.bottom = 1;
    aliased.top = 2;
    aliased.left = 3;
    aliased.right = 4;
    aliased.image_id = random_uuid();
    aliased.bottom = 5;
    aliased.top = 6;
    aliased.left = 7;
    aliased.right = 9;
    let mut first = MapLayerReplyVariantLayerData::new().expect("LayerData constructor");
    first.image_id = copy_uuid(&aliased.image_id);
    first.bottom = aliased.bottom;
    first.top = aliased.top;
    first.left = aliased.left;
    first.right = aliased.right;
    source.layer_data_blocks = vec![first, aliased];
    let map = source.serialize().expect("Serialize");
    let mut target = MapLayerReplyVariant::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.base.flags, source.base.flags);
    assert_eq!(
        target.layer_data_blocks.len(),
        source.layer_data_blocks.len()
    );
    for (actual, expected) in target
        .layer_data_blocks
        .iter()
        .zip(&source.layer_data_blocks)
    {
        assert_uuid_eq(&actual.image_id, &expected.image_id);
        assert_eq!(actual.bottom, expected.bottom);
        assert_eq!(actual.top, expected.top);
        assert_eq!(actual.left, expected.left);
        assert_eq!(actual.right, expected.right);
    }
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ChatSessionRequestStartConference::test 62f582479f737ba7a87d86e572f30139b95c5ab62a01c762eb96c238cb4872eb translated
#[test]
fn chat_session_request_start_conference() {
    let mut source = ChatSessionRequestStartConference::new().expect("message constructor");
    source.session_id = random_uuid();
    source.agents_block = vec![UUID::zero(), UUID::zero()];
    source.agents_block[0] = random_uuid();
    source.agents_block[0] = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = ChatSessionRequestStartConference::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.session_id, &source.session_id);
    assert_eq!(target.base.method, source.base.method);
    assert_eq!(target.agents_block.len(), source.agents_block.len());
    for (actual, expected) in target.agents_block.iter().zip(&source.agents_block) {
        assert_uuid_eq(actual, expected);
    }
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ChatSessionRequestMuteUpdate::test 19bc37af232e38de5e157929c4c68b5b4229fea3323c485aa0eb84710cbb03a7 translated
#[test]
fn chat_session_request_mute_update() {
    let mut source = ChatSessionRequestMuteUpdate::new().expect("message constructor");
    source.agent_id = random_uuid();
    source.request_key = "text".into();
    source.request_value = true;
    source.session_id = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = ChatSessionRequestMuteUpdate::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.agent_id, &source.agent_id);
    assert_eq!(target.base.method, source.base.method);
    assert_eq!(target.request_key, source.request_key);
    assert_eq!(target.request_value, source.request_value);
    assert_uuid_eq(&target.session_id, &source.session_id);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ChatSessionAcceptInvitation::test 68f712a0dad713f6f88d02df6b574a082cfdbfed93827d3c1857a0f992987620 translated
#[test]
fn chat_session_accept_invitation() {
    let mut source = ChatSessionAcceptInvitation::new().expect("message constructor");
    source.session_id = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = ChatSessionAcceptInvitation::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.base.method, source.base.method);
    assert_uuid_eq(&target.session_id, &source.session_id);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.RequiredVoiceVersionMessage::test 175cf76f403efb867f668bf79f31e72f6134783ad41b240e3d488daf14e0f295 translated
#[test]
fn required_voice_version_message() {
    let mut source = RequiredVoiceVersionMessage::new().expect("message constructor");
    source.major_version = 1;
    source.minor_version = 0;
    source.region_name = "Hooper".into();
    let map = source.serialize().expect("Serialize");
    let mut target = RequiredVoiceVersionMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.major_version, source.major_version);
    assert_eq!(target.minor_version, source.minor_version);
    assert_eq!(target.region_name, source.region_name);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.CopyInventoryFromNotecardMessage::test 968ff6415b819d883d94bdf5a975bfb07072783e41f61c98b60b8faac8394e47 translated
#[test]
fn copy_inventory_from_notecard_message() {
    let mut source = CopyInventoryFromNotecardMessage::new().expect("message constructor");
    source.callback_id = 1;
    source.folder_id = random_uuid();
    source.item_id = random_uuid();
    source.notecard_id = random_uuid();
    source.object_id = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = CopyInventoryFromNotecardMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.callback_id, source.callback_id);
    assert_uuid_eq(&target.folder_id, &source.folder_id);
    assert_uuid_eq(&target.item_id, &source.item_id);
    assert_uuid_eq(&target.notecard_id, &source.notecard_id);
    assert_uuid_eq(&target.object_id, &source.object_id);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ProvisionVoiceAccountRequestMessage::test b9e2a46558f10444a5d5c41af4067e63062a713985d806a766ef8079489d94d6 translated
#[test]
fn provision_voice_account_request_message() {
    let mut source = ProvisionVoiceAccountRequestMessage::new().expect("message constructor");
    source.username = "username".into();
    source.password = "password".into();
    let map = source.serialize().expect("Serialize");
    let mut target = ProvisionVoiceAccountRequestMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.password, source.password);
    assert_eq!(target.username, source.username);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.UpdateAgentLanguageMessage::test 2817374708da4d435c58f50c81fc145105eb215064f28b8d99f9e0f5317ab4c2 translated
#[test]
fn update_agent_language_message() {
    let mut source = UpdateAgentLanguageMessage::new().expect("message constructor");
    source.language = "en".into();
    source.language_public = false;
    let map = source.serialize().expect("Serialize");
    let mut target = UpdateAgentLanguageMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.language, source.language);
    assert_eq!(target.language_public, source.language_public);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ParcelPropertiesMessage::test b822e427023f7186a00fded83bab15aa62f41904401afef56697c536ab2bab12 translated
#[test]
fn parcel_properties_message() {
    let mut source = ParcelPropertiesMessage::new().expect("message constructor");
    source.aabb_max = vector("<1,2,3>");
    source.aabb_min = vector("<2,3,1>");
    source.any_av_sounds = true;
    source.area = 1024;
    source.auction_id = u32::MAX;
    source.auth_buyer_id = random_uuid();
    source.bitmap = Utils::empty_bytes();
    source.category = ParcelCategory::Educational;
    source.claim_date = utc(1_230_174_922);
    source.claim_price = 1000;
    source.desc = "Test Description".into();
    source.group_av_sounds = true;
    source.group_id = random_uuid();
    source.group_prims = 50;
    source.is_group_owned = false;
    source.landing_type = LandingType::None;
    source.local_id = 1;
    source.max_prims = 234;
    source.media_auto_scale = false;
    source.media_desc = "Example Media Description".into();
    source.media_height = 480;
    source.media_id = random_uuid();
    source.media_loop = false;
    source.media_type = "text/html".into();
    source.media_url = "http://www.openmetaverse.co".into();
    source.media_width = 640;
    source.music_url = "http://scfire-ntc-aa04.stream.aol.com:80/stream/1075".into();
    source.name = "Test Name".into();
    source.obscure_media = false;
    source.obscure_music = false;
    source.other_clean_time = 5;
    source.other_count = 200;
    source.other_prims = 300;
    source.owner_id = random_uuid();
    source.owner_prims = 0;
    source.parcel_flags = ParcelFlags(
        ParcelFlags::ALLOW_DAMAGE.0
            | ParcelFlags::ALLOW_GROUP_SCRIPTS.0
            | ParcelFlags::ALLOW_VOICE_CHAT.0,
    );
    source.parcel_prim_bonus = 0.0;
    source.pass_hours = 1.5;
    source.pass_price = 10;
    source.public_count = 20;
    source.region_deny_age_unverified = false;
    source.region_deny_anonymous = false;
    source.region_push_override = true;
    source.rent_price = 0;
    source.request_result = ParcelResult::Single;
    source.sale_price = 9999;
    source.see_a_vs = true;
    source.selected_prims = 1;
    source.self_count = 2;
    source.sequence_id = -4000;
    source.sim_wide_max_prims = 937;
    source.sim_wide_total_prims = 117;
    source.snap_selection = false;
    source.snapshot_id = random_uuid();
    source.status = ParcelStatus::Leased;
    source.total_prims = 219;
    source.user_location = vector("<3,4,5>");
    source.user_look_at = vector("<5,4,3>");
    let map = source.serialize().expect("Serialize");
    let mut target = ParcelPropertiesMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_vector_eq(&target.aabb_max, &source.aabb_max);
    assert_vector_eq(&target.aabb_min, &source.aabb_min);
    assert_eq!(target.any_av_sounds, source.any_av_sounds);
    assert_eq!(target.area, source.area);
    assert_eq!(target.auction_id, source.auction_id);
    assert_uuid_eq(&target.auth_buyer_id, &source.auth_buyer_id);
    assert_eq!(target.bitmap, source.bitmap);
    assert_eq!(target.category, source.category);
    assert_eq!(target.claim_date, source.claim_date);
    assert_eq!(target.claim_price, source.claim_price);
    assert_eq!(target.desc, source.desc);
    assert_eq!(target.group_av_sounds, source.group_av_sounds);
    assert_uuid_eq(&target.group_id, &source.group_id);
    assert_eq!(target.group_prims, source.group_prims);
    assert_eq!(target.is_group_owned, source.is_group_owned);
    assert_eq!(target.landing_type, source.landing_type);
    assert_eq!(target.local_id, source.local_id);
    assert_eq!(target.max_prims, source.max_prims);
    assert_eq!(target.media_auto_scale, source.media_auto_scale);
    assert_eq!(target.media_desc, source.media_desc);
    assert_eq!(target.media_height, source.media_height);
    assert_uuid_eq(&target.media_id, &source.media_id);
    assert_eq!(target.media_loop, source.media_loop);
    assert_eq!(target.media_type, source.media_type);
    assert_eq!(target.media_url, source.media_url);
    assert_eq!(target.media_width, source.media_width);
    assert_eq!(target.music_url, source.music_url);
    assert_eq!(target.name, source.name);
    assert_eq!(target.obscure_media, source.obscure_media);
    assert_eq!(target.obscure_music, source.obscure_music);
    assert_eq!(target.other_clean_time, source.other_clean_time);
    assert_eq!(target.other_count, source.other_count);
    assert_eq!(target.other_prims, source.other_prims);
    assert_uuid_eq(&target.owner_id, &source.owner_id);
    assert_eq!(target.owner_prims, source.owner_prims);
    assert_eq!(target.parcel_flags, source.parcel_flags);
    assert_eq!(target.parcel_prim_bonus, source.parcel_prim_bonus);
    assert_eq!(target.pass_hours, source.pass_hours);
    assert_eq!(target.pass_price, source.pass_price);
    assert_eq!(target.public_count, source.public_count);
    assert_eq!(
        target.region_deny_age_unverified,
        source.region_deny_age_unverified
    );
    assert_eq!(target.region_deny_anonymous, source.region_deny_anonymous);
    assert_eq!(target.region_push_override, source.region_push_override);
    assert_eq!(target.rent_price, source.rent_price);
    assert_eq!(target.request_result, source.request_result);
    assert_eq!(target.sale_price, source.sale_price);
    assert_eq!(target.see_a_vs, source.see_a_vs);
    assert_eq!(target.selected_prims, source.selected_prims);
    assert_eq!(target.self_count, source.self_count);
    assert_eq!(target.sequence_id, source.sequence_id);
    assert_eq!(target.sim_wide_max_prims, source.sim_wide_max_prims);
    assert_eq!(target.sim_wide_total_prims, source.sim_wide_total_prims);
    assert_eq!(target.snap_selection, source.snap_selection);
    assert_uuid_eq(&target.snapshot_id, &source.snapshot_id);
    assert_eq!(target.status, source.status);
    assert_eq!(target.total_prims, source.total_prims);
    assert_vector_eq(&target.user_location, &source.user_location);
    assert_vector_eq(&target.user_look_at, &source.user_look_at);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ParcelPropertiesUpdateMessage::test c71c1a0676056e88dc5cb8beb6743c5d9f75edbba9d19662edd8eb2a0be367c1 translated
#[test]
fn parcel_properties_update_message() {
    let mut source = ParcelPropertiesUpdateMessage::new().expect("message constructor");
    source.any_av_sounds = true;
    source.auth_buyer_id = random_uuid();
    source.category = ParcelCategory::Gaming;
    source.desc = "Example Description".into();
    source.group_av_sounds = true;
    source.group_id = random_uuid();
    source.landing = LandingType::LandingPoint;
    source.local_id = 160;
    source.media_auto_scale = true;
    source.media_desc = "Example Media Description".into();
    source.media_height = 600;
    source.media_id = random_uuid();
    source.media_loop = false;
    source.media_type = "image/jpeg".into();
    source.media_url = "http://www.openmetaverse.co/test.jpeg".into();
    source.media_width = 800;
    source.music_url = "http://scfire-ntc-aa04.stream.aol.com:80/stream/1075".into();
    source.name = "Example Parcel Description".into();
    source.obscure_media = true;
    source.obscure_music = true;
    source.parcel_flags =
        ParcelFlags(ParcelFlags::ALLOW_VOICE_CHAT.0 | ParcelFlags::CONTRIBUTE_WITH_DEED.0);
    source.pass_hours = 5.5;
    source.pass_price = 100;
    source.sale_price = 99;
    source.see_a_vs = true;
    source.snapshot_id = random_uuid();
    source.user_location = vector("<128,128,128>");
    source.user_look_at = vector("<256,256,256>");
    let map = source.serialize().expect("Serialize");
    let mut target = ParcelPropertiesUpdateMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.any_av_sounds, source.any_av_sounds);
    assert_uuid_eq(&target.auth_buyer_id, &source.auth_buyer_id);
    assert_eq!(target.category, source.category);
    assert_eq!(target.desc, source.desc);
    assert_eq!(target.group_av_sounds, source.group_av_sounds);
    assert_uuid_eq(&target.group_id, &source.group_id);
    assert_eq!(target.landing, source.landing);
    assert_eq!(target.local_id, source.local_id);
    assert_eq!(target.media_auto_scale, source.media_auto_scale);
    assert_eq!(target.media_desc, source.media_desc);
    assert_eq!(target.media_height, source.media_height);
    assert_uuid_eq(&target.media_id, &source.media_id);
    assert_eq!(target.media_loop, source.media_loop);
    assert_eq!(target.media_type, source.media_type);
    assert_eq!(target.media_url, source.media_url);
    assert_eq!(target.media_width, source.media_width);
    assert_eq!(target.music_url, source.music_url);
    assert_eq!(target.name, source.name);
    assert_eq!(target.obscure_media, source.obscure_media);
    assert_eq!(target.obscure_music, source.obscure_music);
    assert_eq!(target.parcel_flags, source.parcel_flags);
    assert_eq!(target.pass_hours, source.pass_hours);
    assert_eq!(target.pass_price, source.pass_price);
    assert_eq!(target.sale_price, source.sale_price);
    assert_eq!(target.see_a_vs, source.see_a_vs);
    assert_uuid_eq(&target.snapshot_id, &source.snapshot_id);
    assert_vector_eq(&target.user_location, &source.user_location);
    assert_vector_eq(&target.user_look_at, &source.user_look_at);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.EnableSimulatorMessage::test f23b3967772332db28cac474c2205efa49897447a43149b283756792d93f54df translated
#[test]
fn enable_simulator_message() {
    let mut source = EnableSimulatorMessage::new().expect("message constructor");
    let mut first =
        EnableSimulatorMessageSimulatorInfoBlock::new().expect("SimulatorInfoBlock constructor");
    first.ip = test_ip();
    first.port = 3000;
    first.region_handle = 1_106_108_697_797_888;
    let mut second =
        EnableSimulatorMessageSimulatorInfoBlock::new().expect("SimulatorInfoBlock constructor");
    second.ip = test_ip();
    second.port = 3001;
    second.region_handle = 1_106_108_697_797_888;
    source.simulators = vec![first, second];
    let map = source.serialize().expect("Serialize");
    let mut target = EnableSimulatorMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.simulators.len(), source.simulators.len());
    for (actual, expected) in target.simulators.iter().zip(&source.simulators) {
        assert_eq!(actual.ip, expected.ip);
        assert_eq!(actual.port, expected.port);
        assert_eq!(actual.region_handle, expected.region_handle);
    }
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.RemoteParcelRequestReply::test eee2c0cfd5020252c63becb44f5727f113fab30d59f35d5ded742c4af10f593e translated
#[test]
fn remote_parcel_request_reply() {
    let mut source = RemoteParcelRequestReply::new().expect("message constructor");
    source.parcel_id = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = RemoteParcelRequestReply::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.parcel_id, &source.parcel_id);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.UpdateScriptTaskMessage::test b403ec6a01b9e8ff9219a51b4194d7890f83c7f1f58ca370bbbf25e0ca9d76c3 translated
#[test]
fn update_script_task_message() {
    let mut source = UpdateScriptTaskUpdateMessage::new().expect("message constructor");
    source.task_id = random_uuid();
    source.target = "mono".into();
    source.script_running = true;
    source.item_id = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = UpdateScriptTaskUpdateMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.item_id, &source.item_id);
    assert_eq!(target.script_running, source.script_running);
    assert_eq!(target.target, source.target);
    assert_uuid_eq(&target.task_id, &source.task_id);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.UpdateScriptAgentMessage::test 36daa2fbbc2b787430321c85dedf14ae7afb97ae8b1c242eef1405ac41b4ee4d translated
#[test]
fn update_script_agent_message() {
    let mut source = UpdateScriptAgentRequestMessage::new().expect("message constructor");
    source.item_id = random_uuid();
    source.target = "lsl2".into();
    let map = source.serialize().expect("Serialize");
    let mut target = UpdateScriptAgentRequestMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.item_id, &source.item_id);
    assert_eq!(target.target, source.target);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.SendPostcardMessage::test 52b00ea634c999a3e6a1d8b04e41a6607bb5f494107ce3a6bb471b28558c3941 translated
#[test]
fn send_postcard_message() {
    let mut source = SendPostcardMessage::new().expect("message constructor");
    source.from_name = "Jim Radford".into();
    source.global_position = Vector3::one();
    source.message = "Hello, How are you today?".into();
    source.subject = "Postcard from the edge".into();
    source.to_email = "test1@example.com".into();
    let map = source.serialize().expect("Serialize");
    assert!(!map.contains_key("from".into()).expect("OSDMap ContainsKey"));
    let mut target = SendPostcardMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.from_name, source.from_name);
    assert_vector_eq(&target.global_position, &source.global_position);
    assert_eq!(target.message, source.message);
    assert_eq!(target.subject, source.subject);
    assert_eq!(target.to_email, source.to_email);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.UpdateNotecardAgentInventoryMessage::test e1e6fde149db01f6f3b0abaf261af9bca4f5551cc138fa3e3b0dab94f3ae55b5 translated
#[test]
fn update_notecard_agent_inventory_message() {
    let mut source = UpdateAgentInventoryRequestMessage::new().expect("message constructor");
    source.item_id = random_uuid();
    let map = source.serialize().expect("Serialize");
    let mut target = UpdateAgentInventoryRequestMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.item_id, &source.item_id);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.LandStatReplyMessage::test 24617d463c922520e739af51a24d79cd6f46c9492f89edb103904710589b4ff2 translated
#[test]
fn land_stat_reply_message() {
    let mut source = LandStatReplyMessage::new().expect("message constructor");
    source.report_type = 22;
    source.request_flags = 44;
    source.total_object_count = 2;
    let mut first =
        LandStatReplyMessageReportDataBlock::new().expect("ReportDataBlock constructor");
    first.location = Vector3::one();
    first.mono_score = 99.0;
    first.owner_name = "Profoky Neva".into();
    first.score = 10.0;
    first.task_id = random_uuid();
    first.task_local_id = 987_341;
    first.task_name = "Verbal Flogging".into();
    first.time_stamp = utc(1_243_053_000);
    let mut second =
        LandStatReplyMessageReportDataBlock::new().expect("ReportDataBlock constructor");
    second.location = Vector3::one();
    second.mono_score = 1.0;
    second.owner_name = "Philip Linden".into();
    second.score = 5.0;
    second.task_id = random_uuid();
    second.task_local_id = 987_342;
    second.task_name = "Happy Ant".into();
    second.time_stamp = utc(1_208_834_995);
    source.report_data_blocks = vec![first, second];
    let map = source.serialize().expect("Serialize");
    let mut target = LandStatReplyMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.report_type, source.report_type);
    assert_eq!(target.request_flags, source.request_flags);
    assert_eq!(target.total_object_count, source.total_object_count);
    assert_eq!(
        target.report_data_blocks.len(),
        source.report_data_blocks.len()
    );
    for (actual, expected) in target
        .report_data_blocks
        .iter()
        .zip(&source.report_data_blocks)
    {
        assert_vector_eq(&actual.location, &expected.location);
        assert_eq!(actual.mono_score, expected.mono_score);
        assert_eq!(actual.owner_name, expected.owner_name);
        assert_eq!(actual.score, expected.score);
        assert_uuid_eq(&actual.task_id, &expected.task_id);
        assert_eq!(actual.task_local_id, expected.task_local_id);
        assert_eq!(actual.task_name, expected.task_name);
        assert_eq!(actual.time_stamp, expected.time_stamp);
    }
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.TelportFailedMessage::test 29b96f17d4fb9f5b8e0cad23456672f1c1ab0a5e46c5f355f94e3afad3903a2b translated
#[test]
fn teleport_failed_message() {
    let mut source = TeleportFailedMessage::new().expect("message constructor");
    source.agent_id = random_uuid();
    source.message_key = "Key".into();
    source.reason = "Unable To Teleport for some unspecified reason".into();
    source.extra_params = String::new();
    let map = source.serialize().expect("Serialize");
    let mut target = TeleportFailedMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.agent_id, &source.agent_id);
    assert_eq!(target.extra_params, source.extra_params);
    assert_eq!(target.message_key, source.message_key);
    assert_eq!(target.reason, source.reason);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.UpdateAgentInformationMessage::test 57278e94b189b9b71ffd878615f1f74315622334d913f019011f01cf56eb49c1 translated
#[test]
fn update_agent_information_message() {
    let mut source = UpdateAgentInformationMessage::new().expect("message constructor");
    source.max_access = "PG".into();
    let map = source.serialize().expect("Serialize");
    let mut target = UpdateAgentInformationMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_eq!(target.max_access, source.max_access);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.PlacesReplyMessage::test d87a9d42a6873a9ae86c1696c0d4f360aaad006085e0408dee32d295fa83341a translated
#[test]
fn places_reply_message() {
    let mut source = PlacesReplyMessage::new().expect("message constructor");
    source.transaction_id = random_uuid();
    source.agent_id = random_uuid();
    source.query_id = random_uuid();
    let mut first = PlacesReplyMessageQueryData::new().expect("QueryData constructor");
    first.actual_area = 1024;
    first.billable_area = 768;
    first.description = "Test Description Q1".into();
    first.dwell = 1435.4;
    first.flags = 1 << 6;
    first.global_x = 1.0;
    first.global_y = 2.0;
    first.global_z = 3.0;
    first.name = "Test Name Q1".into();
    first.owner_id = random_uuid();
    first.price = 1;
    first.product_sku = "021".into();
    first.sim_name = "Hooper".into();
    first.snap_shot_id = random_uuid();
    let mut second = PlacesReplyMessageQueryData::new().expect("QueryData constructor");
    second.actual_area = 512;
    second.billable_area = 384;
    second.description = "Test Description Q2".into();
    second.dwell = 1.0;
    second.flags = 1 << 4;
    second.global_x = 4.0;
    second.global_y = 5.0;
    second.global_z = 6.0;
    second.name = "Test Name Q2".into();
    second.owner_id = random_uuid();
    second.price = 2;
    second.product_sku = "022".into();
    second.sim_name = "Tethys".into();
    second.snap_shot_id = random_uuid();
    source.query_data_blocks = vec![first, second];
    let map = source.serialize().expect("Serialize");
    let mut target = PlacesReplyMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_uuid_eq(&target.agent_id, &source.agent_id);
    assert_uuid_eq(&target.transaction_id, &source.transaction_id);
    assert_uuid_eq(&target.query_id, &source.query_id);
    assert_eq!(
        target.query_data_blocks.len(),
        source.query_data_blocks.len()
    );
    for (actual, expected) in target
        .query_data_blocks
        .iter()
        .zip(&source.query_data_blocks)
    {
        assert_eq!(actual.actual_area, expected.actual_area);
        assert_eq!(actual.billable_area, expected.billable_area);
        assert_eq!(actual.description, expected.description);
        assert_eq!(actual.dwell, expected.dwell);
        assert_eq!(actual.flags, expected.flags);
        assert_eq!(actual.global_x, expected.global_x);
        assert_eq!(actual.global_y, expected.global_y);
        assert_eq!(actual.global_z, expected.global_z);
        assert_eq!(actual.name, expected.name);
        assert_uuid_eq(&actual.owner_id, &expected.owner_id);
        assert_eq!(actual.price, expected.price);
        assert_eq!(actual.product_sku, expected.product_sku);
        assert_eq!(actual.sim_name, expected.sim_name);
        assert_uuid_eq(&actual.snap_shot_id, &expected.snap_shot_id);
    }
}

fn make_dir_land_reply() -> DirLandReplyMessage {
    let mut source = DirLandReplyMessage::new().expect("message constructor");
    source.agent_id = random_uuid();
    source.query_id = random_uuid();
    let mut first = DirLandReplyMessageQueryReply::new().expect("QueryReply constructor");
    first.actual_area = 1024;
    first.auction = true;
    first.for_sale = true;
    first.name = "For Sale Parcel Q1".into();
    first.product_sku = "023".into();
    first.sale_price = 2193;
    first.parcel_id = random_uuid();
    let mut second = DirLandReplyMessageQueryReply::new().expect("QueryReply constructor");
    second.actual_area = 512;
    second.auction = true;
    second.for_sale = true;
    second.name = "For Sale Parcel Q2".into();
    second.product_sku = "023".into();
    second.sale_price = 22_193;
    second.parcel_id = random_uuid();
    source.query_replies = vec![first, second];
    source
}

fn assert_dir_land_reply(actual: &DirLandReplyMessage, expected: &DirLandReplyMessage) {
    assert_uuid_eq(&actual.agent_id, &expected.agent_id);
    assert_uuid_eq(&actual.query_id, &expected.query_id);
    assert_eq!(actual.query_replies.len(), expected.query_replies.len());
    for (actual, expected) in actual.query_replies.iter().zip(&expected.query_replies) {
        assert_eq!(actual.actual_area, expected.actual_area);
        assert_eq!(actual.auction, expected.auction);
        assert_eq!(actual.for_sale, expected.for_sale);
        assert_eq!(actual.name, expected.name);
        assert_eq!(actual.product_sku, expected.product_sku);
        assert_uuid_eq(&actual.parcel_id, &expected.parcel_id);
        assert_eq!(actual.sale_price, expected.sale_price);
    }
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.DirLandReplyMessage::test 72b8f97104cf8f39437aaf0b034bc7c2e8ef0e90b9cec33fe6aa70befdda95f4 translated
#[test]
fn dir_land_reply_message() {
    let source = make_dir_land_reply();
    let map = source.serialize().expect("Serialize");
    let mut target = DirLandReplyMessage::new().expect("message constructor");
    target.deserialize(map).expect("Deserialize");
    assert_dir_land_reply(&target, &source);
}

const TEST_ITER: usize = 100_000;

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ReflectionPerformanceRemoteParcelResponse::test 5608e1141913ca30dac74c5c22eb11ad6a5f7a6e07fb162734df5245639fec44 benchmark
#[test]
fn reflection_performance_remote_parcel_response() {
    let started = Instant::now();
    for _ in 0..TEST_ITER {
        let mut source = RemoteParcelRequestReply::new().expect("message constructor");
        source.parcel_id = random_uuid();
        let map = source.serialize().expect("Serialize");
        let mut target = RemoteParcelRequestReply::new().expect("message constructor");
        target.deserialize(map).expect("Deserialize");
        assert_uuid_eq(&target.parcel_id, &source.parcel_id);
    }
    println!(
        "RemoteParcelRequestReply: OMV Message System Serialization/Deserialization Passes: {TEST_ITER} Total time: {:?}",
        started.elapsed()
    );
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ReflectionPerformanceDirLandReply::test d4a40f5d6a5f3e66d69591429bea0cfc95d313afc9a7a9ee5e9289c69be069d6 benchmark
#[test]
fn reflection_performance_dir_land_reply() {
    let started = Instant::now();
    for _ in 0..TEST_ITER {
        let source = make_dir_land_reply();
        let map = source.serialize().expect("Serialize");
        let mut target = DirLandReplyMessage::new().expect("message constructor");
        target.deserialize(map).expect("Deserialize");
        assert_dir_land_reply(&target, &source);
    }
    println!(
        "DirLandReplyMessage: OMV Message System Serialization/Deserialization Passes: {TEST_ITER} Total time: {:?}",
        started.elapsed()
    );
}

fn xml_text(value: &str) -> String {
    value
        .replace('&', "&amp;")
        .replace('<', "&lt;")
        .replace('>', "&gt;")
        .replace('"', "&quot;")
        .replace('\'', "&apos;")
}

fn uuid_xml(value: &UUID) -> String {
    let mut xml = String::with_capacity(32);
    for byte in value.get_bytes().expect("UUID bytes") {
        write!(xml, "{byte:02x}").expect("write UUID XML");
    }
    xml
}

fn serialize_dir_land_reply_xml(source: &DirLandReplyMessage) -> String {
    let mut xml = format!(
        "<DirLandReplyMessage><AgentID>{}</AgentID><QueryID>{}</QueryID><QueryReplies>",
        uuid_xml(&source.agent_id),
        uuid_xml(&source.query_id)
    );
    for reply in &source.query_replies {
        write!(
            xml,
            "<QueryReply><ActualArea>{}</ActualArea><Auction>{}</Auction><ForSale>{}</ForSale><Name>{}</Name><ProductSku>{}</ProductSku><SalePrice>{}</SalePrice><ParcelID>{}</ParcelID></QueryReply>",
            reply.actual_area,
            reply.auction,
            reply.for_sale,
            xml_text(&reply.name),
            xml_text(&reply.product_sku),
            reply.sale_price,
            uuid_xml(&reply.parcel_id),
        )
        .expect("write XML");
    }
    xml.push_str("</QueryReplies></DirLandReplyMessage>");
    xml
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ReflectionPerformanceDirLandReply2::test e52dacbdf3f4540553fe9f751334631a2d8440bdffcf6822d2629585176626cc benchmark
#[test]
fn reflection_performance_dir_land_reply_two() {
    let source = make_dir_land_reply();
    let started = Instant::now();
    for _ in 0..TEST_ITER {
        let map = source.serialize().expect("Serialize");
        let json = OSDParser::serialize_json_string(map.copy().expect("OSDMap Copy"), None)
            .expect("OSDParser SerializeJsonString");
        let mut stream = Vec::new();
        stream.extend_from_slice(json.as_bytes());
        std::hint::black_box(stream);
    }
    println!(
        "OMV Message System Serialization/Deserialization Passes: {TEST_ITER} Total time: {}",
        started.elapsed().as_secs_f64()
    );

    let started = Instant::now();
    for _ in 0..TEST_ITER {
        let xml = serialize_dir_land_reply_xml(&source);
        let mut stream = Vec::new();
        stream.extend_from_slice(xml.as_bytes());
        std::hint::black_box(stream);
    }
    println!(
        "Rust XML baseline passes: {TEST_ITER} Total time: {}",
        started.elapsed().as_secs_f64()
    );
}

fn make_parcel_properties_benchmark() -> ParcelPropertiesMessage {
    let mut source = ParcelPropertiesMessage::new().expect("message constructor");
    source.aabb_max = vector("<1,2,3>");
    source.aabb_min = vector("<2,3,1>");
    source.area = 1024;
    source.auction_id = u32::MAX;
    source.auth_buyer_id = random_uuid();
    source.bitmap = Utils::empty_bytes();
    source.category = ParcelCategory::Educational;
    source.claim_date = utc(1_230_174_922);
    source.claim_price = 1000;
    source.desc = "Test Description".into();
    source.group_id = random_uuid();
    source.group_prims = 50;
    source.is_group_owned = false;
    source.landing_type = LandingType::None;
    source.local_id = 1;
    source.max_prims = 234;
    source.media_auto_scale = false;
    source.media_desc = "Example Media Description".into();
    source.media_height = 480;
    source.media_id = random_uuid();
    source.media_loop = false;
    source.media_type = "text/html".into();
    source.media_url = "http://www.openmetaverse.co".into();
    source.media_width = 640;
    source.music_url = "http://scfire-ntc-aa04.stream.aol.com:80/stream/1075".into();
    source.name = "Test Name".into();
    source.obscure_media = false;
    source.obscure_music = false;
    source.other_clean_time = 5;
    source.other_count = 200;
    source.other_prims = 300;
    source.owner_id = random_uuid();
    source.owner_prims = 0;
    source.parcel_flags = ParcelFlags(
        ParcelFlags::ALLOW_DAMAGE.0
            | ParcelFlags::ALLOW_GROUP_SCRIPTS.0
            | ParcelFlags::ALLOW_VOICE_CHAT.0,
    );
    source.parcel_prim_bonus = 0.0;
    source.pass_hours = 1.5;
    source.pass_price = 10;
    source.public_count = 20;
    source.region_deny_age_unverified = false;
    source.region_deny_anonymous = false;
    source.region_push_override = true;
    source.rent_price = 0;
    source.request_result = ParcelResult::Single;
    source.sale_price = 9999;
    source.selected_prims = 1;
    source.self_count = 2;
    source.sequence_id = -4000;
    source.sim_wide_max_prims = 937;
    source.sim_wide_total_prims = 117;
    source.snap_selection = false;
    source.snapshot_id = random_uuid();
    source.status = ParcelStatus::Leased;
    source.total_prims = 219;
    source.user_location = vector("<3,4,5>");
    source.user_look_at = vector("<5,4,3>");
    source
}

fn assert_parcel_properties_benchmark(
    actual: &ParcelPropertiesMessage,
    expected: &ParcelPropertiesMessage,
) {
    assert_vector_eq(&actual.aabb_max, &expected.aabb_max);
    assert_vector_eq(&actual.aabb_min, &expected.aabb_min);
    assert_eq!(actual.area, expected.area);
    assert_eq!(actual.auction_id, expected.auction_id);
    assert_uuid_eq(&actual.auth_buyer_id, &expected.auth_buyer_id);
    assert_eq!(actual.bitmap, expected.bitmap);
    assert_eq!(actual.category, expected.category);
    assert_eq!(actual.claim_date, expected.claim_date);
    assert_eq!(actual.claim_price, expected.claim_price);
    assert_eq!(actual.desc, expected.desc);
    assert_uuid_eq(&actual.group_id, &expected.group_id);
    assert_eq!(actual.group_prims, expected.group_prims);
    assert_eq!(actual.is_group_owned, expected.is_group_owned);
    assert_eq!(actual.landing_type, expected.landing_type);
    assert_eq!(actual.local_id, expected.local_id);
    assert_eq!(actual.max_prims, expected.max_prims);
    assert_eq!(actual.media_auto_scale, expected.media_auto_scale);
    assert_eq!(actual.media_desc, expected.media_desc);
    assert_eq!(actual.media_height, expected.media_height);
    assert_uuid_eq(&actual.media_id, &expected.media_id);
    assert_eq!(actual.media_loop, expected.media_loop);
    assert_eq!(actual.media_type, expected.media_type);
    assert_eq!(actual.media_url, expected.media_url);
    assert_eq!(actual.media_width, expected.media_width);
    assert_eq!(actual.music_url, expected.music_url);
    assert_eq!(actual.name, expected.name);
    assert_eq!(actual.obscure_media, expected.obscure_media);
    assert_eq!(actual.obscure_music, expected.obscure_music);
    assert_eq!(actual.other_clean_time, expected.other_clean_time);
    assert_eq!(actual.other_count, expected.other_count);
    assert_eq!(actual.other_prims, expected.other_prims);
    assert_uuid_eq(&actual.owner_id, &expected.owner_id);
    assert_eq!(actual.owner_prims, expected.owner_prims);
    assert_eq!(actual.parcel_flags, expected.parcel_flags);
    assert_eq!(actual.parcel_prim_bonus, expected.parcel_prim_bonus);
    assert_eq!(actual.pass_hours, expected.pass_hours);
    assert_eq!(actual.pass_price, expected.pass_price);
    assert_eq!(actual.public_count, expected.public_count);
    assert_eq!(
        actual.region_deny_age_unverified,
        expected.region_deny_age_unverified
    );
    assert_eq!(actual.region_deny_anonymous, expected.region_deny_anonymous);
    assert_eq!(actual.region_push_override, expected.region_push_override);
    assert_eq!(actual.rent_price, expected.rent_price);
    assert_eq!(actual.request_result, expected.request_result);
    assert_eq!(actual.sale_price, expected.sale_price);
    assert_eq!(actual.selected_prims, expected.selected_prims);
    assert_eq!(actual.self_count, expected.self_count);
    assert_eq!(actual.sequence_id, expected.sequence_id);
    assert_eq!(actual.sim_wide_max_prims, expected.sim_wide_max_prims);
    assert_eq!(actual.sim_wide_total_prims, expected.sim_wide_total_prims);
    assert_eq!(actual.snap_selection, expected.snap_selection);
    assert_uuid_eq(&actual.snapshot_id, &expected.snapshot_id);
    assert_eq!(actual.status, expected.status);
    assert_eq!(actual.total_prims, expected.total_prims);
    assert_vector_eq(&actual.user_location, &expected.user_location);
    assert_vector_eq(&actual.user_look_at, &expected.user_look_at);
}

// parity-case: LibreMetaverse.Tests/MessageTests.cs::MessageTests.ReflectionPerformanceParcelProperties::test 914e6015a8abc1b5c1b58a219ef4f67258f793cac02c903e518758deaaddf8a4 benchmark
#[test]
fn reflection_performance_parcel_properties() {
    let started = Instant::now();
    for _ in 0..TEST_ITER {
        let source = make_parcel_properties_benchmark();
        let map = source.serialize().expect("Serialize");
        let mut target = ParcelPropertiesMessage::new().expect("message constructor");
        target.deserialize(map).expect("Deserialize");
        assert_parcel_properties_benchmark(&target, &source);
    }
    println!(
        "ParcelPropertiesMessage: OMV Message System Serialization/Deserialization Passes: {TEST_ITER} Total time: {:?}",
        started.elapsed()
    );
}
