diff --git a/lib/rs/src/protocol/binary.rs b/lib/rs/src/protocol/binary.rs
new file mode 100644
index 0000000..f3c9ea2
--- /dev/null
+++ b/lib/rs/src/protocol/binary.rs
@@ -0,0 +1,817 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use byteorder::{BigEndian, ByteOrder, ReadBytesExt, WriteBytesExt};
+use std::cell::RefCell;
+use std::convert::From;
+use std::io::{Read, Write};
+use std::rc::Rc;
+use try_from::TryFrom;
+
+use ::{ProtocolError, ProtocolErrorKind};
+use ::transport::TTransport;
+use super::{TFieldIdentifier, TInputProtocol, TInputProtocolFactory, TListIdentifier,
+            TMapIdentifier, TMessageIdentifier, TMessageType};
+use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
+
+const BINARY_PROTOCOL_VERSION_1: u32 = 0x80010000;
+
+/// Read messages encoded in the Thrift simple binary encoding.
+///
+/// There are two available modes: `strict` and `non-strict`, where the
+/// `non-strict` version does not check for the protocol version in the
+/// received message header.
+///
+/// # Examples
+///
+/// Create and use a `TBinaryInputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut i_prot = TBinaryInputProtocol::new(transport, true);
+///
+/// let recvd_bool = i_prot.read_bool().unwrap();
+/// let recvd_string = i_prot.read_string().unwrap();
+/// ```
+pub struct TBinaryInputProtocol {
+    strict: bool,
+    transport: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TBinaryInputProtocol {
+    /// Create a `TBinaryInputProtocol` that reads bytes from `transport`.
+    ///
+    /// Set `strict` to `true` if all incoming messages contain the protocol
+    /// version number in the protocol header.
+    pub fn new(transport: Rc<RefCell<Box<TTransport>>>, strict: bool) -> TBinaryInputProtocol {
+        TBinaryInputProtocol {
+            strict: strict,
+            transport: transport,
+        }
+    }
+}
+
+impl TInputProtocol for TBinaryInputProtocol {
+    #[cfg_attr(feature = "cargo-clippy", allow(collapsible_if))]
+    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+        let mut first_bytes = vec![0; 4];
+        self.transport.borrow_mut().read_exact(&mut first_bytes[..])?;
+
+        // the thrift version header is intentionally negative
+        // so the first check we'll do is see if the sign bit is set
+        // and if so - assume it's the protocol-version header
+        if first_bytes[0] >= 8 {
+            // apparently we got a protocol-version header - check
+            // it, and if it matches, read the rest of the fields
+            if first_bytes[0..2] != [0x80, 0x01] {
+                Err(::Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::BadVersion,
+                    message: format!("received bad version: {:?}", &first_bytes[0..2]),
+                }))
+            } else {
+                let message_type: TMessageType = TryFrom::try_from(first_bytes[3])?;
+                let name = self.read_string()?;
+                let sequence_number = self.read_i32()?;
+                Ok(TMessageIdentifier::new(name, message_type, sequence_number))
+            }
+        } else {
+            // apparently we didn't get a protocol-version header,
+            // which happens if the sender is not using the strict protocol
+            if self.strict {
+                // we're in strict mode however, and that always
+                // requires the protocol-version header to be written first
+                Err(::Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::BadVersion,
+                    message: format!("received bad version: {:?}", &first_bytes[0..2]),
+                }))
+            } else {
+                // in the non-strict version the first message field
+                // is the message name. strings (byte arrays) are length-prefixed,
+                // so we've just read the length in the first 4 bytes
+                let name_size = BigEndian::read_i32(&first_bytes) as usize;
+                let mut name_buf: Vec<u8> = Vec::with_capacity(name_size);
+                self.transport.borrow_mut().read_exact(&mut name_buf)?;
+                let name = String::from_utf8(name_buf)?;
+
+                // read the rest of the fields
+                let message_type: TMessageType = self.read_byte().and_then(TryFrom::try_from)?;
+                let sequence_number = self.read_i32()?;
+                Ok(TMessageIdentifier::new(name, message_type, sequence_number))
+            }
+        }
+    }
+
+    fn read_message_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+        Ok(None)
+    }
+
+    fn read_struct_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+        let field_type_byte = self.read_byte()?;
+        let field_type = field_type_from_u8(field_type_byte)?;
+        let id = match field_type {
+            TType::Stop => Ok(0),
+            _ => self.read_i16(),
+        }?;
+        Ok(TFieldIdentifier::new::<Option<String>, String, i16>(None, field_type, id))
+    }
+
+    fn read_field_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+        let num_bytes = self.transport.borrow_mut().read_i32::<BigEndian>()? as usize;
+        let mut buf = vec![0u8; num_bytes];
+        self.transport.borrow_mut().read_exact(&mut buf).map(|_| buf).map_err(From::from)
+    }
+
+    fn read_bool(&mut self) -> ::Result<bool> {
+        let b = self.read_i8()?;
+        match b {
+            0 => Ok(false),
+            _ => Ok(true),
+        }
+    }
+
+    fn read_i8(&mut self) -> ::Result<i8> {
+        self.transport.borrow_mut().read_i8().map_err(From::from)
+    }
+
+    fn read_i16(&mut self) -> ::Result<i16> {
+        self.transport.borrow_mut().read_i16::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_i32(&mut self) -> ::Result<i32> {
+        self.transport.borrow_mut().read_i32::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_i64(&mut self) -> ::Result<i64> {
+        self.transport.borrow_mut().read_i64::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_double(&mut self) -> ::Result<f64> {
+        self.transport.borrow_mut().read_f64::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_string(&mut self) -> ::Result<String> {
+        let bytes = self.read_bytes()?;
+        String::from_utf8(bytes).map_err(From::from)
+    }
+
+    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
+        let size = self.read_i32()?;
+        Ok(TListIdentifier::new(element_type, size))
+    }
+
+    fn read_list_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+        let element_type: TType = self.read_byte().and_then(field_type_from_u8)?;
+        let size = self.read_i32()?;
+        Ok(TSetIdentifier::new(element_type, size))
+    }
+
+    fn read_set_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+        let key_type: TType = self.read_byte().and_then(field_type_from_u8)?;
+        let value_type: TType = self.read_byte().and_then(field_type_from_u8)?;
+        let size = self.read_i32()?;
+        Ok(TMapIdentifier::new(key_type, value_type, size))
+    }
+
+    fn read_map_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    // utility
+    //
+
+    fn read_byte(&mut self) -> ::Result<u8> {
+        self.transport.borrow_mut().read_u8().map_err(From::from)
+    }
+}
+
+/// Factory for creating instances of `TBinaryInputProtocol`.
+#[derive(Default)]
+pub struct TBinaryInputProtocolFactory;
+
+impl TBinaryInputProtocolFactory {
+    /// Create a `TBinaryInputProtocolFactory`.
+    pub fn new() -> TBinaryInputProtocolFactory {
+        TBinaryInputProtocolFactory {}
+    }
+}
+
+impl TInputProtocolFactory for TBinaryInputProtocolFactory {
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TInputProtocol> {
+        Box::new(TBinaryInputProtocol::new(transport, true)) as Box<TInputProtocol>
+    }
+}
+
+/// Write messages using the Thrift simple binary encoding.
+///
+/// There are two available modes: `strict` and `non-strict`, where the
+/// `strict` version writes the protocol version number in the outgoing message
+/// header and the `non-strict` version does not.
+///
+/// # Examples
+///
+/// Create and use a `TBinaryOutputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryOutputProtocol, TOutputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut o_prot = TBinaryOutputProtocol::new(transport, true);
+///
+/// o_prot.write_bool(true).unwrap();
+/// o_prot.write_string("test_string").unwrap();
+/// ```
+pub struct TBinaryOutputProtocol {
+    strict: bool,
+    transport: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TBinaryOutputProtocol {
+    /// Create a `TBinaryOutputProtocol` that writes bytes to `transport`.
+    ///
+    /// Set `strict` to `true` if all outgoing messages should contain the
+    /// protocol version number in the protocol header.
+    pub fn new(transport: Rc<RefCell<Box<TTransport>>>, strict: bool) -> TBinaryOutputProtocol {
+        TBinaryOutputProtocol {
+            strict: strict,
+            transport: transport,
+        }
+    }
+
+    fn write_transport(&mut self, buf: &[u8]) -> ::Result<()> {
+        self.transport.borrow_mut().write(buf).map(|_| ()).map_err(From::from)
+    }
+}
+
+impl TOutputProtocol for TBinaryOutputProtocol {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+        if self.strict {
+            let message_type: u8 = identifier.message_type.into();
+            let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
+            self.transport.borrow_mut().write_u32::<BigEndian>(header)?;
+            self.write_string(&identifier.name)?;
+            self.write_i32(identifier.sequence_number)
+        } else {
+            self.write_string(&identifier.name)?;
+            self.write_byte(identifier.message_type.into())?;
+            self.write_i32(identifier.sequence_number)
+        }
+    }
+
+    fn write_message_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_struct_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+        if identifier.id.is_none() && identifier.field_type != TType::Stop {
+            return Err(::Error::Protocol(ProtocolError {
+                kind: ProtocolErrorKind::Unknown,
+                message: format!("cannot write identifier {:?} without sequence number",
+                                 &identifier),
+            }));
+        }
+
+        self.write_byte(field_type_to_u8(identifier.field_type))?;
+        if let Some(id) = identifier.id {
+            self.write_i16(id)
+        } else {
+            Ok(())
+        }
+    }
+
+    fn write_field_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_field_stop(&mut self) -> ::Result<()> {
+        self.write_byte(field_type_to_u8(TType::Stop))
+    }
+
+    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+        self.write_i32(b.len() as i32)?;
+        self.write_transport(b)
+    }
+
+    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+        if b {
+            self.write_i8(1)
+        } else {
+            self.write_i8(0)
+        }
+    }
+
+    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+        self.transport.borrow_mut().write_i8(i).map_err(From::from)
+    }
+
+    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+        self.transport.borrow_mut().write_i16::<BigEndian>(i).map_err(From::from)
+    }
+
+    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+        self.transport.borrow_mut().write_i32::<BigEndian>(i).map_err(From::from)
+    }
+
+    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+        self.transport.borrow_mut().write_i64::<BigEndian>(i).map_err(From::from)
+    }
+
+    fn write_double(&mut self, d: f64) -> ::Result<()> {
+        self.transport.borrow_mut().write_f64::<BigEndian>(d).map_err(From::from)
+    }
+
+    fn write_string(&mut self, s: &str) -> ::Result<()> {
+        self.write_bytes(s.as_bytes())
+    }
+
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+        self.write_byte(field_type_to_u8(identifier.element_type))?;
+        self.write_i32(identifier.size)
+    }
+
+    fn write_list_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+        self.write_byte(field_type_to_u8(identifier.element_type))?;
+        self.write_i32(identifier.size)
+    }
+
+    fn write_set_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+        let key_type = identifier.key_type
+            .expect("map identifier to write should contain key type");
+        self.write_byte(field_type_to_u8(key_type))?;
+        let val_type = identifier.value_type
+            .expect("map identifier to write should contain value type");
+        self.write_byte(field_type_to_u8(val_type))?;
+        self.write_i32(identifier.size)
+    }
+
+    fn write_map_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn flush(&mut self) -> ::Result<()> {
+        self.transport.borrow_mut().flush().map_err(From::from)
+    }
+
+    // utility
+    //
+
+    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+        self.transport.borrow_mut().write_u8(b).map_err(From::from)
+    }
+}
+
+/// Factory for creating instances of `TBinaryOutputProtocol`.
+#[derive(Default)]
+pub struct TBinaryOutputProtocolFactory;
+
+impl TBinaryOutputProtocolFactory {
+    /// Create a `TBinaryOutputProtocolFactory`.
+    pub fn new() -> TBinaryOutputProtocolFactory {
+        TBinaryOutputProtocolFactory {}
+    }
+}
+
+impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TOutputProtocol> {
+        Box::new(TBinaryOutputProtocol::new(transport, true)) as Box<TOutputProtocol>
+    }
+}
+
+fn field_type_to_u8(field_type: TType) -> u8 {
+    match field_type {
+        TType::Stop => 0x00,
+        TType::Void => 0x01,
+        TType::Bool => 0x02,
+        TType::I08 => 0x03, // equivalent to TType::Byte
+        TType::Double => 0x04,
+        TType::I16 => 0x06,
+        TType::I32 => 0x08,
+        TType::I64 => 0x0A,
+        TType::String | TType::Utf7 => 0x0B,
+        TType::Struct => 0x0C,
+        TType::Map => 0x0D,
+        TType::Set => 0x0E,
+        TType::List => 0x0F,
+        TType::Utf8 => 0x10,
+        TType::Utf16 => 0x11,
+    }
+}
+
+fn field_type_from_u8(b: u8) -> ::Result<TType> {
+    match b {
+        0x00 => Ok(TType::Stop),
+        0x01 => Ok(TType::Void),
+        0x02 => Ok(TType::Bool),
+        0x03 => Ok(TType::I08), // Equivalent to TType::Byte
+        0x04 => Ok(TType::Double),
+        0x06 => Ok(TType::I16),
+        0x08 => Ok(TType::I32),
+        0x0A => Ok(TType::I64),
+        0x0B => Ok(TType::String), // technically, also a UTF7, but we'll treat it as string
+        0x0C => Ok(TType::Struct),
+        0x0D => Ok(TType::Map),
+        0x0E => Ok(TType::Set),
+        0x0F => Ok(TType::List),
+        0x10 => Ok(TType::Utf8),
+        0x11 => Ok(TType::Utf16),
+        unkn => {
+            Err(::Error::Protocol(ProtocolError {
+                kind: ProtocolErrorKind::InvalidData,
+                message: format!("cannot convert {} to TType", unkn),
+            }))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use std::rc::Rc;
+    use std::cell::RefCell;
+
+    use ::protocol::{TFieldIdentifier, TMessageIdentifier, TMessageType, TInputProtocol,
+                     TListIdentifier, TMapIdentifier, TOutputProtocol, TSetIdentifier,
+                     TStructIdentifier, TType};
+    use ::transport::{TPassThruTransport, TTransport};
+    use ::transport::mem::TBufferTransport;
+
+    use super::*;
+
+    #[test]
+    fn must_write_message_call_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        let ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
+        assert!(o_prot.write_message_begin(&ident).is_ok());
+
+        let buf = trans.borrow().write_buffer_to_vec();
+
+        let expected: [u8; 16] = [0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x74, 0x65,
+                                  0x73, 0x74, 0x00, 0x00, 0x00, 0x01];
+
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+
+    #[test]
+    fn must_write_message_reply_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        let ident = TMessageIdentifier::new("test", TMessageType::Reply, 10);
+        assert!(o_prot.write_message_begin(&ident).is_ok());
+
+        let buf = trans.borrow().write_buffer_to_vec();
+
+        let expected: [u8; 16] = [0x80, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x74, 0x65,
+                                  0x73, 0x74, 0x00, 0x00, 0x00, 0x0A];
+
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_strict_message_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let sent_ident = TMessageIdentifier::new("test", TMessageType::Call, 1);
+        assert!(o_prot.write_message_begin(&sent_ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_ident = assert_success!(i_prot.read_message_begin());
+        assert_eq!(&received_ident, &sent_ident);
+    }
+
+    #[test]
+    fn must_write_message_end() {
+        assert_no_write(|o| o.write_message_end());
+    }
+
+    #[test]
+    fn must_write_struct_begin() {
+        assert_no_write(|o| o.write_struct_begin(&TStructIdentifier::new("foo")));
+    }
+
+    #[test]
+    fn must_write_struct_end() {
+        assert_no_write(|o| o.write_struct_end());
+    }
+
+    #[test]
+    fn must_write_field_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_field_begin(&TFieldIdentifier::new("some_field", TType::String, 22))
+            .is_ok());
+
+        let expected: [u8; 3] = [0x0B, 0x00, 0x16];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_field_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let sent_field_ident = TFieldIdentifier::new("foo", TType::I64, 20);
+        assert!(o_prot.write_field_begin(&sent_field_ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let expected_ident = TFieldIdentifier {
+            name: None,
+            field_type: TType::I64,
+            id: Some(20),
+        }; // no name
+        let received_ident = assert_success!(i_prot.read_field_begin());
+        assert_eq!(&received_ident, &expected_ident);
+    }
+
+    #[test]
+    fn must_write_stop_field() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_field_stop().is_ok());
+
+        let expected: [u8; 1] = [0x00];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_field_stop() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_field_stop().is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let expected_ident = TFieldIdentifier {
+            name: None,
+            field_type: TType::Stop,
+            id: Some(0),
+        }; // we get id 0
+
+        let received_ident = assert_success!(i_prot.read_field_begin());
+        assert_eq!(&received_ident, &expected_ident);
+    }
+
+    #[test]
+    fn must_write_field_end() {
+        assert_no_write(|o| o.write_field_end());
+    }
+
+    #[test]
+    fn must_write_list_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_list_begin(&TListIdentifier::new(TType::Bool, 5)).is_ok());
+
+        let expected: [u8; 5] = [0x02, 0x00, 0x00, 0x00, 0x05];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_list_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TListIdentifier::new(TType::List, 900);
+        assert!(o_prot.write_list_begin(&ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_ident = assert_success!(i_prot.read_list_begin());
+        assert_eq!(&received_ident, &ident);
+    }
+
+    #[test]
+    fn must_write_list_end() {
+        assert_no_write(|o| o.write_list_end());
+    }
+
+    #[test]
+    fn must_write_set_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_set_begin(&TSetIdentifier::new(TType::I16, 7)).is_ok());
+
+        let expected: [u8; 5] = [0x06, 0x00, 0x00, 0x00, 0x07];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_set_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TSetIdentifier::new(TType::I64, 2000);
+        assert!(o_prot.write_set_begin(&ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_ident_result = i_prot.read_set_begin();
+        assert!(received_ident_result.is_ok());
+        assert_eq!(&received_ident_result.unwrap(), &ident);
+    }
+
+    #[test]
+    fn must_write_set_end() {
+        assert_no_write(|o| o.write_set_end());
+    }
+
+    #[test]
+    fn must_write_map_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_map_begin(&TMapIdentifier::new(TType::I64, TType::Struct, 32))
+            .is_ok());
+
+        let expected: [u8; 6] = [0x0A, 0x0C, 0x00, 0x00, 0x00, 0x20];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_round_trip_map_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TMapIdentifier::new(TType::Map, TType::Set, 100);
+        assert!(o_prot.write_map_begin(&ident).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_ident = assert_success!(i_prot.read_map_begin());
+        assert_eq!(&received_ident, &ident);
+    }
+
+    #[test]
+    fn must_write_map_end() {
+        assert_no_write(|o| o.write_map_end());
+    }
+
+    #[test]
+    fn must_write_bool_true() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_bool(true).is_ok());
+
+        let expected: [u8; 1] = [0x01];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_write_bool_false() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert!(o_prot.write_bool(false).is_ok());
+
+        let expected: [u8; 1] = [0x00];
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&expected, buf.as_slice());
+    }
+
+    #[test]
+    fn must_read_bool_true() {
+        let (trans, mut i_prot, _) = test_objects();
+
+        trans.borrow_mut().set_readable_bytes(&[0x01]);
+
+        let read_bool = assert_success!(i_prot.read_bool());
+        assert_eq!(read_bool, true);
+    }
+
+    #[test]
+    fn must_read_bool_false() {
+        let (trans, mut i_prot, _) = test_objects();
+
+        trans.borrow_mut().set_readable_bytes(&[0x00]);
+
+        let read_bool = assert_success!(i_prot.read_bool());
+        assert_eq!(read_bool, false);
+    }
+
+    #[test]
+    fn must_allow_any_non_zero_value_to_be_interpreted_as_bool_true() {
+        let (trans, mut i_prot, _) = test_objects();
+
+        trans.borrow_mut().set_readable_bytes(&[0xAC]);
+
+        let read_bool = assert_success!(i_prot.read_bool());
+        assert_eq!(read_bool, true);
+    }
+
+    #[test]
+    fn must_write_bytes() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        let bytes: [u8; 10] = [0x0A, 0xCC, 0xD1, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF];
+
+        assert!(o_prot.write_bytes(&bytes).is_ok());
+
+        let buf = trans.borrow().write_buffer_to_vec();
+        assert_eq!(&buf[0..4], [0x00, 0x00, 0x00, 0x0A]); // length
+        assert_eq!(&buf[4..], bytes); // actual bytes
+    }
+
+    #[test]
+    fn must_round_trip_bytes() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let bytes: [u8; 25] = [0x20, 0xFD, 0x18, 0x84, 0x99, 0x12, 0xAB, 0xBB, 0x45, 0xDF, 0x34,
+                               0xDC, 0x98, 0xA4, 0x6D, 0xF3, 0x99, 0xB4, 0xB7, 0xD4, 0x9C, 0xA5,
+                               0xB3, 0xC9, 0x88];
+
+        assert!(o_prot.write_bytes(&bytes).is_ok());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let received_bytes = assert_success!(i_prot.read_bytes());
+        assert_eq!(&received_bytes, &bytes);
+    }
+
+    fn test_objects
+        ()
+        -> (Rc<RefCell<Box<TBufferTransport>>>, TBinaryInputProtocol, TBinaryOutputProtocol)
+    {
+        let mem = Rc::new(RefCell::new(Box::new(TBufferTransport::with_capacity(40, 40))));
+
+        let inner: Box<TTransport> = Box::new(TPassThruTransport { inner: mem.clone() });
+        let inner = Rc::new(RefCell::new(inner));
+
+        let i_prot = TBinaryInputProtocol::new(inner.clone(), true);
+        let o_prot = TBinaryOutputProtocol::new(inner.clone(), true);
+
+        (mem, i_prot, o_prot)
+    }
+
+    fn assert_no_write<F: FnMut(&mut TBinaryOutputProtocol) -> ::Result<()>>(mut write_fn: F) {
+        let (trans, _, mut o_prot) = test_objects();
+        assert!(write_fn(&mut o_prot).is_ok());
+        assert_eq!(trans.borrow().write_buffer_as_ref().len(), 0);
+    }
+}
diff --git a/lib/rs/src/protocol/compact.rs b/lib/rs/src/protocol/compact.rs
new file mode 100644
index 0000000..96fa8ef
--- /dev/null
+++ b/lib/rs/src/protocol/compact.rs
@@ -0,0 +1,2085 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
+use integer_encoding::{VarIntReader, VarIntWriter};
+use std::cell::RefCell;
+use std::convert::From;
+use std::rc::Rc;
+use std::io::{Read, Write};
+use try_from::TryFrom;
+
+use ::transport::TTransport;
+use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType,
+            TInputProtocol, TInputProtocolFactory};
+use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
+
+const COMPACT_PROTOCOL_ID: u8 = 0x82;
+const COMPACT_VERSION: u8 = 0x01;
+const COMPACT_VERSION_MASK: u8 = 0x1F;
+
+/// Read messages encoded in the Thrift compact protocol.
+///
+/// # Examples
+///
+/// Create and use a `TCompactInputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TCompactInputProtocol, TInputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut i_prot = TCompactInputProtocol::new(transport);
+///
+/// let recvd_bool = i_prot.read_bool().unwrap();
+/// let recvd_string = i_prot.read_string().unwrap();
+/// ```
+pub struct TCompactInputProtocol {
+    // Identifier of the last field deserialized for a struct.
+    last_read_field_id: i16,
+    // Stack of the last read field ids (a new entry is added each time a nested struct is read).
+    read_field_id_stack: Vec<i16>,
+    // Boolean value for a field.
+    // Saved because boolean fields and their value are encoded in a single byte,
+    // and reading the field only occurs after the field id is read.
+    pending_read_bool_value: Option<bool>,
+    // Underlying transport used for byte-level operations.
+    transport: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TCompactInputProtocol {
+    /// Create a `TCompactInputProtocol` that reads bytes from `transport`.
+    pub fn new(transport: Rc<RefCell<Box<TTransport>>>) -> TCompactInputProtocol {
+        TCompactInputProtocol {
+            last_read_field_id: 0,
+            read_field_id_stack: Vec::new(),
+            pending_read_bool_value: None,
+            transport: transport,
+        }
+    }
+
+    fn read_list_set_begin(&mut self) -> ::Result<(TType, i32)> {
+        let header = self.read_byte()?;
+        let element_type = collection_u8_to_type(header & 0x0F)?;
+
+        let element_count;
+        let possible_element_count = (header & 0xF0) >> 4;
+        if possible_element_count != 15 {
+            // high bits set high if count and type encoded separately
+            element_count = possible_element_count as i32;
+        } else {
+            element_count = self.transport.borrow_mut().read_varint::<u32>()? as i32;
+        }
+
+        Ok((element_type, element_count))
+    }
+}
+
+impl TInputProtocol for TCompactInputProtocol {
+    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+        let compact_id = self.read_byte()?;
+        if compact_id != COMPACT_PROTOCOL_ID {
+            Err(::Error::Protocol(::ProtocolError {
+                kind: ::ProtocolErrorKind::BadVersion,
+                message: format!("invalid compact protocol header {:?}", compact_id),
+            }))
+        } else {
+            Ok(())
+        }?;
+
+        let type_and_byte = self.read_byte()?;
+        let received_version = type_and_byte & COMPACT_VERSION_MASK;
+        if received_version != COMPACT_VERSION {
+            Err(::Error::Protocol(::ProtocolError {
+                kind: ::ProtocolErrorKind::BadVersion,
+                message: format!("cannot process compact protocol version {:?}",
+                                 received_version),
+            }))
+        } else {
+            Ok(())
+        }?;
+
+        // NOTE: unsigned right shift will pad with 0s
+        let message_type: TMessageType = TMessageType::try_from(type_and_byte >> 5)?;
+        let sequence_number = self.read_i32()?;
+        let service_call_name = self.read_string()?;
+
+        self.last_read_field_id = 0;
+
+        Ok(TMessageIdentifier::new(service_call_name, message_type, sequence_number))
+    }
+
+    fn read_message_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+        self.read_field_id_stack.push(self.last_read_field_id);
+        self.last_read_field_id = 0;
+        Ok(None)
+    }
+
+    fn read_struct_end(&mut self) -> ::Result<()> {
+        self.last_read_field_id = self.read_field_id_stack
+            .pop()
+            .expect("should have previous field ids");
+        Ok(())
+    }
+
+    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+        // we can read at least one byte, which is:
+        // - the type
+        // - the field delta and the type
+        let field_type = self.read_byte()?;
+        let field_delta = (field_type & 0xF0) >> 4;
+        let field_type = match field_type & 0x0F {
+            0x01 => {
+                self.pending_read_bool_value = Some(true);
+                Ok(TType::Bool)
+            }
+            0x02 => {
+                self.pending_read_bool_value = Some(false);
+                Ok(TType::Bool)
+            }
+            ttu8 => u8_to_type(ttu8),
+        }?;
+
+        match field_type {
+            TType::Stop => {
+                Ok(TFieldIdentifier::new::<Option<String>, String, Option<i16>>(None,
+                                                                                TType::Stop,
+                                                                                None))
+            }
+            _ => {
+                if field_delta != 0 {
+                    self.last_read_field_id += field_delta as i16;
+                } else {
+                    self.last_read_field_id = self.read_i16()?;
+                };
+
+                Ok(TFieldIdentifier {
+                    name: None,
+                    field_type: field_type,
+                    id: Some(self.last_read_field_id),
+                })
+            }
+        }
+    }
+
+    fn read_field_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_bool(&mut self) -> ::Result<bool> {
+        match self.pending_read_bool_value.take() {
+            Some(b) => Ok(b),
+            None => {
+                let b = self.read_byte()?;
+                match b {
+                    0x01 => Ok(true),
+                    0x02 => Ok(false),
+                    unkn => {
+                        Err(::Error::Protocol(::ProtocolError {
+                            kind: ::ProtocolErrorKind::InvalidData,
+                            message: format!("cannot convert {} into bool", unkn),
+                        }))
+                    }
+                }
+            }
+        }
+    }
+
+    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+        let len = self.transport.borrow_mut().read_varint::<u32>()?;
+        let mut buf = vec![0u8; len as usize];
+        self.transport.borrow_mut().read_exact(&mut buf).map_err(From::from).map(|_| buf)
+    }
+
+    fn read_i8(&mut self) -> ::Result<i8> {
+        self.read_byte().map(|i| i as i8)
+    }
+
+    fn read_i16(&mut self) -> ::Result<i16> {
+        self.transport.borrow_mut().read_varint::<i16>().map_err(From::from)
+    }
+
+    fn read_i32(&mut self) -> ::Result<i32> {
+        self.transport.borrow_mut().read_varint::<i32>().map_err(From::from)
+    }
+
+    fn read_i64(&mut self) -> ::Result<i64> {
+        self.transport.borrow_mut().read_varint::<i64>().map_err(From::from)
+    }
+
+    fn read_double(&mut self) -> ::Result<f64> {
+        self.transport.borrow_mut().read_f64::<BigEndian>().map_err(From::from)
+    }
+
+    fn read_string(&mut self) -> ::Result<String> {
+        let bytes = self.read_bytes()?;
+        String::from_utf8(bytes).map_err(From::from)
+    }
+
+    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+        let (element_type, element_count) = self.read_list_set_begin()?;
+        Ok(TListIdentifier::new(element_type, element_count))
+    }
+
+    fn read_list_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+        let (element_type, element_count) = self.read_list_set_begin()?;
+        Ok(TSetIdentifier::new(element_type, element_count))
+    }
+
+    fn read_set_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+        let element_count = self.transport.borrow_mut().read_varint::<u32>()? as i32;
+        if element_count == 0 {
+            Ok(TMapIdentifier::new(None, None, 0))
+        } else {
+            let type_header = self.read_byte()?;
+            let key_type = collection_u8_to_type((type_header & 0xF0) >> 4)?;
+            let val_type = collection_u8_to_type(type_header & 0x0F)?;
+            Ok(TMapIdentifier::new(key_type, val_type, element_count))
+        }
+    }
+
+    fn read_map_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    // utility
+    //
+
+    fn read_byte(&mut self) -> ::Result<u8> {
+        let mut buf = [0u8; 1];
+        self.transport.borrow_mut().read_exact(&mut buf).map_err(From::from).map(|_| buf[0])
+    }
+}
+
+/// Factory for creating instances of `TCompactInputProtocol`.
+#[derive(Default)]
+pub struct TCompactInputProtocolFactory;
+
+impl TCompactInputProtocolFactory {
+    /// Create a `TCompactInputProtocolFactory`.
+    pub fn new() -> TCompactInputProtocolFactory {
+        TCompactInputProtocolFactory {}
+    }
+}
+
+impl TInputProtocolFactory for TCompactInputProtocolFactory {
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TInputProtocol> {
+        Box::new(TCompactInputProtocol::new(transport)) as Box<TInputProtocol>
+    }
+}
+
+/// Write messages using the Thrift compact protocol.
+///
+/// # Examples
+///
+/// Create and use a `TCompactOutputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TCompactOutputProtocol, TOutputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut o_prot = TCompactOutputProtocol::new(transport);
+///
+/// o_prot.write_bool(true).unwrap();
+/// o_prot.write_string("test_string").unwrap();
+/// ```
+pub struct TCompactOutputProtocol {
+    // Identifier of the last field serialized for a struct.
+    last_write_field_id: i16,
+    // Stack of the last written field ids (a new entry is added each time a nested struct is written).
+    write_field_id_stack: Vec<i16>,
+    // Field identifier of the boolean field to be written.
+    // Saved because boolean fields and their value are encoded in a single byte
+    pending_write_bool_field_identifier: Option<TFieldIdentifier>,
+    // Underlying transport used for byte-level operations.
+    transport: Rc<RefCell<Box<TTransport>>>,
+}
+
+impl TCompactOutputProtocol {
+    /// Create a `TCompactOutputProtocol` that writes bytes to `transport`.
+    pub fn new(transport: Rc<RefCell<Box<TTransport>>>) -> TCompactOutputProtocol {
+        TCompactOutputProtocol {
+            last_write_field_id: 0,
+            write_field_id_stack: Vec::new(),
+            pending_write_bool_field_identifier: None,
+            transport: transport,
+        }
+    }
+
+    // FIXME: field_type as unconstrained u8 is bad
+    fn write_field_header(&mut self, field_type: u8, field_id: i16) -> ::Result<()> {
+        let field_delta = field_id - self.last_write_field_id;
+        if field_delta > 0 && field_delta < 15 {
+            self.write_byte(((field_delta as u8) << 4) | field_type)?;
+        } else {
+            self.write_byte(field_type)?;
+            self.write_i16(field_id)?;
+        }
+        self.last_write_field_id = field_id;
+        Ok(())
+    }
+
+    fn write_list_set_begin(&mut self, element_type: TType, element_count: i32) -> ::Result<()> {
+        let elem_identifier = collection_type_to_u8(element_type);
+        if element_count <= 14 {
+            let header = (element_count as u8) << 4 | elem_identifier;
+            self.write_byte(header)
+        } else {
+            let header = 0xF0 | elem_identifier;
+            self.write_byte(header)?;
+            self.transport
+                .borrow_mut()
+                .write_varint(element_count as u32)
+                .map_err(From::from)
+                .map(|_| ())
+        }
+    }
+
+    fn assert_no_pending_bool_write(&self) {
+        if let Some(ref f) = self.pending_write_bool_field_identifier {
+            panic!("pending bool field {:?} not written", f)
+        }
+    }
+}
+
+impl TOutputProtocol for TCompactOutputProtocol {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+        self.write_byte(COMPACT_PROTOCOL_ID)?;
+        self.write_byte((u8::from(identifier.message_type) << 5) | COMPACT_VERSION)?;
+        self.write_i32(identifier.sequence_number)?;
+        self.write_string(&identifier.name)?;
+        Ok(())
+    }
+
+    fn write_message_end(&mut self) -> ::Result<()> {
+        self.assert_no_pending_bool_write();
+        Ok(())
+    }
+
+    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
+        self.write_field_id_stack.push(self.last_write_field_id);
+        self.last_write_field_id = 0;
+        Ok(())
+    }
+
+    fn write_struct_end(&mut self) -> ::Result<()> {
+        self.assert_no_pending_bool_write();
+        self.last_write_field_id =
+            self.write_field_id_stack.pop().expect("should have previous field ids");
+        Ok(())
+    }
+
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+        match identifier.field_type {
+            TType::Bool => {
+                if self.pending_write_bool_field_identifier.is_some() {
+                    panic!("should not have a pending bool while writing another bool with id: \
+                            {:?}",
+                           identifier)
+                }
+                self.pending_write_bool_field_identifier = Some(identifier.clone());
+                Ok(())
+            }
+            _ => {
+                let field_type = type_to_u8(identifier.field_type);
+                let field_id = identifier.id.expect("non-stop field should have field id");
+                self.write_field_header(field_type, field_id)
+            }
+        }
+    }
+
+    fn write_field_end(&mut self) -> ::Result<()> {
+        self.assert_no_pending_bool_write();
+        Ok(())
+    }
+
+    fn write_field_stop(&mut self) -> ::Result<()> {
+        self.assert_no_pending_bool_write();
+        self.write_byte(type_to_u8(TType::Stop))
+    }
+
+    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+        match self.pending_write_bool_field_identifier.take() {
+            Some(pending) => {
+                let field_id = pending.id.expect("bool field should have a field id");
+                let field_type_as_u8 = if b { 0x01 } else { 0x02 };
+                self.write_field_header(field_type_as_u8, field_id)
+            }
+            None => {
+                if b {
+                    self.write_byte(0x01)
+                } else {
+                    self.write_byte(0x02)
+                }
+            }
+        }
+    }
+
+    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+        self.transport.borrow_mut().write_varint(b.len() as u32)?;
+        self.transport.borrow_mut().write_all(b).map_err(From::from)
+    }
+
+    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+        self.write_byte(i as u8)
+    }
+
+    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+        self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
+    }
+
+    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+        self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
+    }
+
+    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+        self.transport.borrow_mut().write_varint(i).map_err(From::from).map(|_| ())
+    }
+
+    fn write_double(&mut self, d: f64) -> ::Result<()> {
+        self.transport.borrow_mut().write_f64::<BigEndian>(d).map_err(From::from)
+    }
+
+    fn write_string(&mut self, s: &str) -> ::Result<()> {
+        self.write_bytes(s.as_bytes())
+    }
+
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+        self.write_list_set_begin(identifier.element_type, identifier.size)
+    }
+
+    fn write_list_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+        self.write_list_set_begin(identifier.element_type, identifier.size)
+    }
+
+    fn write_set_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+        if identifier.size == 0 {
+            self.write_byte(0)
+        } else {
+            self.transport.borrow_mut().write_varint(identifier.size as u32)?;
+
+            let key_type = identifier.key_type
+                .expect("map identifier to write should contain key type");
+            let key_type_byte = collection_type_to_u8(key_type) << 4;
+
+            let val_type = identifier.value_type
+                .expect("map identifier to write should contain value type");
+            let val_type_byte = collection_type_to_u8(val_type);
+
+            let map_type_header = key_type_byte | val_type_byte;
+            self.write_byte(map_type_header)
+        }
+    }
+
+    fn write_map_end(&mut self) -> ::Result<()> {
+        Ok(())
+    }
+
+    fn flush(&mut self) -> ::Result<()> {
+        self.transport.borrow_mut().flush().map_err(From::from)
+    }
+
+    // utility
+    //
+
+    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+        self.transport.borrow_mut().write(&[b]).map_err(From::from).map(|_| ())
+    }
+}
+
+/// Factory for creating instances of `TCompactOutputProtocol`.
+#[derive(Default)]
+pub struct TCompactOutputProtocolFactory;
+
+impl TCompactOutputProtocolFactory {
+    /// Create a `TCompactOutputProtocolFactory`.
+    pub fn new() -> TCompactOutputProtocolFactory {
+        TCompactOutputProtocolFactory {}
+    }
+}
+
+impl TOutputProtocolFactory for TCompactOutputProtocolFactory {
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TOutputProtocol> {
+        Box::new(TCompactOutputProtocol::new(transport)) as Box<TOutputProtocol>
+    }
+}
+
+fn collection_type_to_u8(field_type: TType) -> u8 {
+    match field_type {
+        TType::Bool => 0x01,
+        f => type_to_u8(f),
+    }
+}
+
+fn type_to_u8(field_type: TType) -> u8 {
+    match field_type {
+        TType::Stop => 0x00,
+        TType::I08 => 0x03, // equivalent to TType::Byte
+        TType::I16 => 0x04,
+        TType::I32 => 0x05,
+        TType::I64 => 0x06,
+        TType::Double => 0x07,
+        TType::String => 0x08,
+        TType::List => 0x09,
+        TType::Set => 0x0A,
+        TType::Map => 0x0B,
+        TType::Struct => 0x0C,
+        _ => panic!(format!("should not have attempted to convert {} to u8", field_type)),
+    }
+}
+
+fn collection_u8_to_type(b: u8) -> ::Result<TType> {
+    match b {
+        0x01 => Ok(TType::Bool),
+        o => u8_to_type(o),
+    }
+}
+
+fn u8_to_type(b: u8) -> ::Result<TType> {
+    match b {
+        0x00 => Ok(TType::Stop),
+        0x03 => Ok(TType::I08), // equivalent to TType::Byte
+        0x04 => Ok(TType::I16),
+        0x05 => Ok(TType::I32),
+        0x06 => Ok(TType::I64),
+        0x07 => Ok(TType::Double),
+        0x08 => Ok(TType::String),
+        0x09 => Ok(TType::List),
+        0x0A => Ok(TType::Set),
+        0x0B => Ok(TType::Map),
+        0x0C => Ok(TType::Struct),
+        unkn => {
+            Err(::Error::Protocol(::ProtocolError {
+                kind: ::ProtocolErrorKind::InvalidData,
+                message: format!("cannot convert {} into TType", unkn),
+            }))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use std::rc::Rc;
+    use std::cell::RefCell;
+
+    use ::protocol::{TFieldIdentifier, TMessageIdentifier, TMessageType, TInputProtocol,
+                     TListIdentifier, TMapIdentifier, TOutputProtocol, TSetIdentifier,
+                     TStructIdentifier, TType};
+    use ::transport::{TPassThruTransport, TTransport};
+    use ::transport::mem::TBufferTransport;
+
+    use super::*;
+
+    #[test]
+    fn must_write_message_begin_0() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new("foo", TMessageType::Call, 431)));
+
+        let expected: [u8; 8] =
+            [0x82 /* protocol ID */, 0x21 /* message type | protocol version */, 0xDE,
+             0x06 /* zig-zag varint sequence number */, 0x03 /* message-name length */,
+             0x66, 0x6F, 0x6F /* "foo" */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_write_message_begin_1() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new("bar", TMessageType::Reply, 991828)));
+
+        let expected: [u8; 9] =
+            [0x82 /* protocol ID */, 0x41 /* message type | protocol version */, 0xA8,
+             0x89, 0x79 /* zig-zag varint sequence number */,
+             0x03 /* message-name length */, 0x62, 0x61, 0x72 /* "bar" */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_message_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1283948);
+
+        assert_success!(o_prot.write_message_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_message_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_message_end() {
+        assert_no_write(|o| o.write_message_end());
+    }
+
+    // NOTE: structs and fields are tested together
+    //
+
+    #[test]
+    fn must_write_struct_with_delta_fields() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with tiny field ids
+        // since they're small the field ids will be encoded as deltas
+
+        // since this is the first field (and it's zero) it gets the full varint write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 0)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I16, 4)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::List, 9)));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 5] = [0x03 /* field type */, 0x00 /* first field id */,
+                                 0x44 /* field delta (4) | field type */,
+                                 0x59 /* field delta (5) | field type */,
+                                 0x00 /* field stop */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_struct_with_delta_fields() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with tiny field ids
+        // since they're small the field ids will be encoded as deltas
+
+        // since this is the first field (and it's zero) it gets the full varint write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I08, 0);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I16, 4);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::List, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_struct_with_non_zero_initial_field_and_delta_fields() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with tiny field ids
+        // since they're small the field ids will be encoded as deltas
+
+        // gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 6)));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 4] = [0x15 /* field delta (1) | field type */,
+                                 0x1A /* field delta (1) | field type */,
+                                 0x48 /* field delta (4) | field type */,
+                                 0x00 /* field stop */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_struct_with_non_zero_initial_field_and_delta_fields() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with tiny field ids
+        // since they're small the field ids will be encoded as deltas
+
+        // gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::Set, 2);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it can be encoded as a delta
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::String, 6);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_struct_with_long_fields() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since this is the first field (and it's zero) it gets the full varint write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 0)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 16)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 99)));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 8] =
+            [0x05 /* field type */, 0x00 /* first field id */,
+             0x06 /* field type */, 0x20 /* zig-zag varint field id */,
+             0x0A /* field type */, 0xC6, 0x01 /* zig-zag varint field id */,
+             0x00 /* field stop */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_struct_with_long_fields() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since this is the first field (and it's zero) it gets the full varint write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I32, 0);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I64, 16);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 99);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_struct_with_mix_of_long_and_delta_fields() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 1000)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2001)));
+        assert_success!(o_prot.write_field_end());
+
+        // since this is only 3 up from the previous it is recorded as a delta
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Set, 2004)));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 10] =
+            [0x16 /* field delta (1) | field type */,
+             0x85 /* field delta (8) | field type */, 0x0A /* field type */, 0xD0,
+             0x0F /* zig-zag varint field id */, 0x0A /* field type */, 0xA2,
+             0x1F /* zig-zag varint field id */,
+             0x3A /* field delta (3) | field type */, 0x00 /* field stop */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_struct_with_mix_of_long_and_delta_fields() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        let struct_ident = TStructIdentifier::new("foo");
+        assert_success!(o_prot.write_struct_begin(&struct_ident));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Set, 1000);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta is > 15 it is encoded as a zig-zag varint
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::Set, 2001);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // since this is only 3 up from the previous it is recorded as a delta
+        let field_ident_5 = TFieldIdentifier::new("foo", TType::Set, 2004);
+        assert_success!(o_prot.write_field_begin(&field_ident_5));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_5 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_5,
+                   TFieldIdentifier { name: None, ..field_ident_5 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_nested_structs_0() {
+        // last field of the containing struct is a delta
+        // first field of the the contained struct is a delta
+
+        let (trans, _, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 7)));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 7] =
+            [0x16 /* field delta (1) | field type */,
+             0x85 /* field delta (8) | field type */,
+             0x73 /* field delta (7) | field type */, 0x07 /* field type */,
+             0x30 /* zig-zag varint field id */, 0x00 /* field stop - contained */,
+             0x00 /* field stop - containing */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_nested_structs_0() {
+        // last field of the containing struct is a delta
+        // first field of the the contained struct is a delta
+
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::I08, 7);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::Double, 24);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read containing struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        // read contained struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        // end contained struct
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+
+        // end containing struct
+        let read_ident_7 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_7,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_nested_structs_1() {
+        // last field of the containing struct is a delta
+        // first field of the the contained struct is a full write
+
+        let (trans, _, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I32, 9)));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 24)));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 7] =
+            [0x16 /* field delta (1) | field type */,
+             0x85 /* field delta (8) | field type */, 0x07 /* field type */,
+             0x30 /* zig-zag varint field id */,
+             0x33 /* field delta (3) | field type */, 0x00 /* field stop - contained */,
+             0x00 /* field stop - containing */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_nested_structs_1() {
+        // last field of the containing struct is a delta
+        // first field of the the contained struct is a full write
+
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::I32, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 24);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read containing struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        // read contained struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        // end contained struct
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+
+        // end containing struct
+        let read_ident_7 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_7,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_nested_structs_2() {
+        // last field of the containing struct is a full write
+        // first field of the the contained struct is a delta write
+
+        let (trans, _, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 7)));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 10)));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 7] =
+            [0x16 /* field delta (1) | field type */, 0x08 /* field type */,
+             0x2A /* zig-zag varint field id */, 0x77 /* field delta(7) | field type */,
+             0x33 /* field delta (3) | field type */, 0x00 /* field stop - contained */,
+             0x00 /* field stop - containing */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_nested_structs_2() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 15 it gets a full write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 7);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 10);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read containing struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        // read contained struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        // end contained struct
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+
+        // end containing struct
+        let read_ident_7 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_7,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_nested_structs_3() {
+        // last field of the containing struct is a full write
+        // first field of the the contained struct is a full write
+
+        let (trans, _, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I64, 1)));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::String, 21)));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Double, 21)));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::I08, 27)));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 8] =
+            [0x16 /* field delta (1) | field type */, 0x08 /* field type */,
+             0x2A /* zig-zag varint field id */, 0x07 /* field type */,
+             0x2A /* zig-zag varint field id */,
+             0x63 /* field delta (6) | field type */, 0x00 /* field stop - contained */,
+             0x00 /* field stop - containing */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_nested_structs_3() {
+        // last field of the containing struct is a full write
+        // first field of the the contained struct is a full write
+
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // start containing struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // containing struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::I64, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_field_end());
+
+        // containing struct
+        // since this delta > 15 it gets a full write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::String, 21);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_field_end());
+
+        // start contained struct
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // contained struct
+        // since this delta > 15 it gets a full write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Double, 21);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_field_end());
+
+        // contained struct
+        // since the delta is > 0 and < 15 it gets a delta write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::I08, 27);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_field_end());
+
+        // end contained struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // end containing struct
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read containing struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        assert_success!(i_prot.read_field_end());
+
+        // read contained struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        assert_success!(i_prot.read_field_end());
+
+        // end contained struct
+        let read_ident_6 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_6,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+
+        // end containing struct
+        let read_ident_7 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_7,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    fn must_write_bool_field() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+
+        // write three fields with field ids that cannot be encoded as deltas
+
+        // since the delta is > 0 and < 16 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it gets a delta write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 9)));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 26)));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 15 it gets a full write
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 45)));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        // get bytes written
+        let buf = trans.borrow_mut().write_buffer_to_vec();
+
+        let expected: [u8; 7] = [0x11 /* field delta (1) | true */,
+                                 0x82 /* field delta (8) | false */, 0x01 /* true */,
+                                 0x34 /* field id */, 0x02 /* false */,
+                                 0x5A /* field id */, 0x00 /* stop field */];
+
+        assert_eq!(&buf, &expected);
+    }
+
+    #[test]
+    fn must_round_trip_bool_field() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        // no bytes should be written however
+        let struct_ident = TStructIdentifier::new("foo");
+        assert_success!(o_prot.write_struct_begin(&struct_ident));
+
+        // write two fields
+
+        // since the delta is > 0 and < 16 it gets a delta write
+        let field_ident_1 = TFieldIdentifier::new("foo", TType::Bool, 1);
+        assert_success!(o_prot.write_field_begin(&field_ident_1));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 0 and < 15 it gets a delta write
+        let field_ident_2 = TFieldIdentifier::new("foo", TType::Bool, 9);
+        assert_success!(o_prot.write_field_begin(&field_ident_2));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 15 it gets a full write
+        let field_ident_3 = TFieldIdentifier::new("foo", TType::Bool, 26);
+        assert_success!(o_prot.write_field_begin(&field_ident_3));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_field_end());
+
+        // since this delta > 15 it gets a full write
+        let field_ident_4 = TFieldIdentifier::new("foo", TType::Bool, 45);
+        assert_success!(o_prot.write_field_begin(&field_ident_4));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_field_end());
+
+        // now, finish the struct off
+        assert_success!(o_prot.write_field_stop());
+        assert_success!(o_prot.write_struct_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // read the struct back
+        assert_success!(i_prot.read_struct_begin());
+
+        let read_ident_1 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_1,
+                   TFieldIdentifier { name: None, ..field_ident_1 });
+        let read_value_1 = assert_success!(i_prot.read_bool());
+        assert_eq!(read_value_1, true);
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_2 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_2,
+                   TFieldIdentifier { name: None, ..field_ident_2 });
+        let read_value_2 = assert_success!(i_prot.read_bool());
+        assert_eq!(read_value_2, false);
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_3 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_3,
+                   TFieldIdentifier { name: None, ..field_ident_3 });
+        let read_value_3 = assert_success!(i_prot.read_bool());
+        assert_eq!(read_value_3, true);
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_4 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_4,
+                   TFieldIdentifier { name: None, ..field_ident_4 });
+        let read_value_4 = assert_success!(i_prot.read_bool());
+        assert_eq!(read_value_4, false);
+        assert_success!(i_prot.read_field_end());
+
+        let read_ident_5 = assert_success!(i_prot.read_field_begin());
+        assert_eq!(read_ident_5,
+                   TFieldIdentifier {
+                       name: None,
+                       field_type: TType::Stop,
+                       id: None,
+                   });
+
+        assert_success!(i_prot.read_struct_end());
+    }
+
+    #[test]
+    #[should_panic]
+    fn must_fail_if_write_field_end_without_writing_bool_value() {
+        let (_, _, mut o_prot) = test_objects();
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
+        o_prot.write_field_end().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn must_fail_if_write_stop_field_without_writing_bool_value() {
+        let (_, _, mut o_prot) = test_objects();
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
+        o_prot.write_field_stop().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn must_fail_if_write_struct_end_without_writing_bool_value() {
+        let (_, _, mut o_prot) = test_objects();
+        assert_success!(o_prot.write_struct_begin(&TStructIdentifier::new("foo")));
+        assert_success!(o_prot.write_field_begin(&TFieldIdentifier::new("foo", TType::Bool, 1)));
+        o_prot.write_struct_end().unwrap();
+    }
+
+    #[test]
+    #[should_panic]
+    fn must_fail_if_write_struct_end_without_any_fields() {
+        let (_, _, mut o_prot) = test_objects();
+        o_prot.write_struct_end().unwrap();
+    }
+
+    #[test]
+    fn must_write_field_end() {
+        assert_no_write(|o| o.write_field_end());
+    }
+
+    #[test]
+    fn must_write_small_sized_list_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_list_begin(&TListIdentifier::new(TType::I64, 4)));
+
+        let expected: [u8; 1] = [0x46 /* size | elem_type */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_small_sized_list_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TListIdentifier::new(TType::I08, 10);
+
+        assert_success!(o_prot.write_list_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_list_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_large_sized_list_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        let res = o_prot.write_list_begin(&TListIdentifier::new(TType::List, 9999));
+        assert!(res.is_ok());
+
+        let expected: [u8; 3] = [0xF9 /* 0xF0 | elem_type */, 0x8F,
+                                 0x4E /* size as varint */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_large_sized_list_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TListIdentifier::new(TType::Set, 47381);
+
+        assert_success!(o_prot.write_list_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_list_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_list_end() {
+        assert_no_write(|o| o.write_list_end());
+    }
+
+    #[test]
+    fn must_write_small_sized_set_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Struct, 2)));
+
+        let expected: [u8; 1] = [0x2C /* size | elem_type */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_small_sized_set_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TSetIdentifier::new(TType::I16, 7);
+
+        assert_success!(o_prot.write_set_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_set_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_large_sized_set_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_set_begin(&TSetIdentifier::new(TType::Double, 23891)));
+
+        let expected: [u8; 4] = [0xF7 /* 0xF0 | elem_type */, 0xD3, 0xBA,
+                                 0x01 /* size as varint */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_large_sized_set_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TSetIdentifier::new(TType::Map, 3928429);
+
+        assert_success!(o_prot.write_set_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_set_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_set_end() {
+        assert_no_write(|o| o.write_set_end());
+    }
+
+    #[test]
+    fn must_write_zero_sized_map_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::String, TType::I32, 0)));
+
+        let expected: [u8; 1] = [0x00]; // since size is zero we don't write anything
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_read_zero_sized_map_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::I32, 0)));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_map_begin());
+        assert_eq!(&res,
+                   &TMapIdentifier {
+                       key_type: None,
+                       value_type: None,
+                       size: 0,
+                   });
+    }
+
+    #[test]
+    fn must_write_map_begin() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Double, TType::String, 238)));
+
+        let expected: [u8; 3] = [0xEE, 0x01 /* size as varint */,
+                                 0x78 /* key type | val type */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_map_begin() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let ident = TMapIdentifier::new(TType::Map, TType::List, 1928349);
+
+        assert_success!(o_prot.write_map_begin(&ident));
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        let res = assert_success!(i_prot.read_map_begin());
+        assert_eq!(&res, &ident);
+    }
+
+    #[test]
+    fn must_write_map_end() {
+        assert_no_write(|o| o.write_map_end());
+    }
+
+    #[test]
+    fn must_write_map_with_bool_key_and_value() {
+        let (trans, _, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_map_begin(&TMapIdentifier::new(TType::Bool, TType::Bool, 1)));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_map_end());
+
+        let expected: [u8; 4] = [0x01 /* size as varint */,
+                                 0x11 /* key type | val type */, 0x01 /* key: true */,
+                                 0x02 /* val: false */];
+
+        assert_eq!(trans.borrow().write_buffer_as_ref(), &expected);
+    }
+
+    #[test]
+    fn must_round_trip_map_with_bool_value() {
+        let (trans, mut i_prot, mut o_prot) = test_objects();
+
+        let map_ident = TMapIdentifier::new(TType::Bool, TType::Bool, 2);
+        assert_success!(o_prot.write_map_begin(&map_ident));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_bool(false));
+        assert_success!(o_prot.write_bool(true));
+        assert_success!(o_prot.write_map_end());
+
+        trans.borrow_mut().copy_write_buffer_to_read_buffer();
+
+        // map header
+        let rcvd_ident = assert_success!(i_prot.read_map_begin());
+        assert_eq!(&rcvd_ident, &map_ident);
+        // key 1
+        let b = assert_success!(i_prot.read_bool());
+        assert_eq!(b, true);
+        // val 1
+        let b = assert_success!(i_prot.read_bool());
+        assert_eq!(b, false);
+        // key 2
+        let b = assert_success!(i_prot.read_bool());
+        assert_eq!(b, false);
+        // val 2
+        let b = assert_success!(i_prot.read_bool());
+        assert_eq!(b, true);
+        // map end
+        assert_success!(i_prot.read_map_end());
+    }
+
+    #[test]
+    fn must_read_map_end() {
+        let (_, mut i_prot, _) = test_objects();
+        assert!(i_prot.read_map_end().is_ok()); // will blow up if we try to read from empty buffer
+    }
+
+    fn test_objects
+        ()
+        -> (Rc<RefCell<Box<TBufferTransport>>>, TCompactInputProtocol, TCompactOutputProtocol)
+    {
+        let mem = Rc::new(RefCell::new(Box::new(TBufferTransport::with_capacity(80, 80))));
+
+        let inner: Box<TTransport> = Box::new(TPassThruTransport { inner: mem.clone() });
+        let inner = Rc::new(RefCell::new(inner));
+
+        let i_prot = TCompactInputProtocol::new(inner.clone());
+        let o_prot = TCompactOutputProtocol::new(inner.clone());
+
+        (mem, i_prot, o_prot)
+    }
+
+    fn assert_no_write<F: FnMut(&mut TCompactOutputProtocol) -> ::Result<()>>(mut write_fn: F) {
+        let (trans, _, mut o_prot) = test_objects();
+        assert!(write_fn(&mut o_prot).is_ok());
+        assert_eq!(trans.borrow().write_buffer_as_ref().len(), 0);
+    }
+}
diff --git a/lib/rs/src/protocol/mod.rs b/lib/rs/src/protocol/mod.rs
new file mode 100644
index 0000000..b230d63
--- /dev/null
+++ b/lib/rs/src/protocol/mod.rs
@@ -0,0 +1,709 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+//! Types used to send and receive primitives between a Thrift client and server.
+//!
+//! # Examples
+//!
+//! Create and use a `TOutputProtocol`.
+//!
+//! ```no_run
+//! use std::cell::RefCell;
+//! use std::rc::Rc;
+//! use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType};
+//! use thrift::transport::{TTcpTransport, TTransport};
+//!
+//! // create the I/O channel
+//! let mut transport = TTcpTransport::new();
+//! transport.open("127.0.0.1:9090").unwrap();
+//! let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+//!
+//! // create the protocol to encode types into bytes
+//! let mut o_prot = TBinaryOutputProtocol::new(transport.clone(), true);
+//!
+//! // write types
+//! o_prot.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap();
+//! o_prot.write_string("foo").unwrap();
+//! o_prot.write_field_end().unwrap();
+//! ```
+//!
+//! Create and use a `TInputProtocol`.
+//!
+//! ```no_run
+//! use std::cell::RefCell;
+//! use std::rc::Rc;
+//! use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
+//! use thrift::transport::{TTcpTransport, TTransport};
+//!
+//! // create the I/O channel
+//! let mut transport = TTcpTransport::new();
+//! transport.open("127.0.0.1:9090").unwrap();
+//! let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+//!
+//! // create the protocol to decode bytes into types
+//! let mut i_prot = TBinaryInputProtocol::new(transport.clone(), true);
+//!
+//! // read types from the wire
+//! let field_identifier = i_prot.read_field_begin().unwrap();
+//! let field_contents = i_prot.read_string().unwrap();
+//! let field_end = i_prot.read_field_end().unwrap();
+//! ```
+
+use std::cell::RefCell;
+use std::fmt;
+use std::fmt::{Display, Formatter};
+use std::convert::From;
+use std::rc::Rc;
+use try_from::TryFrom;
+
+use ::{ProtocolError, ProtocolErrorKind};
+use ::transport::TTransport;
+
+mod binary;
+mod compact;
+mod multiplexed;
+mod stored;
+
+pub use self::binary::{TBinaryInputProtocol, TBinaryInputProtocolFactory, TBinaryOutputProtocol,
+                       TBinaryOutputProtocolFactory};
+pub use self::compact::{TCompactInputProtocol, TCompactInputProtocolFactory,
+                        TCompactOutputProtocol, TCompactOutputProtocolFactory};
+pub use self::multiplexed::TMultiplexedOutputProtocol;
+pub use self::stored::TStoredInputProtocol;
+
+// Default maximum depth to which `TInputProtocol::skip` will skip a Thrift
+// field. A default is necessary because Thrift structs or collections may
+// contain nested structs and collections, which could result in indefinite
+// recursion.
+const MAXIMUM_SKIP_DEPTH: i8 = 64;
+
+/// Converts a stream of bytes into Thrift identifiers, primitives,
+/// containers, or structs.
+///
+/// This trait does not deal with higher-level Thrift concepts like structs or
+/// exceptions - only with primitives and message or container boundaries. Once
+/// bytes are read they are deserialized and an identifier (for example
+/// `TMessageIdentifier`) or a primitive is returned.
+///
+/// All methods return a `thrift::Result`. If an `Err` is returned the protocol
+/// instance and its underlying transport should be terminated.
+///
+/// # Examples
+///
+/// Create and use a `TInputProtocol`
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryInputProtocol, TInputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("127.0.0.1:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut i_prot = TBinaryInputProtocol::new(transport.clone(), true);
+///
+/// let field_identifier = i_prot.read_field_begin().unwrap();
+/// let field_contents = i_prot.read_string().unwrap();
+/// let field_end = i_prot.read_field_end().unwrap();
+/// ```
+pub trait TInputProtocol {
+    /// Read the beginning of a Thrift message.
+    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier>;
+    /// Read the end of a Thrift message.
+    fn read_message_end(&mut self) -> ::Result<()>;
+    /// Read the beginning of a Thrift struct.
+    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>>;
+    /// Read the end of a Thrift struct.
+    fn read_struct_end(&mut self) -> ::Result<()>;
+    /// Read the beginning of a Thrift struct field.
+    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier>;
+    /// Read the end of a Thrift struct field.
+    fn read_field_end(&mut self) -> ::Result<()>;
+    /// Read a bool.
+    fn read_bool(&mut self) -> ::Result<bool>;
+    /// Read a fixed-length byte array.
+    fn read_bytes(&mut self) -> ::Result<Vec<u8>>;
+    /// Read a word.
+    fn read_i8(&mut self) -> ::Result<i8>;
+    /// Read a 16-bit signed integer.
+    fn read_i16(&mut self) -> ::Result<i16>;
+    /// Read a 32-bit signed integer.
+    fn read_i32(&mut self) -> ::Result<i32>;
+    /// Read a 64-bit signed integer.
+    fn read_i64(&mut self) -> ::Result<i64>;
+    /// Read a 64-bit float.
+    fn read_double(&mut self) -> ::Result<f64>;
+    /// Read a fixed-length string (not null terminated).
+    fn read_string(&mut self) -> ::Result<String>;
+    /// Read the beginning of a list.
+    fn read_list_begin(&mut self) -> ::Result<TListIdentifier>;
+    /// Read the end of a list.
+    fn read_list_end(&mut self) -> ::Result<()>;
+    /// Read the beginning of a set.
+    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier>;
+    /// Read the end of a set.
+    fn read_set_end(&mut self) -> ::Result<()>;
+    /// Read the beginning of a map.
+    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier>;
+    /// Read the end of a map.
+    fn read_map_end(&mut self) -> ::Result<()>;
+    /// Skip a field with type `field_type` recursively until the default
+    /// maximum skip depth is reached.
+    fn skip(&mut self, field_type: TType) -> ::Result<()> {
+        self.skip_till_depth(field_type, MAXIMUM_SKIP_DEPTH)
+    }
+    /// Skip a field with type `field_type` recursively up to `depth` levels.
+    fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> ::Result<()> {
+        if depth == 0 {
+            return Err(::Error::Protocol(ProtocolError {
+                kind: ProtocolErrorKind::DepthLimit,
+                message: format!("cannot parse past {:?}", field_type),
+            }));
+        }
+
+        match field_type {
+            TType::Bool => self.read_bool().map(|_| ()),
+            TType::I08 => self.read_i8().map(|_| ()),
+            TType::I16 => self.read_i16().map(|_| ()),
+            TType::I32 => self.read_i32().map(|_| ()),
+            TType::I64 => self.read_i64().map(|_| ()),
+            TType::Double => self.read_double().map(|_| ()),
+            TType::String => self.read_string().map(|_| ()),
+            TType::Struct => {
+                self.read_struct_begin()?;
+                loop {
+                    let field_ident = self.read_field_begin()?;
+                    if field_ident.field_type == TType::Stop {
+                        break;
+                    }
+                    self.skip_till_depth(field_ident.field_type, depth - 1)?;
+                }
+                self.read_struct_end()
+            }
+            TType::List => {
+                let list_ident = self.read_list_begin()?;
+                for _ in 0..list_ident.size {
+                    self.skip_till_depth(list_ident.element_type, depth - 1)?;
+                }
+                self.read_list_end()
+            }
+            TType::Set => {
+                let set_ident = self.read_set_begin()?;
+                for _ in 0..set_ident.size {
+                    self.skip_till_depth(set_ident.element_type, depth - 1)?;
+                }
+                self.read_set_end()
+            }
+            TType::Map => {
+                let map_ident = self.read_map_begin()?;
+                for _ in 0..map_ident.size {
+                    let key_type = map_ident.key_type
+                        .expect("non-zero sized map should contain key type");
+                    let val_type = map_ident.value_type
+                        .expect("non-zero sized map should contain value type");
+                    self.skip_till_depth(key_type, depth - 1)?;
+                    self.skip_till_depth(val_type, depth - 1)?;
+                }
+                self.read_map_end()
+            }
+            u => {
+                Err(::Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::Unknown,
+                    message: format!("cannot skip field type {:?}", &u),
+                }))
+            }
+        }
+    }
+
+    // utility (DO NOT USE IN GENERATED CODE!!!!)
+    //
+
+    /// Read an unsigned byte.
+    ///
+    /// This method should **never** be used in generated code.
+    fn read_byte(&mut self) -> ::Result<u8>;
+}
+
+/// Converts Thrift identifiers, primitives, containers or structs into a
+/// stream of bytes.
+///
+/// This trait does not deal with higher-level Thrift concepts like structs or
+/// exceptions - only with primitives and message or container boundaries.
+/// Write methods take an identifier (for example, `TMessageIdentifier`) or a
+/// primitive. Any or all of the fields in an identifier may be omitted when
+/// writing to the transport. Write methods may even be noops. All of this is
+/// transparent to the caller; as long as a matching `TInputProtocol`
+/// implementation is used, received messages will be decoded correctly.
+///
+/// All methods return a `thrift::Result`. If an `Err` is returned the protocol
+/// instance and its underlying transport should be terminated.
+///
+/// # Examples
+///
+/// Create and use a `TOutputProtocol`
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryOutputProtocol, TFieldIdentifier, TOutputProtocol, TType};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("127.0.0.1:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut o_prot = TBinaryOutputProtocol::new(transport.clone(), true);
+///
+/// o_prot.write_field_begin(&TFieldIdentifier::new("string_thing", TType::String, 1)).unwrap();
+/// o_prot.write_string("foo").unwrap();
+/// o_prot.write_field_end().unwrap();
+/// ```
+pub trait TOutputProtocol {
+    /// Write the beginning of a Thrift message.
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()>;
+    /// Write the end of a Thrift message.
+    fn write_message_end(&mut self) -> ::Result<()>;
+    /// Write the beginning of a Thrift struct.
+    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> ::Result<()>;
+    /// Write the end of a Thrift struct.
+    fn write_struct_end(&mut self) -> ::Result<()>;
+    /// Write the beginning of a Thrift field.
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()>;
+    /// Write the end of a Thrift field.
+    fn write_field_end(&mut self) -> ::Result<()>;
+    /// Write a STOP field indicating that all the fields in a struct have been
+    /// written.
+    fn write_field_stop(&mut self) -> ::Result<()>;
+    /// Write a bool.
+    fn write_bool(&mut self, b: bool) -> ::Result<()>;
+    /// Write a fixed-length byte array.
+    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()>;
+    /// Write an 8-bit signed integer.
+    fn write_i8(&mut self, i: i8) -> ::Result<()>;
+    /// Write a 16-bit signed integer.
+    fn write_i16(&mut self, i: i16) -> ::Result<()>;
+    /// Write a 32-bit signed integer.
+    fn write_i32(&mut self, i: i32) -> ::Result<()>;
+    /// Write a 64-bit signed integer.
+    fn write_i64(&mut self, i: i64) -> ::Result<()>;
+    /// Write a 64-bit float.
+    fn write_double(&mut self, d: f64) -> ::Result<()>;
+    /// Write a fixed-length string.
+    fn write_string(&mut self, s: &str) -> ::Result<()>;
+    /// Write the beginning of a list.
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()>;
+    /// Write the end of a list.
+    fn write_list_end(&mut self) -> ::Result<()>;
+    /// Write the beginning of a set.
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()>;
+    /// Write the end of a set.
+    fn write_set_end(&mut self) -> ::Result<()>;
+    /// Write the beginning of a map.
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()>;
+    /// Write the end of a map.
+    fn write_map_end(&mut self) -> ::Result<()>;
+    /// Flush buffered bytes to the underlying transport.
+    fn flush(&mut self) -> ::Result<()>;
+
+    // utility (DO NOT USE IN GENERATED CODE!!!!)
+    //
+
+    /// Write an unsigned byte.
+    ///
+    /// This method should **never** be used in generated code.
+    fn write_byte(&mut self, b: u8) -> ::Result<()>; // FIXME: REMOVE
+}
+
+/// Helper type used by servers to create `TInputProtocol` instances for
+/// accepted client connections.
+///
+/// # Examples
+///
+/// Create a `TInputProtocolFactory` and use it to create a `TInputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryInputProtocolFactory, TInputProtocolFactory};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("127.0.0.1:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut i_proto_factory = TBinaryInputProtocolFactory::new();
+/// let i_prot = i_proto_factory.create(transport);
+/// ```
+pub trait TInputProtocolFactory {
+    /// Create a `TInputProtocol` that reads bytes from `transport`.
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TInputProtocol>;
+}
+
+/// Helper type used by servers to create `TOutputProtocol` instances for
+/// accepted client connections.
+///
+/// # Examples
+///
+/// Create a `TOutputProtocolFactory` and use it to create a `TOutputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TBinaryOutputProtocolFactory, TOutputProtocolFactory};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("127.0.0.1:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let mut o_proto_factory = TBinaryOutputProtocolFactory::new();
+/// let o_prot = o_proto_factory.create(transport);
+/// ```
+pub trait TOutputProtocolFactory {
+    /// Create a `TOutputProtocol` that writes bytes to `transport`.
+    fn create(&mut self, transport: Rc<RefCell<Box<TTransport>>>) -> Box<TOutputProtocol>;
+}
+
+/// Thrift message identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TMessageIdentifier {
+    /// Service call the message is associated with.
+    pub name: String,
+    /// Message type.
+    pub message_type: TMessageType,
+    /// Ordered sequence number identifying the message.
+    pub sequence_number: i32,
+}
+
+impl TMessageIdentifier {
+    /// Create a `TMessageIdentifier` for a Thrift service-call named `name`
+    /// with message type `message_type` and sequence number `sequence_number`.
+    pub fn new<S: Into<String>>(name: S,
+                                message_type: TMessageType,
+                                sequence_number: i32)
+                                -> TMessageIdentifier {
+        TMessageIdentifier {
+            name: name.into(),
+            message_type: message_type,
+            sequence_number: sequence_number,
+        }
+    }
+}
+
+/// Thrift struct identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TStructIdentifier {
+    /// Name of the encoded Thrift struct.
+    pub name: String,
+}
+
+impl TStructIdentifier {
+    /// Create a `TStructIdentifier` for a struct named `name`.
+    pub fn new<S: Into<String>>(name: S) -> TStructIdentifier {
+        TStructIdentifier { name: name.into() }
+    }
+}
+
+/// Thrift field identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TFieldIdentifier {
+    /// Name of the Thrift field.
+    ///
+    /// `None` if it's not sent over the wire.
+    pub name: Option<String>,
+    /// Field type.
+    ///
+    /// This may be a primitive, container, or a struct.
+    pub field_type: TType,
+    /// Thrift field id.
+    ///
+    /// `None` only if `field_type` is `TType::Stop`.
+    pub id: Option<i16>,
+}
+
+impl TFieldIdentifier {
+    /// Create a `TFieldIdentifier` for a field named `name` with type
+    /// `field_type` and field id `id`.
+    ///
+    /// `id` should be `None` if `field_type` is `TType::Stop`.
+    pub fn new<N, S, I>(name: N, field_type: TType, id: I) -> TFieldIdentifier
+        where N: Into<Option<S>>,
+              S: Into<String>,
+              I: Into<Option<i16>>
+    {
+        TFieldIdentifier {
+            name: name.into().map(|n| n.into()),
+            field_type: field_type,
+            id: id.into(),
+        }
+    }
+}
+
+/// Thrift list identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TListIdentifier {
+    /// Type of the elements in the list.
+    pub element_type: TType,
+    /// Number of elements in the list.
+    pub size: i32,
+}
+
+impl TListIdentifier {
+    /// Create a `TListIdentifier` for a list with `size` elements of type
+    /// `element_type`.
+    pub fn new(element_type: TType, size: i32) -> TListIdentifier {
+        TListIdentifier {
+            element_type: element_type,
+            size: size,
+        }
+    }
+}
+
+/// Thrift set identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TSetIdentifier {
+    /// Type of the elements in the set.
+    pub element_type: TType,
+    /// Number of elements in the set.
+    pub size: i32,
+}
+
+impl TSetIdentifier {
+    /// Create a `TSetIdentifier` for a set with `size` elements of type
+    /// `element_type`.
+    pub fn new(element_type: TType, size: i32) -> TSetIdentifier {
+        TSetIdentifier {
+            element_type: element_type,
+            size: size,
+        }
+    }
+}
+
+/// Thrift map identifier.
+#[derive(Clone, Debug, Eq, PartialEq)]
+pub struct TMapIdentifier {
+    /// Map key type.
+    pub key_type: Option<TType>,
+    /// Map value type.
+    pub value_type: Option<TType>,
+    /// Number of entries in the map.
+    pub size: i32,
+}
+
+impl TMapIdentifier {
+    /// Create a `TMapIdentifier` for a map with `size` entries of type
+    /// `key_type -> value_type`.
+    pub fn new<K, V>(key_type: K, value_type: V, size: i32) -> TMapIdentifier
+        where K: Into<Option<TType>>,
+              V: Into<Option<TType>>
+    {
+        TMapIdentifier {
+            key_type: key_type.into(),
+            value_type: value_type.into(),
+            size: size,
+        }
+    }
+}
+
+/// Thrift message types.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum TMessageType {
+    /// Service-call request.
+    Call,
+    /// Service-call response.
+    Reply,
+    /// Unexpected error in the remote service.
+    Exception,
+    /// One-way service-call request (no response is expected).
+    OneWay,
+}
+
+impl Display for TMessageType {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        match *self {
+            TMessageType::Call => write!(f, "Call"),
+            TMessageType::Reply => write!(f, "Reply"),
+            TMessageType::Exception => write!(f, "Exception"),
+            TMessageType::OneWay => write!(f, "OneWay"),
+        }
+    }
+}
+
+impl From<TMessageType> for u8 {
+    fn from(message_type: TMessageType) -> Self {
+        match message_type {
+            TMessageType::Call => 0x01,
+            TMessageType::Reply => 0x02,
+            TMessageType::Exception => 0x03,
+            TMessageType::OneWay => 0x04,
+        }
+    }
+}
+
+impl TryFrom<u8> for TMessageType {
+    type Err = ::Error;
+    fn try_from(b: u8) -> ::Result<Self> {
+        match b {
+            0x01 => Ok(TMessageType::Call),
+            0x02 => Ok(TMessageType::Reply),
+            0x03 => Ok(TMessageType::Exception),
+            0x04 => Ok(TMessageType::OneWay),
+            unkn => {
+                Err(::Error::Protocol(ProtocolError {
+                    kind: ProtocolErrorKind::InvalidData,
+                    message: format!("cannot convert {} to TMessageType", unkn),
+                }))
+            }
+        }
+    }
+}
+
+/// Thrift struct-field types.
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub enum TType {
+    /// Indicates that there are no more serialized fields in this Thrift struct.
+    Stop,
+    /// Void (`()`) field.
+    Void,
+    /// Boolean.
+    Bool,
+    /// Signed 8-bit int.
+    I08,
+    /// Double-precision number.
+    Double,
+    /// Signed 16-bit int.
+    I16,
+    /// Signed 32-bit int.
+    I32,
+    /// Signed 64-bit int.
+    I64,
+    /// UTF-8 string.
+    String,
+    /// UTF-7 string. *Unsupported*.
+    Utf7,
+    /// Thrift struct.
+    Struct,
+    /// Map.
+    Map,
+    /// Set.
+    Set,
+    /// List.
+    List,
+    /// UTF-8 string.
+    Utf8,
+    /// UTF-16 string. *Unsupported*.
+    Utf16,
+}
+
+impl Display for TType {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+        match *self {
+            TType::Stop => write!(f, "STOP"),
+            TType::Void => write!(f, "void"),
+            TType::Bool => write!(f, "bool"),
+            TType::I08 => write!(f, "i08"),
+            TType::Double => write!(f, "double"),
+            TType::I16 => write!(f, "i16"),
+            TType::I32 => write!(f, "i32"),
+            TType::I64 => write!(f, "i64"),
+            TType::String => write!(f, "string"),
+            TType::Utf7 => write!(f, "UTF7"),
+            TType::Struct => write!(f, "struct"),
+            TType::Map => write!(f, "map"),
+            TType::Set => write!(f, "set"),
+            TType::List => write!(f, "list"),
+            TType::Utf8 => write!(f, "UTF8"),
+            TType::Utf16 => write!(f, "UTF16"),
+        }
+    }
+}
+
+/// Compare the expected message sequence number `expected` with the received
+/// message sequence number `actual`.
+///
+/// Return `()` if `actual == expected`, `Err` otherwise.
+pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> ::Result<()> {
+    if expected == actual {
+        Ok(())
+    } else {
+        Err(::Error::Application(::ApplicationError {
+            kind: ::ApplicationErrorKind::BadSequenceId,
+            message: format!("expected {} got {}", expected, actual),
+        }))
+    }
+}
+
+/// Compare the expected service-call name `expected` with the received
+/// service-call name `actual`.
+///
+/// Return `()` if `actual == expected`, `Err` otherwise.
+pub fn verify_expected_service_call(expected: &str, actual: &str) -> ::Result<()> {
+    if expected == actual {
+        Ok(())
+    } else {
+        Err(::Error::Application(::ApplicationError {
+            kind: ::ApplicationErrorKind::WrongMethodName,
+            message: format!("expected {} got {}", expected, actual),
+        }))
+    }
+}
+
+/// Compare the expected message type `expected` with the received message type
+/// `actual`.
+///
+/// Return `()` if `actual == expected`, `Err` otherwise.
+pub fn verify_expected_message_type(expected: TMessageType, actual: TMessageType) -> ::Result<()> {
+    if expected == actual {
+        Ok(())
+    } else {
+        Err(::Error::Application(::ApplicationError {
+            kind: ::ApplicationErrorKind::InvalidMessageType,
+            message: format!("expected {} got {}", expected, actual),
+        }))
+    }
+}
+
+/// Check if a required Thrift struct field exists.
+///
+/// Return `()` if it does, `Err` otherwise.
+pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> ::Result<()> {
+    match *field {
+        Some(_) => Ok(()),
+        None => {
+            Err(::Error::Protocol(::ProtocolError {
+                kind: ::ProtocolErrorKind::Unknown,
+                message: format!("missing required field {}", field_name),
+            }))
+        }
+    }
+}
+
+/// Extract the field id from a Thrift field identifier.
+///
+/// `field_ident` must *not* have `TFieldIdentifier.field_type` of type `TType::Stop`.
+///
+/// Return `TFieldIdentifier.id` if an id exists, `Err` otherwise.
+pub fn field_id(field_ident: &TFieldIdentifier) -> ::Result<i16> {
+    field_ident.id.ok_or_else(|| {
+        ::Error::Protocol(::ProtocolError {
+            kind: ::ProtocolErrorKind::Unknown,
+            message: format!("missing field in in {:?}", field_ident),
+        })
+    })
+}
diff --git a/lib/rs/src/protocol/multiplexed.rs b/lib/rs/src/protocol/multiplexed.rs
new file mode 100644
index 0000000..15fe608
--- /dev/null
+++ b/lib/rs/src/protocol/multiplexed.rs
@@ -0,0 +1,219 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TMessageType,
+            TOutputProtocol, TSetIdentifier, TStructIdentifier};
+
+/// `TOutputProtocol` that prefixes the service name to all outgoing Thrift
+/// messages.
+///
+/// A `TMultiplexedOutputProtocol` should be used when multiple Thrift services
+/// send messages over a single I/O channel. By prefixing service identifiers
+/// to outgoing messages receivers are able to demux them and route them to the
+/// appropriate service processor. Rust receivers must use a `TMultiplexedProcessor`
+/// to process incoming messages, while other languages must use their
+/// corresponding multiplexed processor implementations.
+///
+/// For example, given a service `TestService` and a service call `test_call`,
+/// this implementation would identify messages as originating from
+/// `TestService:test_call`.
+///
+/// # Examples
+///
+/// Create and use a `TMultiplexedOutputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift::protocol::{TMessageIdentifier, TMessageType, TOutputProtocol};
+/// use thrift::protocol::{TBinaryOutputProtocol, TMultiplexedOutputProtocol};
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// let o_prot = TBinaryOutputProtocol::new(transport, true);
+/// let mut o_prot = TMultiplexedOutputProtocol::new("service_name", Box::new(o_prot));
+///
+/// let ident = TMessageIdentifier::new("svc_call", TMessageType::Call, 1);
+/// o_prot.write_message_begin(&ident).unwrap();
+/// ```
+pub struct TMultiplexedOutputProtocol {
+    service_name: String,
+    inner: Box<TOutputProtocol>,
+}
+
+impl TMultiplexedOutputProtocol {
+    /// Create a `TMultiplexedOutputProtocol` that identifies outgoing messages
+    /// as originating from a service named `service_name` and sends them over
+    /// the `wrapped` `TOutputProtocol`. Outgoing messages are encoded and sent
+    /// by `wrapped`, not by this instance.
+    pub fn new(service_name: &str, wrapped: Box<TOutputProtocol>) -> TMultiplexedOutputProtocol {
+        TMultiplexedOutputProtocol {
+            service_name: service_name.to_owned(),
+            inner: wrapped,
+        }
+    }
+}
+
+// FIXME: avoid passthrough methods
+impl TOutputProtocol for TMultiplexedOutputProtocol {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+        match identifier.message_type { // FIXME: is there a better way to override identifier here?
+            TMessageType::Call | TMessageType::OneWay => {
+                let identifier = TMessageIdentifier {
+                    name: format!("{}:{}", self.service_name, identifier.name),
+                    ..*identifier
+                };
+                self.inner.write_message_begin(&identifier)
+            }
+            _ => self.inner.write_message_begin(identifier),
+        }
+    }
+
+    fn write_message_end(&mut self) -> ::Result<()> {
+        self.inner.write_message_end()
+    }
+
+    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> ::Result<()> {
+        self.inner.write_struct_begin(identifier)
+    }
+
+    fn write_struct_end(&mut self) -> ::Result<()> {
+        self.inner.write_struct_end()
+    }
+
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+        self.inner.write_field_begin(identifier)
+    }
+
+    fn write_field_end(&mut self) -> ::Result<()> {
+        self.inner.write_field_end()
+    }
+
+    fn write_field_stop(&mut self) -> ::Result<()> {
+        self.inner.write_field_stop()
+    }
+
+    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+        self.inner.write_bytes(b)
+    }
+
+    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+        self.inner.write_bool(b)
+    }
+
+    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+        self.inner.write_i8(i)
+    }
+
+    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+        self.inner.write_i16(i)
+    }
+
+    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+        self.inner.write_i32(i)
+    }
+
+    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+        self.inner.write_i64(i)
+    }
+
+    fn write_double(&mut self, d: f64) -> ::Result<()> {
+        self.inner.write_double(d)
+    }
+
+    fn write_string(&mut self, s: &str) -> ::Result<()> {
+        self.inner.write_string(s)
+    }
+
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+        self.inner.write_list_begin(identifier)
+    }
+
+    fn write_list_end(&mut self) -> ::Result<()> {
+        self.inner.write_list_end()
+    }
+
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+        self.inner.write_set_begin(identifier)
+    }
+
+    fn write_set_end(&mut self) -> ::Result<()> {
+        self.inner.write_set_end()
+    }
+
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+        self.inner.write_map_begin(identifier)
+    }
+
+    fn write_map_end(&mut self) -> ::Result<()> {
+        self.inner.write_map_end()
+    }
+
+    fn flush(&mut self) -> ::Result<()> {
+        self.inner.flush()
+    }
+
+    // utility
+    //
+
+    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+        self.inner.write_byte(b)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    use std::cell::RefCell;
+    use std::rc::Rc;
+
+    use ::protocol::{TBinaryOutputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
+    use ::transport::{TPassThruTransport, TTransport};
+    use ::transport::mem::TBufferTransport;
+
+    use super::*;
+
+    #[test]
+    fn must_write_message_begin_with_prefixed_service_name() {
+        let (trans, mut o_prot) = test_objects();
+
+        let ident = TMessageIdentifier::new("bar", TMessageType::Call, 2);
+        assert_success!(o_prot.write_message_begin(&ident));
+
+        let expected: [u8; 19] =
+            [0x80, 0x01 /* protocol identifier */, 0x00, 0x01 /* message type */, 0x00,
+             0x00, 0x00, 0x07, 0x66, 0x6F, 0x6F /* "foo" */, 0x3A /* ":" */, 0x62, 0x61,
+             0x72 /* "bar" */, 0x00, 0x00, 0x00, 0x02 /* sequence number */];
+
+        assert_eq!(&trans.borrow().write_buffer_to_vec(), &expected);
+    }
+
+    fn test_objects() -> (Rc<RefCell<Box<TBufferTransport>>>, TMultiplexedOutputProtocol) {
+        let mem = Rc::new(RefCell::new(Box::new(TBufferTransport::with_capacity(40, 40))));
+
+        let inner: Box<TTransport> = Box::new(TPassThruTransport { inner: mem.clone() });
+        let inner = Rc::new(RefCell::new(inner));
+
+        let o_prot = TBinaryOutputProtocol::new(inner.clone(), true);
+        let o_prot = TMultiplexedOutputProtocol::new("foo", Box::new(o_prot));
+
+        (mem, o_prot)
+    }
+}
diff --git a/lib/rs/src/protocol/stored.rs b/lib/rs/src/protocol/stored.rs
new file mode 100644
index 0000000..6826c00
--- /dev/null
+++ b/lib/rs/src/protocol/stored.rs
@@ -0,0 +1,191 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::convert::Into;
+
+use ::ProtocolErrorKind;
+use super::{TFieldIdentifier, TListIdentifier, TMapIdentifier, TMessageIdentifier, TInputProtocol,
+            TSetIdentifier, TStructIdentifier};
+
+/// `TInputProtocol` required to use a `TMultiplexedProcessor`.
+///
+/// A `TMultiplexedProcessor` reads incoming message identifiers to determine to
+/// which `TProcessor` requests should be forwarded. However, once read, those
+/// message identifier bytes are no longer on the wire. Since downstream
+/// processors expect to read message identifiers from the given input protocol
+/// we need some way of supplying a `TMessageIdentifier` with the service-name
+/// stripped. This implementation stores the received `TMessageIdentifier`
+/// (without the service name) and passes it to the wrapped `TInputProtocol`
+/// when `TInputProtocol::read_message_begin(...)` is called. It delegates all
+/// other calls directly to the wrapped `TInputProtocol`.
+///
+/// This type **should not** be used by application code.
+///
+/// # Examples
+///
+/// Create and use a `TStoredInputProtocol`.
+///
+/// ```no_run
+/// use std::cell::RefCell;
+/// use std::rc::Rc;
+/// use thrift;
+/// use thrift::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
+/// use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TStoredInputProtocol};
+/// use thrift::server::TProcessor;
+/// use thrift::transport::{TTcpTransport, TTransport};
+///
+/// // sample processor
+/// struct ActualProcessor;
+/// impl TProcessor for ActualProcessor {
+///     fn process(
+///         &mut self,
+///         _: &mut TInputProtocol,
+///         _: &mut TOutputProtocol
+///     ) -> thrift::Result<()> {
+///         unimplemented!()
+///     }
+/// }
+/// let mut processor = ActualProcessor {};
+///
+/// // construct the shared transport
+/// let mut transport = TTcpTransport::new();
+/// transport.open("localhost:9090").unwrap();
+/// let transport = Rc::new(RefCell::new(Box::new(transport) as Box<TTransport>));
+///
+/// // construct the actual input and output protocols
+/// let mut i_prot = TBinaryInputProtocol::new(transport.clone(), true);
+/// let mut o_prot = TBinaryOutputProtocol::new(transport.clone(), true);
+///
+/// // message identifier received from remote and modified to remove the service name
+/// let new_msg_ident = TMessageIdentifier::new("service_call", TMessageType::Call, 1);
+///
+/// // construct the proxy input protocol
+/// let mut proxy_i_prot = TStoredInputProtocol::new(&mut i_prot, new_msg_ident);
+/// let res = processor.process(&mut proxy_i_prot, &mut o_prot);
+/// ```
+pub struct TStoredInputProtocol<'a> {
+    inner: &'a mut TInputProtocol,
+    message_ident: Option<TMessageIdentifier>,
+}
+
+impl<'a> TStoredInputProtocol<'a> {
+    /// Create a `TStoredInputProtocol` that delegates all calls other than
+    /// `TInputProtocol::read_message_begin(...)` to a `wrapped`
+    /// `TInputProtocol`. `message_ident` is the modified message identifier -
+    /// with service name stripped - that will be passed to
+    /// `wrapped.read_message_begin(...)`.
+    pub fn new(wrapped: &mut TInputProtocol,
+               message_ident: TMessageIdentifier)
+               -> TStoredInputProtocol {
+        TStoredInputProtocol {
+            inner: wrapped,
+            message_ident: message_ident.into(),
+        }
+    }
+}
+
+impl<'a> TInputProtocol for TStoredInputProtocol<'a> {
+    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+        self.message_ident.take().ok_or_else(|| {
+            ::errors::new_protocol_error(ProtocolErrorKind::Unknown,
+                                         "message identifier already read")
+        })
+    }
+
+    fn read_message_end(&mut self) -> ::Result<()> {
+        self.inner.read_message_end()
+    }
+
+    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+        self.inner.read_struct_begin()
+    }
+
+    fn read_struct_end(&mut self) -> ::Result<()> {
+        self.inner.read_struct_end()
+    }
+
+    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+        self.inner.read_field_begin()
+    }
+
+    fn read_field_end(&mut self) -> ::Result<()> {
+        self.inner.read_field_end()
+    }
+
+    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+        self.inner.read_bytes()
+    }
+
+    fn read_bool(&mut self) -> ::Result<bool> {
+        self.inner.read_bool()
+    }
+
+    fn read_i8(&mut self) -> ::Result<i8> {
+        self.inner.read_i8()
+    }
+
+    fn read_i16(&mut self) -> ::Result<i16> {
+        self.inner.read_i16()
+    }
+
+    fn read_i32(&mut self) -> ::Result<i32> {
+        self.inner.read_i32()
+    }
+
+    fn read_i64(&mut self) -> ::Result<i64> {
+        self.inner.read_i64()
+    }
+
+    fn read_double(&mut self) -> ::Result<f64> {
+        self.inner.read_double()
+    }
+
+    fn read_string(&mut self) -> ::Result<String> {
+        self.inner.read_string()
+    }
+
+    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+        self.inner.read_list_begin()
+    }
+
+    fn read_list_end(&mut self) -> ::Result<()> {
+        self.inner.read_list_end()
+    }
+
+    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+        self.inner.read_set_begin()
+    }
+
+    fn read_set_end(&mut self) -> ::Result<()> {
+        self.inner.read_set_end()
+    }
+
+    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+        self.inner.read_map_begin()
+    }
+
+    fn read_map_end(&mut self) -> ::Result<()> {
+        self.inner.read_map_end()
+    }
+
+    // utility
+    //
+
+    fn read_byte(&mut self) -> ::Result<u8> {
+        self.inner.read_byte()
+    }
+}
