public void udtSerDeserTest(int version) throws Exception {
    ListType<?> lt = ListType.getInstance(Int32Type.instance, true);
    SetType<?> st = SetType.getInstance(UTF8Type.instance, true);
    MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance, true);

    UserType udt =
        new UserType(
            "ks",
            bb("myType"),
            Arrays.asList(bb("f1"), bb("f2"), bb("f3"), bb("f4")),
            Arrays.asList(LongType.instance, lt, st, mt));

    Map<ColumnIdentifier, Term.Raw> value = new HashMap<>();
    value.put(ci("f1"), lit(42));
    value.put(ci("f2"), new Lists.Literal(Arrays.<Term.Raw>asList(lit(3), lit(1))));
    value.put(ci("f3"), new Sets.Literal(Arrays.<Term.Raw>asList(lit("foo"), lit("bar"))));
    value.put(
        ci("f4"),
        new Maps.Literal(
            Arrays.<Pair<Term.Raw, Term.Raw>>asList(
                Pair.<Term.Raw, Term.Raw>create(lit("foo"), lit(24)),
                Pair.<Term.Raw, Term.Raw>create(lit("bar"), lit(12)))));

    UserTypes.Literal u = new UserTypes.Literal(value);
    Term t = u.prepare("ks", columnSpec("myValue", udt));

    QueryOptions options = QueryOptions.DEFAULT;
    if (version == 2)
      options =
          QueryOptions.fromProtocolV2(ConsistencyLevel.ONE, Collections.<ByteBuffer>emptyList());
    else if (version != 3) throw new AssertionError("Invalid protocol version for test");

    ByteBuffer serialized = t.bindAndGet(options);

    ByteBuffer[] fields = udt.split(serialized);

    assertEquals(4, fields.length);

    assertEquals(bytes(42L), fields[0]);

    // Note that no matter what the protocol version has been used in bindAndGet above, the
    // collections inside
    // a UDT should alway be serialized with version 3 of the protocol. Which is why we don't use
    // 'version'
    // on purpose below.

    assertEquals(
        Arrays.asList(3, 1), lt.getSerializer().deserializeForNativeProtocol(fields[1], 3));

    LinkedHashSet<String> s = new LinkedHashSet<>();
    s.addAll(Arrays.asList("bar", "foo"));
    assertEquals(s, st.getSerializer().deserializeForNativeProtocol(fields[2], 3));

    LinkedHashMap<String, Long> m = new LinkedHashMap<>();
    m.put("bar", 12L);
    m.put("foo", 24L);
    assertEquals(m, mt.getSerializer().deserializeForNativeProtocol(fields[3], 3));
  }
  public void collectionSerDeserTest(int version) throws Exception {
    // Lists
    ListType<?> lt = ListType.getInstance(Int32Type.instance, true);
    List<Integer> l = Arrays.asList(2, 6, 1, 9);

    List<ByteBuffer> lb = new ArrayList<>(l.size());
    for (Integer i : l) lb.add(Int32Type.instance.decompose(i));

    assertEquals(
        l,
        lt.getSerializer()
            .deserializeForNativeProtocol(
                CollectionSerializer.pack(lb, lb.size(), version), version));

    // Sets
    SetType<?> st = SetType.getInstance(UTF8Type.instance, true);
    Set<String> s = new LinkedHashSet<>();
    s.addAll(Arrays.asList("bar", "foo", "zee"));

    List<ByteBuffer> sb = new ArrayList<>(s.size());
    for (String t : s) sb.add(UTF8Type.instance.decompose(t));

    assertEquals(
        s,
        st.getSerializer()
            .deserializeForNativeProtocol(
                CollectionSerializer.pack(sb, sb.size(), version), version));

    // Maps
    MapType<?, ?> mt = MapType.getInstance(UTF8Type.instance, LongType.instance, true);
    Map<String, Long> m = new LinkedHashMap<>();
    m.put("bar", 12L);
    m.put("foo", 42L);
    m.put("zee", 14L);

    List<ByteBuffer> mb = new ArrayList<>(m.size() * 2);
    for (Map.Entry<String, Long> entry : m.entrySet()) {
      mb.add(UTF8Type.instance.decompose(entry.getKey()));
      mb.add(LongType.instance.decompose(entry.getValue()));
    }

    assertEquals(
        m,
        mt.getSerializer()
            .deserializeForNativeProtocol(
                CollectionSerializer.pack(mb, m.size(), version), version));
  }