@Override
  protected <T> void roundTrip(T message, Schema<T> schema, Pipe.Schema<T> pipeSchema)
      throws Exception {
    byte[] protobuf = ProtobufIOUtil.toByteArray(message, schema, buf());

    ByteArrayInputStream protobufStream = new ByteArrayInputStream(protobuf);

    byte[] protostuff =
        ProtostuffIOUtil.toByteArray(
            ProtobufIOUtil.newPipe(protobuf, 0, protobuf.length), pipeSchema, buf());

    byte[] protostuffFromStream =
        ProtostuffIOUtil.toByteArray(ProtobufIOUtil.newPipe(protobufStream), pipeSchema, buf());

    assertTrue(Arrays.equals(protostuff, protostuffFromStream));

    T parsedMessage = schema.newMessage();
    ProtostuffIOUtil.mergeFrom(protostuff, parsedMessage, schema);
    SerializableObjects.assertEquals(message, parsedMessage);

    ByteArrayInputStream protostuffStream = new ByteArrayInputStream(protostuff);

    byte[] protobufRoundTrip =
        ProtobufIOUtil.toByteArray(
            ProtostuffIOUtil.newPipe(protostuff, 0, protostuff.length), pipeSchema, buf());

    byte[] protobufRoundTripFromStream =
        ProtobufIOUtil.toByteArray(ProtostuffIOUtil.newPipe(protostuffStream), pipeSchema, buf());

    assertTrue(Arrays.equals(protobufRoundTrip, protobufRoundTripFromStream));

    assertTrue(Arrays.equals(protobufRoundTrip, protobuf));
  }
  static void deser(PrintStream out, Deserializer deserializer, String name, int warmups, int loops)
      throws Exception {
    final byte[] data = deserializer.getSerializer().serialize(foo);
    int len = data.length;
    Foo f = new Foo();
    deserializer.mergeFrom(data, f);
    SerializableObjects.assertEquals(foo, f);

    for (int i = 0; i < warmups; i++) deserializer.mergeFrom(data, new Foo());

    long start = System.currentTimeMillis();

    for (int i = 0; i < loops; i++) deserializer.mergeFrom(data, new Foo());

    long finish = System.currentTimeMillis();
    long elapsed = finish - start;
    out.println(elapsed + " ms elapsed with " + len + " bytes for " + name);
  }