Merge pull request #2221 from zeshuai007/THRIFT-5249

THRIFT-5249 Fix Failed to run FastbinaryTest.py
diff --git a/CHANGES.md b/CHANGES.md
index be0286a..65ed07f 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -16,6 +16,7 @@
 - [THRIFT-5186](https://issues.apache.org/jira/browse/THRIFT-5186) - cpp: use all getaddrinfo() results when retrying failed bind() in T{Nonblocking,}ServerSocket
 - [THRIFT-5233](https://issues.apache.org/jira/browse/THRIFT-5233) - go: Now all Read*, Write* and Skip functions in TProtocol accept context arg
 - [THRIFT-5152](https://issues.apache.org/jira/browse/THRIFT-5152) - go: TSocket and TSSLSocket now have separated connect timeout and socket timeout
+- c++: dropped support for Windows XP
 
 ### Java
 
diff --git a/build/appveyor/CYGW-appveyor-install.bat b/build/appveyor/CYGW-appveyor-install.bat
index 72712b2..69a159f 100644
--- a/build/appveyor/CYGW-appveyor-install.bat
+++ b/build/appveyor/CYGW-appveyor-install.bat
@@ -47,4 +47,4 @@
 ::
 
 %BASH% -lc "apt-cyg remove cmake"
-%BASH% -lc "cd / && wget http://mirror.clarkson.edu/cygwin/x86_64/release/cmake/cmake-3.13.1-1.tar.xz && tar xJf cmake-3.13.1-1.tar.xz && hash -r && cmake --version"
+%BASH% -lc "cd / && wget http://mirror.clarkson.edu/cygwin/x86_64/release/cmake/cmake-3.14.5-1.tar.xz && tar xJf cmake-3.14.5-1.tar.xz && hash -r && cmake --version"
diff --git a/build/docker/README.md b/build/docker/README.md
index 6f170e1..e3c2ec1 100644
--- a/build/docker/README.md
+++ b/build/docker/README.md
@@ -192,6 +192,6 @@
 | python    | 2.7.12        | 2.7.15        |       |
 | python3   | 3.5.2         | 3.6.8         |       |
 | ruby      | 2.3.1p112     | 2.5.1p57      |       |
-| rust      | 1.34.0        | 1.35.0        |       |
+| rust      | 1.40.0        | 1.40.0        |       |
 | smalltalk |               |               | Not in CI |
 | swift     |               | 5.1.4         |       |
diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile
index c22a859..7deefcb 100644
--- a/build/docker/ubuntu-bionic/Dockerfile
+++ b/build/docker/ubuntu-bionic/Dockerfile
@@ -23,7 +23,7 @@
 
 RUN apt-get update && \
     apt-get dist-upgrade -y && \
-    apt-get install -y --no-install-recommends \
+    apt-get install -y --no-install-recommends --fix-missing \
       apt \
       apt-transport-https \
       apt-utils \
@@ -247,7 +247,7 @@
       ruby-bundler
 
 # Rust dependencies
-RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.36.0 -y
+RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.40.0 -y
 ENV PATH /root/.cargo/bin:$PATH
 
 # Swift on Linux for cross tests
diff --git a/build/docker/ubuntu-disco/Dockerfile b/build/docker/ubuntu-disco/Dockerfile
index 247bcf1..cfa4041 100644
--- a/build/docker/ubuntu-disco/Dockerfile
+++ b/build/docker/ubuntu-disco/Dockerfile
@@ -248,7 +248,7 @@
       ruby-bundler
 
 # Rust dependencies
-RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.35.0 -y
+RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.40.0 -y
 ENV PATH /root/.cargo/bin:$PATH
 
 # Swift on Linux for cross tests
diff --git a/build/docker/ubuntu-xenial/Dockerfile b/build/docker/ubuntu-xenial/Dockerfile
index 315b298..535db41 100644
--- a/build/docker/ubuntu-xenial/Dockerfile
+++ b/build/docker/ubuntu-xenial/Dockerfile
@@ -253,7 +253,7 @@
       ruby-bundler
 
 # Rust dependencies
-RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.34.0 -y
+RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.40.0 -y
 
 # Clean up
 RUN rm -rf /var/cache/apt/* && \
diff --git a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
index 2a92183..8cb82c1 100644
--- a/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_c_glib_generator.cc
@@ -2371,48 +2371,6 @@
         }
         f_service_ << "return_value, "
                    << "NULL);" << endl;
-
-        // Deallocate (or unref) return_value
-        return_type = get_true_type(return_type);
-        if (return_type->is_base_type()) {
-          t_base_type* base_type = ((t_base_type*)return_type);
-
-          if (base_type->get_base() == t_base_type::TYPE_STRING) {
-            f_service_ << indent() << "if (return_value != NULL)" << endl;
-            indent_up();
-            if (base_type->is_binary()) {
-              f_service_ << indent() << "g_byte_array_unref (return_value);" << endl;
-            } else {
-              f_service_ << indent() << "g_free (return_value);" << endl;
-            }
-            indent_down();
-          }
-        } else if (return_type->is_container()) {
-          f_service_ << indent() << "if (return_value != NULL)" << endl;
-          indent_up();
-
-          if (return_type->is_list()) {
-            t_type* elem_type = ((t_list*)return_type)->get_elem_type();
-
-            f_service_ << indent();
-            if (is_numeric(elem_type)) {
-              f_service_ << "g_array_unref";
-            } else {
-              f_service_ << "g_ptr_array_unref";
-            }
-            f_service_ << " (return_value);" << endl;
-          } else if (return_type->is_map() || return_type->is_set()) {
-            f_service_ << indent() << "g_hash_table_unref (return_value);" << endl;
-          }
-
-          indent_down();
-        } else if (return_type->is_struct()) {
-          f_service_ << indent() << "if (return_value != NULL)" << endl;
-          indent_up();
-          f_service_ << indent() << "g_object_unref (return_value);" << endl;
-          indent_down();
-        }
-
         f_service_ << endl;
       }
       f_service_ << indent() << "result =" << endl;
@@ -2551,6 +2509,47 @@
     }
 
     if (!(*function_iter)->is_oneway()) {
+      if (has_return_value) {
+        // Deallocate (or unref) return_value
+        return_type = get_true_type(return_type);
+        if (return_type->is_base_type()) {
+          t_base_type* base_type = ((t_base_type*)return_type);
+            if (base_type->get_base() == t_base_type::TYPE_STRING) {
+            f_service_ << indent() << "if (return_value != NULL)" << endl;
+            indent_up();
+            if (base_type->is_binary()) {
+              f_service_ << indent() << "g_byte_array_unref (return_value);" << endl;
+            } else {
+              f_service_ << indent() << "g_free (return_value);" << endl;
+            }
+            indent_down();
+          }
+        } else if (return_type->is_container()) {
+          f_service_ << indent() << "if (return_value != NULL)" << endl;
+          indent_up();
+
+          if (return_type->is_list()) {
+            t_type* elem_type = ((t_list*)return_type)->get_elem_type();
+
+            f_service_ << indent();
+            if (is_numeric(elem_type)) {
+              f_service_ << "g_array_unref";
+            } else {
+              f_service_ << "g_ptr_array_unref";
+            }
+            f_service_ << " (return_value);" << endl;
+          } else if (return_type->is_map() || return_type->is_set()) {
+            f_service_ << indent() << "g_hash_table_unref (return_value);" << endl;
+          }
+
+          indent_down();
+        } else if (return_type->is_struct()) {
+          f_service_ << indent() << "if (return_value != NULL)" << endl;
+          indent_up();
+          f_service_ << indent() << "g_object_unref (return_value);" << endl;
+          indent_down();
+        }
+      }
       f_service_ << indent() << "g_object_unref (result_struct);" << endl << endl << indent()
                  << "if (result == TRUE)" << endl;
       indent_up();
diff --git a/compiler/cpp/src/thrift/generate/t_java_generator.cc b/compiler/cpp/src/thrift/generate/t_java_generator.cc
index 8778702..ef35f76 100644
--- a/compiler/cpp/src/thrift/generate/t_java_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_java_generator.cc
@@ -2526,7 +2526,7 @@
       }else{
         indent(out) << " : java.nio.ByteBuffer.wrap(" << field_name << ".clone());" << endl;
       }
-                 
+
       if (!bean_style_) {
         indent(out) << "  return this;" << endl;
       }
@@ -3861,19 +3861,18 @@
     // Declare variables, read header
     if (ttype->is_map()) {
       indent(out) << "org.apache.thrift.protocol.TMap " << obj
-                  << " = new org.apache.thrift.protocol.TMap("
+                  << " = iprot.readMapBegin("
                   << type_to_enum(((t_map*)ttype)->get_key_type()) << ", "
-                  << type_to_enum(((t_map*)ttype)->get_val_type()) << ", "
-                  << "iprot.readI32());" << endl;
+                  << type_to_enum(((t_map*)ttype)->get_val_type()) << "); "<< endl;
     } else if (ttype->is_set()) {
       indent(out) << "org.apache.thrift.protocol.TSet " << obj
-                  << " = new org.apache.thrift.protocol.TSet("
-                  << type_to_enum(((t_set*)ttype)->get_elem_type()) << ", iprot.readI32());"
+                  << " = iprot.readSetBegin("
+                  << type_to_enum(((t_set*)ttype)->get_elem_type()) << ");"
                   << endl;
     } else if (ttype->is_list()) {
       indent(out) << "org.apache.thrift.protocol.TList " << obj
-                  << " = new org.apache.thrift.protocol.TList("
-                  << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", iprot.readI32());"
+                  << " = iprot.readListBegin("
+                  << type_to_enum(((t_list*)ttype)->get_elem_type()) << ");"
                   << endl;
     }
   }
diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
index b63569d..17dbac7 100644
--- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
@@ -659,7 +659,9 @@
 
   indent(out) << "local name, mtype, seqid = iprot:readMessageBegin()" << endl;
   indent(out) << "local func_name = 'process_' .. name" << endl;
-  indent(out) << "if not self[func_name] or ttype(self[func_name]) ~= 'function' then";
+  indent(out) << "if not self[func_name] or ttype(self[func_name]) ~= 'function' then" << endl;
+  indent_up();
+  indent(out) << "if oprot ~= nil then";
   indent_up();
   out << endl << indent() << "iprot:skip(TType.STRUCT)" << endl << indent()
       << "iprot:readMessageEnd()" << endl << indent() << "x = TApplicationException:new{" << endl
@@ -668,8 +670,11 @@
       << "seqid)" << endl << indent() << "x:write(oprot)" << endl << indent()
       << "oprot:writeMessageEnd()" << endl << indent() << "oprot.trans:flush()" << endl;
   indent_down();
+  out << indent() << "end" << endl << indent()
+      << "return false, 'Unknown function '..name" << endl;
+  indent_down();
   indent(out) << "else" << endl << indent()
-              << "  self[func_name](self, seqid, iprot, oprot, server_ctx)" << endl << indent()
+              << "  return self[func_name](self, seqid, iprot, oprot, server_ctx)" << endl << indent()
               << "end" << endl;
 
   indent_down();
@@ -698,37 +703,45 @@
   // Read the request
   out << indent() << "local args = " << argsname << ":new{}" << endl << indent()
       << "local reply_type = TMessageType.REPLY" << endl << indent() << "args:read(iprot)" << endl
-      << indent() << "iprot:readMessageEnd()" << endl << indent() << "local result = " << resultname
-      << ":new{}" << endl << indent() << "local status, res = pcall(self.handler." << fn_name
-      << ", self.handler";
+      << indent() << "iprot:readMessageEnd()" << endl;
 
+  if (!tfunction->is_oneway()) {
+      out << indent() << "local result = " << resultname
+          << ":new{}" << endl;
+  }
+
+  out <<  indent() << "local status, res = pcall(self.handler." << fn_name
+      << ", self.handler";
   // Print arguments
   t_struct* args = tfunction->get_arglist();
   if (args->get_members().size() > 0) {
     out << ", " << argument_list(args, "args.");
   }
+  out << ")" << endl;
 
-  // Check for errors
-  out << ")" << endl << indent() << "if not status then" << endl << indent()
-      << "  reply_type = TMessageType.EXCEPTION" << endl << indent()
-      << "  result = TApplicationException:new{message = res}" << endl;
+  if (!tfunction->is_oneway()) {
+      // Check for errors
+      out << indent() << "if not status then" << endl << indent()
+          << "  reply_type = TMessageType.EXCEPTION" << endl << indent()
+          << "  result = TApplicationException:new{message = res}" << endl;
 
-  // Handle custom exceptions
-  const std::vector<t_field*>& xf = tfunction->get_xceptions()->get_members();
-  if (xf.size() > 0) {
-    vector<t_field*>::const_iterator x_iter;
-    for (x_iter = xf.begin(); x_iter != xf.end(); ++x_iter) {
-      out << indent() << "elseif ttype(res) == '" << (*x_iter)->get_type()->get_name() << "' then"
-          << endl << indent() << "  result." << (*x_iter)->get_name() << " = res" << endl;
-    }
+      // Handle custom exceptions
+      const std::vector<t_field*>& xf = tfunction->get_xceptions()->get_members();
+      if (xf.size() > 0) {
+          vector<t_field*>::const_iterator x_iter;
+          for (x_iter = xf.begin(); x_iter != xf.end(); ++x_iter) {
+              out << indent() << "elseif ttype(res) == '" << (*x_iter)->get_type()->get_name() << "' then"
+                  << endl << indent() << "  result." << (*x_iter)->get_name() << " = res" << endl;
+          }
+      }
+
+      // Set the result and write the reply
+      out << indent() << "else" << endl << indent() << "  result.success = res" << endl << indent()
+          << "end" << endl << indent() << "oprot:writeMessageBegin('" << fn_name << "', reply_type, "
+          << "seqid)" << endl << indent() << "result:write(oprot)" << endl << indent()
+          << "oprot:writeMessageEnd()" << endl << indent() << "oprot.trans:flush()" << endl;
   }
-
-  // Set the result and write the reply
-  out << indent() << "else" << endl << indent() << "  result.success = res" << endl << indent()
-      << "end" << endl << indent() << "oprot:writeMessageBegin('" << fn_name << "', reply_type, "
-      << "seqid)" << endl << indent() << "result:write(oprot)" << endl << indent()
-      << "oprot:writeMessageEnd()" << endl << indent() << "oprot.trans:flush()" << endl;
-
+  out << indent() << "return status, res" << endl;
   indent_down();
   indent(out) << "end" << endl;
 }
diff --git a/compiler/cpp/src/thrift/generate/t_py_generator.cc b/compiler/cpp/src/thrift/generate/t_py_generator.cc
index 224ff6a..fe40fc2 100644
--- a/compiler/cpp/src/thrift/generate/t_py_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_py_generator.cc
@@ -1172,7 +1172,7 @@
 
   // Close service file
   f_service_ << "fix_spec(all_structs)" << endl
-             << "del all_structs" << endl << endl;
+             << "del all_structs" << endl;
   f_service_.close();
 }
 
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index bdadf58..4384dfe 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -554,8 +554,6 @@
   f_gen_ << endl;
 
   // add standard includes
-  f_gen_ << "extern crate thrift;" << endl;
-  f_gen_ << endl;
   f_gen_ << "use thrift::OrderedFloat;" << endl;
   f_gen_ << "use std::cell::RefCell;" << endl;
   f_gen_ << "use std::collections::{BTreeMap, BTreeSet};" << endl;
@@ -600,7 +598,7 @@
   if (!referenced_modules.empty()) {
     set<string>::iterator module_iter;
     for (module_iter = referenced_modules.begin(); module_iter != referenced_modules.end(); ++module_iter) {
-      f_gen_ << "use " << rust_snake_case(*module_iter) << ";" << endl;
+      f_gen_ << "use crate::" << rust_snake_case(*module_iter) << ";" << endl;
     }
     f_gen_ << endl;
   }
diff --git a/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c b/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c
index 12a24a7..7a5600c 100644
--- a/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c
+++ b/lib/c_glib/src/thrift/c_glib/processor/thrift_multiplexed_processor.c
@@ -215,13 +215,9 @@
 
   }
 
-  /*
-  FIXME This makes everything fail, I don't know why.
-  if(stored_message_protocol!=NULL){
-	  // After its use we must free it
-	  g_object_unref(stored_message_protocol);
+  if (stored_message_protocol != NULL) {
+      g_object_unref (stored_message_protocol);
   }
-  */
   return retval;
 }
 
diff --git a/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c b/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
index 22aca8a..6f1586f 100644
--- a/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
+++ b/lib/c_glib/src/thrift/c_glib/protocol/thrift_stored_message_protocol.c
@@ -55,7 +55,7 @@
   ThriftStoredMessageProtocol *self = THRIFT_STORED_MESSAGE_PROTOCOL (protocol);
 
   /* We return the stored values on construction */
-  *name = self->name;
+  *name = g_strdup (self->name);
   *message_type = self->mtype;
   *seqid = self->seqid;
 
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h
index 837f467..afb9466 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_buffered_transport.h
@@ -37,7 +37,7 @@
 #define THRIFT_BUFFERED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransport))
 #define THRIFT_IS_BUFFERED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT))
 #define THRIFT_BUFFERED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransportClass))
-#define THRIFT_IS_BUFFERED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_BUFFERED_TRANSPORT)
+#define THRIFT_IS_BUFFERED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_BUFFERED_TRANSPORT))
 #define THRIFT_BUFFERED_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_BUFFERED_TRANSPORT, ThriftBufferedTransportClass))
 
 typedef struct _ThriftBufferedTransport ThriftBufferedTransport;
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c
index 1faf16e..f7b8192 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.c
@@ -98,7 +98,7 @@
     sz = ntohl (sz);
 
     /* create a buffer to hold the data and read that much data */
-    tmpdata = g_alloca (sz);
+    tmpdata = g_new0 (guchar, sz);
     bytes = thrift_transport_read (t->transport, tmpdata, sz, error);
 
     if (bytes > 0 && (error == NULL || *error == NULL))
@@ -108,6 +108,7 @@
 
       result = TRUE;
     }
+    g_free (tmpdata);
   }
 
   return result;
@@ -249,7 +250,7 @@
   sz_nbo = (gint32) htonl ((guint32) t->w_buf->len);
 
   /* copy the size of the frame and then the frame itself */
-  tmpdata = g_alloca (sz_hbo);
+  tmpdata = g_new0 (guchar, sz_hbo);
   memcpy (tmpdata, (guint8 *) &sz_nbo, sizeof (sz_nbo));
 
   if (t->w_buf->len > 0)
@@ -265,7 +266,7 @@
 
   THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush (t->transport,
                                                     error);
-
+  g_free (tmpdata);
   return TRUE;
 }
 
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h
index 95c0123..a102061 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_framed_transport.h
@@ -37,7 +37,7 @@
 #define THRIFT_FRAMED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransport))
 #define THRIFT_IS_FRAMED_TRANSPORT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_FRAMED_TRANSPORT))
 #define THRIFT_FRAMED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransportClass))
-#define THRIFT_IS_FRAMED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_FRAMED_TRANSPORT)
+#define THRIFT_IS_FRAMED_TRANSPORT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_FRAMED_TRANSPORT))
 #define THRIFT_FRAMED_TRANSPORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_FRAMED_TRANSPORT, ThriftFramedTransportClass))
 
 typedef struct _ThriftFramedTransport ThriftFramedTransport;
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h
index d5d47b3..9ddc16c 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_memory_buffer.h
@@ -36,7 +36,7 @@
 #define THRIFT_MEMORY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBuffer))
 #define THRIFT_IS_MEMORY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), THRIFT_TYPE_MEMORY_BUFFER))
 #define THRIFT_MEMORY_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBufferClass))
-#define THRIFT_IS_MEMORY_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MEMORY_BUFFER)
+#define THRIFT_IS_MEMORY_BUFFER_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_MEMORY_BUFFER))
 #define THRIFT_MEMORY_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_MEMORY_BUFFER, ThriftMemoryBufferClass))
 
 typedef struct _ThriftMemoryBuffer ThriftMemoryBuffer;
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h
index c91f52f..912929e 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_socket.h
@@ -68,6 +68,32 @@
 /* used by THRIFT_TYPE_SOCKET */
 GType thrift_socket_get_type (void);
 
+/**
+ * Check if the socket is open and ready to send and receive
+ * @param transport
+ * @return true if open
+ */
+gboolean
+thrift_socket_is_open (ThriftTransport *transport);
+
+/**
+ * Open connection if required and set the socket to be ready to send and receive
+ * @param transport
+ * @param error
+ * @return true if operation was correct
+ */
+gboolean
+thrift_socket_open (ThriftTransport *transport, GError **error);
+
+/**
+ * Close connection if required
+ * @param transport
+ * @param error
+ * @return true if operation was correct
+ */
+gboolean
+thrift_socket_close (ThriftTransport *transport, GError **error);
+
 G_END_DECLS
 
 #endif
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h
index 0ca465a..dd07c63 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_ssl_socket.h
@@ -188,6 +188,15 @@
 gboolean
 thrift_ssl_socket_open (ThriftTransport *transport, GError **error);
 
+/**
+ * Close connection if required
+ * @param transport
+ * @param error
+ * @return true if operation was correct
+ */
+gboolean
+thrift_ssl_socket_close (ThriftTransport *transport, GError **error);
+
 
 /**
  * @brief Initialization function
diff --git a/lib/cpp/src/thrift/transport/PlatformSocket.h b/lib/cpp/src/thrift/transport/PlatformSocket.h
index 9591058..10df944 100644
--- a/lib/cpp/src/thrift/transport/PlatformSocket.h
+++ b/lib/cpp/src/thrift/transport/PlatformSocket.h
@@ -70,16 +70,10 @@
 #  define THRIFT_SLEEP_USEC thrift_usleep
 #  define THRIFT_TIMESPEC thrift_timespec
 #  define THRIFT_CTIME_R thrift_ctime_r
-#  define THRIFT_POLL thrift_poll
-#  if WINVER <= 0x0502 //XP, Server2003
-#    define THRIFT_POLLFD  thrift_pollfd
-#    define THRIFT_POLLIN  0x0300
-#    define THRIFT_POLLOUT 0x0010
-#  else //Vista, Win7...
-#    define THRIFT_POLLFD  pollfd
-#    define THRIFT_POLLIN  POLLIN
-#    define THRIFT_POLLOUT POLLOUT
-#  endif //WINVER
+#  define THRIFT_POLL WSAPoll
+#  define THRIFT_POLLFD  pollfd
+#  define THRIFT_POLLIN  POLLIN
+#  define THRIFT_POLLOUT POLLOUT
 #  define THRIFT_SHUT_RDWR SD_BOTH
 #  if !defined(AI_ADDRCONFIG)
 #    define AI_ADDRCONFIG 0x00000400
diff --git a/lib/cpp/src/thrift/transport/TServerSocket.cpp b/lib/cpp/src/thrift/transport/TServerSocket.cpp
index 6b76525..c917538 100644
--- a/lib/cpp/src/thrift/transport/TServerSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TServerSocket.cpp
@@ -167,7 +167,13 @@
 }
 
 bool TServerSocket::isOpen() const {
-  return (serverSocket_ != THRIFT_INVALID_SOCKET);
+  if (serverSocket_ == THRIFT_INVALID_SOCKET)
+    return false;
+
+  if (!listening_)
+    return false;
+
+  return true;
 }
 
 void TServerSocket::setSendTimeout(int sendTimeout) {
@@ -324,7 +330,6 @@
 }
 
 void TServerSocket::listen() {
-  listening_ = true;
 #ifdef _WIN32
   TWinsockSingleton::create();
 #endif // _WIN32
@@ -538,6 +543,7 @@
   }
 
   // The socket is now listening!
+  listening_ = true;
 }
 
 int TServerSocket::getPort() {
diff --git a/lib/cpp/src/thrift/transport/TSocket.cpp b/lib/cpp/src/thrift/transport/TSocket.cpp
index 81aaccf..5000baf 100644
--- a/lib/cpp/src/thrift/transport/TSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TSocket.cpp
@@ -438,7 +438,7 @@
 
 void TSocket::unix_open() {
   if (!path_.empty()) {
-    // Unix Domain SOcket does not need addrinfo struct, so we pass nullptr
+    // Unix Domain Socket does not need addrinfo struct, so we pass NULL
     openConnection(nullptr);
   }
 }
@@ -711,6 +711,10 @@
   return port_;
 }
 
+std::string TSocket::getPath() {
+    return path_;
+}
+
 void TSocket::setHost(string host) {
   host_ = host;
 }
@@ -719,6 +723,10 @@
   port_ = port;
 }
 
+void TSocket::setPath(std::string path) {
+    path_ = path;
+}
+
 void TSocket::setLinger(bool on, int linger) {
   lingerOn_ = on;
   lingerVal_ = linger;
@@ -828,7 +836,11 @@
       oss << "<Host: " << host_ << " Port: " << port_ << ">";
     }
   } else {
-    oss << "<Path: " << path_ << ">";
+    std::string fmt_path_ = path_;
+    // Handle printing abstract sockets (first character is a '\0' char):
+    if (!fmt_path_.empty() && fmt_path_[0] == '\0')
+      fmt_path_[0] = '@';
+    oss << "<Path: " << fmt_path_ << ">";
   }
   return oss.str();
 }
diff --git a/lib/cpp/src/thrift/transport/TSocket.h b/lib/cpp/src/thrift/transport/TSocket.h
index 043f0de..8a224f2 100644
--- a/lib/cpp/src/thrift/transport/TSocket.h
+++ b/lib/cpp/src/thrift/transport/TSocket.h
@@ -68,6 +68,7 @@
    * Note that this does NOT actually connect the socket.
    *
    * @param path The Unix domain socket e.g. "/tmp/ThriftTest.binary.thrift"
+   * or a zero-prefixed string to create an abstract domain socket on Linux.
    */
   TSocket(const std::string& path, std::shared_ptr<TConfiguration> config = nullptr);
 
@@ -150,6 +151,13 @@
   int getPort();
 
   /**
+   * Get the Unix domain socket path that the socket is connected to
+   *
+   * @return std::string path
+   */
+  std::string getPath();
+
+  /**
    * Set the host that socket will connect to
    *
    * @param host host identifier
@@ -164,6 +172,13 @@
   void setPort(int port);
 
   /**
+   * Set the Unix domain socket path for the socket
+   *
+   * @param path std::string path
+   */
+  void setPath(std::string path);
+
+  /**
    * Controls whether the linger option is set on the socket.
    *
    * @param on      Whether SO_LINGER is on
diff --git a/lib/cpp/src/thrift/windows/WinFcntl.cpp b/lib/cpp/src/thrift/windows/WinFcntl.cpp
index 292ddfc..cec2f67 100644
--- a/lib/cpp/src/thrift/windows/WinFcntl.cpp
+++ b/lib/cpp/src/thrift/windows/WinFcntl.cpp
@@ -42,57 +42,6 @@
   return res;
 }
 
-#if WINVER <= 0x0502 // XP, Server2003
-int thrift_poll(THRIFT_POLLFD* fdArray, ULONG nfds, INT timeout) {
-  fd_set read_fds, write_fds;
-  fd_set* read_fds_ptr = nullptr;
-  fd_set* write_fds_ptr = nullptr;
-
-  FD_ZERO(&read_fds);
-  FD_ZERO(&write_fds);
-
-  for (ULONG i = 0; i < nfds; i++) {
-    // Read (in) socket
-    if ((fdArray[i].events & THRIFT_POLLIN) == THRIFT_POLLIN) {
-      read_fds_ptr = &read_fds;
-      FD_SET(fdArray[i].fd, &read_fds);
-    }
-    // Write (out) socket
-    else if ((fdArray[i].events & THRIFT_POLLOUT) == THRIFT_POLLOUT) {
-      write_fds_ptr = &write_fds;
-      FD_SET(fdArray[i].fd, &write_fds);
-    }
-  }
-
-  timeval time_out;
-  timeval* time_out_ptr = nullptr;
-  if (timeout >= 0) {
-    time_out.tv_sec = timeout / 1000;
-    time_out.tv_usec = (timeout % 1000) * 1000;
-    time_out_ptr = &time_out;
-  } else { // to avoid compiler warnings
-    (void)time_out;
-    (void)timeout;
-  }
-
-  int sktready = select(1, read_fds_ptr, write_fds_ptr, nullptr, time_out_ptr);
-  if (sktready > 0) {
-    for (ULONG i = 0; i < nfds; i++) {
-      fdArray[i].revents = 0;
-      if (FD_ISSET(fdArray[i].fd, &read_fds))
-        fdArray[i].revents |= THRIFT_POLLIN;
-      if (FD_ISSET(fdArray[i].fd, &write_fds))
-        fdArray[i].revents |= THRIFT_POLLOUT;
-    }
-  }
-  return sktready;
-}
-#else  // Vista, Win7...
-int thrift_poll(THRIFT_POLLFD* fdArray, ULONG nfds, INT timeout) {
-  return WSAPoll(fdArray, nfds, timeout);
-}
-#endif // WINVER
-
 #ifdef _WIN32_WCE
 std::string thrift_wstr2str(std::wstring ws) {
   std::string s(ws.begin(), ws.end());
diff --git a/lib/cpp/src/thrift/windows/WinFcntl.h b/lib/cpp/src/thrift/windows/WinFcntl.h
index 6c6be97..4816fc5 100644
--- a/lib/cpp/src/thrift/windows/WinFcntl.h
+++ b/lib/cpp/src/thrift/windows/WinFcntl.h
@@ -36,17 +36,8 @@
 #include <Winsock2.h>
 #include <thrift/transport/PlatformSocket.h>
 
-#if WINVER <= 0x0502 // XP, Server2003
-struct thrift_pollfd {
-  THRIFT_SOCKET fd;
-  SHORT events;
-  SHORT revents;
-};
-#endif
-
 extern "C" {
 int thrift_fcntl(THRIFT_SOCKET fd, int cmd, int flags);
-int thrift_poll(THRIFT_POLLFD* fdArray, ULONG nfds, INT timeout);
 }
 
 #ifdef _WIN32_WCE
diff --git a/lib/cpp/test/Base64Test.cpp b/lib/cpp/test/Base64Test.cpp
index 7686e4e..843b236 100644
--- a/lib/cpp/test/Base64Test.cpp
+++ b/lib/cpp/test/Base64Test.cpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 #include <thrift/protocol/TBase64Utils.h>
 
 using apache::thrift::protocol::base64_encode;
diff --git a/lib/cpp/test/OneWayHTTPTest.cpp b/lib/cpp/test/OneWayHTTPTest.cpp
index 55d919b..7823482 100644
--- a/lib/cpp/test/OneWayHTTPTest.cpp
+++ b/lib/cpp/test/OneWayHTTPTest.cpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 #include <boost/thread.hpp>
 #include <iostream>
 #include <climits>
diff --git a/lib/cpp/test/TBufferBaseTest.cpp b/lib/cpp/test/TBufferBaseTest.cpp
index 7203f82..3aa845b 100644
--- a/lib/cpp/test/TBufferBaseTest.cpp
+++ b/lib/cpp/test/TBufferBaseTest.cpp
@@ -18,7 +18,7 @@
  */
 
 #include <algorithm>
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 #include <thrift/transport/TBufferTransports.h>
 #include <thrift/transport/TShortReadTransport.h>
 #include <memory>
diff --git a/lib/cpp/test/TMemoryBufferTest.cpp b/lib/cpp/test/TMemoryBufferTest.cpp
index 42f9711..759aa0c 100644
--- a/lib/cpp/test/TMemoryBufferTest.cpp
+++ b/lib/cpp/test/TMemoryBufferTest.cpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 #include <iostream>
 #include <climits>
 #include <vector>
diff --git a/lib/cpp/test/TSSLSocketInterruptTest.cpp b/lib/cpp/test/TSSLSocketInterruptTest.cpp
index 33f686c..83fb993 100644
--- a/lib/cpp/test/TSSLSocketInterruptTest.cpp
+++ b/lib/cpp/test/TSSLSocketInterruptTest.cpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 #include <boost/test/unit_test_suite.hpp>
 #include <boost/chrono/duration.hpp>
 #include <boost/date_time/posix_time/posix_time_duration.hpp>
diff --git a/lib/cpp/test/TServerIntegrationTest.cpp b/lib/cpp/test/TServerIntegrationTest.cpp
index b88c35b..ab235d5 100644
--- a/lib/cpp/test/TServerIntegrationTest.cpp
+++ b/lib/cpp/test/TServerIntegrationTest.cpp
@@ -19,7 +19,7 @@
 
 #define BOOST_TEST_MODULE TServerIntegrationTest
 #include <atomic>
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 #include <boost/date_time/posix_time/ptime.hpp>
 #include <boost/foreach.hpp>
 #include <boost/format.hpp>
diff --git a/lib/cpp/test/TServerSocketTest.cpp b/lib/cpp/test/TServerSocketTest.cpp
index c96700f..929defa 100644
--- a/lib/cpp/test/TServerSocketTest.cpp
+++ b/lib/cpp/test/TServerSocketTest.cpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 #include <thrift/transport/TSocket.h>
 #include <thrift/transport/TServerSocket.h>
 #include <memory>
diff --git a/lib/cpp/test/TServerTransportTest.cpp b/lib/cpp/test/TServerTransportTest.cpp
index 18a393e..8944737 100644
--- a/lib/cpp/test/TServerTransportTest.cpp
+++ b/lib/cpp/test/TServerTransportTest.cpp
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 #include <thrift/transport/TSocket.h>
 #include <thrift/transport/TServerTransport.h>
 #include <memory>
diff --git a/lib/cpp/test/TSocketInterruptTest.cpp b/lib/cpp/test/TSocketInterruptTest.cpp
index a546c23..1e3e59c 100644
--- a/lib/cpp/test/TSocketInterruptTest.cpp
+++ b/lib/cpp/test/TSocketInterruptTest.cpp
@@ -18,7 +18,7 @@
  */
 
 #define BOOST_TEST_MODULE TSocketInterruptTest
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 
 #include <boost/chrono/duration.hpp>
 #include <boost/date_time/posix_time/posix_time_duration.hpp>
diff --git a/lib/cpp/test/ToStringTest.cpp b/lib/cpp/test/ToStringTest.cpp
index d204cb3..5a05ed7 100644
--- a/lib/cpp/test/ToStringTest.cpp
+++ b/lib/cpp/test/ToStringTest.cpp
@@ -20,7 +20,7 @@
 #include <vector>
 #include <map>
 
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
 
 #include <thrift/TToString.h>
 
diff --git a/lib/cpp/test/UnitTestMain.cpp b/lib/cpp/test/UnitTestMain.cpp
index f0ef1e4..04b37ff 100644
--- a/lib/cpp/test/UnitTestMain.cpp
+++ b/lib/cpp/test/UnitTestMain.cpp
@@ -18,4 +18,4 @@
  */
 
 #define BOOST_TEST_MODULE thrift
-#include <boost/test/auto_unit_test.hpp>
+#include <boost/test/unit_test.hpp>
diff --git a/lib/go/thrift/compact_protocol.go b/lib/go/thrift/compact_protocol.go
index 4689357..8510f1f 100644
--- a/lib/go/thrift/compact_protocol.go
+++ b/lib/go/thrift/compact_protocol.go
@@ -209,7 +209,6 @@
 	}
 
 	p.lastFieldId = fieldId
-	// p.lastField.Push(field.id);
 	return written, nil
 }
 
diff --git a/lib/go/thrift/field.go b/lib/go/thrift/field.go
deleted file mode 100644
index 9d66525..0000000
--- a/lib/go/thrift/field.go
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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.
- */
-
-package thrift
-
-// Helper class that encapsulates field metadata.
-type field struct {
-	name   string
-	typeId TType
-	id     int
-}
-
-func newField(n string, t TType, i int) *field {
-	return &field{name: n, typeId: t, id: i}
-}
-
-func (p *field) Name() string {
-	if p == nil {
-		return ""
-	}
-	return p.name
-}
-
-func (p *field) TypeId() TType {
-	if p == nil {
-		return TType(VOID)
-	}
-	return p.typeId
-}
-
-func (p *field) Id() int {
-	if p == nil {
-		return -1
-	}
-	return p.id
-}
-
-func (p *field) String() string {
-	if p == nil {
-		return "<nil>"
-	}
-	return "<TField name:'" + p.name + "' type:" + string(p.typeId) + " field-id:" + string(p.id) + ">"
-}
-
-var ANONYMOUS_FIELD *field
-
-type fieldSlice []field
-
-func (p fieldSlice) Len() int {
-	return len(p)
-}
-
-func (p fieldSlice) Less(i, j int) bool {
-	return p[i].Id() < p[j].Id()
-}
-
-func (p fieldSlice) Swap(i, j int) {
-	p[i], p[j] = p[j], p[i]
-}
-
-func init() {
-	ANONYMOUS_FIELD = newField("", STOP, 0)
-}
diff --git a/lib/go/thrift/json_protocol_test.go b/lib/go/thrift/json_protocol_test.go
index 07afa96..333d383 100644
--- a/lib/go/thrift/json_protocol_test.go
+++ b/lib/go/thrift/json_protocol_test.go
@@ -609,7 +609,7 @@
 	for k, value := range DOUBLE_VALUES {
 		ik, err := p.ReadI32(context.Background())
 		if err != nil {
-			t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, ik, string(k), err.Error())
+			t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, ik, k, err.Error())
 		}
 		if int(ik) != k {
 			t.Fatalf("Bad key for %s index %v, wrote: %v, expected: %v", thetype, k, ik, k)
diff --git a/lib/go/thrift/numeric.go b/lib/go/thrift/numeric.go
index aa8daa9..e4512d2 100644
--- a/lib/go/thrift/numeric.go
+++ b/lib/go/thrift/numeric.go
@@ -69,14 +69,14 @@
 
 func NewNumericFromI64(iValue int64) Numeric {
 	dValue := float64(iValue)
-	sValue := string(iValue)
+	sValue := strconv.FormatInt(iValue, 10)
 	isNil := false
 	return &numeric{iValue: iValue, dValue: dValue, sValue: sValue, isNil: isNil}
 }
 
 func NewNumericFromI32(iValue int32) Numeric {
 	dValue := float64(iValue)
-	sValue := string(iValue)
+	sValue := strconv.FormatInt(int64(iValue), 10)
 	isNil := false
 	return &numeric{iValue: int64(iValue), dValue: dValue, sValue: sValue, isNil: isNil}
 }
diff --git a/lib/go/thrift/simple_json_protocol_test.go b/lib/go/thrift/simple_json_protocol_test.go
index 951389a..986fff2 100644
--- a/lib/go/thrift/simple_json_protocol_test.go
+++ b/lib/go/thrift/simple_json_protocol_test.go
@@ -682,7 +682,7 @@
 		strv := l[k*2+4]
 		ik, err := strconv.Atoi(strk)
 		if err != nil {
-			t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, strk, string(k), err.Error())
+			t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v, error: %s", thetype, k, strk, k, err.Error())
 		}
 		if ik != k {
 			t.Fatalf("Bad value for %s index %v, wrote: %v, expected: %v", thetype, k, strk, k)
diff --git a/lib/java/src/org/apache/thrift/TAsyncProcessor.java b/lib/java/src/org/apache/thrift/TAsyncProcessor.java
index 66f7688..5e287d5 100644
--- a/lib/java/src/org/apache/thrift/TAsyncProcessor.java
+++ b/lib/java/src/org/apache/thrift/TAsyncProcessor.java
@@ -23,7 +23,7 @@
 public interface TAsyncProcessor {
   /**
    * Process a single frame.
-   
+
    * <b>Note:</b> Implementations must call fb.responseReady() once processing
    * is complete
    *
diff --git a/lib/java/src/org/apache/thrift/TConfiguration.java b/lib/java/src/org/apache/thrift/TConfiguration.java
new file mode 100644
index 0000000..b98274a
--- /dev/null
+++ b/lib/java/src/org/apache/thrift/TConfiguration.java
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+package org.apache.thrift;
+
+
+public class TConfiguration {
+    public static final int DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024;
+    public static final int DEFAULT_MAX_FRAME_SIZE = 16384000;      // this value is used consistently across all Thrift libraries
+    public static final int DEFAULT_RECURSION_DEPTH = 64;
+
+    private int maxMessageSize;
+    private int maxFrameSize;
+    private int recursionLimit;
+
+    public TConfiguration() {
+        this(DEFAULT_MAX_MESSAGE_SIZE, DEFAULT_MAX_FRAME_SIZE, DEFAULT_RECURSION_DEPTH);
+    }
+    public TConfiguration(int maxMessageSize, int maxFrameSize, int recursionLimit) {
+        this.maxFrameSize = maxFrameSize;
+        this.maxMessageSize = maxMessageSize;
+        this.recursionLimit = recursionLimit;
+    }
+
+    public int getMaxMessageSize() {
+        return maxMessageSize;
+    }
+
+    public int getMaxFrameSize() {
+        return maxFrameSize;
+    }
+
+    public int getRecursionLimit() {
+        return recursionLimit;
+    }
+
+    public void setMaxMessageSize(int maxMessageSize) {
+        this.maxMessageSize = maxMessageSize;
+    }
+
+    public void setMaxFrameSize(int maxFrameSize) {
+        this.maxFrameSize = maxFrameSize;
+    }
+
+    public void setRecursionLimit(int recursionLimit) {
+        this.recursionLimit = recursionLimit;
+    }
+
+    public static final TConfiguration DEFAULT = new Builder().build();
+
+    public static TConfiguration.Builder custom() {
+        return new Builder();
+    }
+
+    public static class Builder {
+        private int maxMessageSize ;
+        private int maxFrameSize;
+        private int recursionLimit ;
+
+        Builder() {
+            super();
+            this.maxFrameSize = DEFAULT_MAX_FRAME_SIZE;
+            this.maxMessageSize = DEFAULT_MAX_MESSAGE_SIZE;
+            this.recursionLimit = DEFAULT_RECURSION_DEPTH;
+        }
+
+        public Builder setMaxMessageSize(int maxMessageSize) {
+            this.maxMessageSize = maxMessageSize;
+            return this;
+        }
+
+        public Builder setMaxFrameSize(int maxFrameSize) {
+            this.maxFrameSize = maxFrameSize;
+            return this;
+        }
+
+        public Builder setRecursionLimit(int recursionLimit) {
+            this.recursionLimit = recursionLimit;
+            return this;
+        }
+
+        public TConfiguration build() {
+            return new TConfiguration(maxMessageSize, maxFrameSize, recursionLimit);
+        }
+    }
+}
diff --git a/lib/java/src/org/apache/thrift/TDeserializer.java b/lib/java/src/org/apache/thrift/TDeserializer.java
index d1d3966..29be557 100644
--- a/lib/java/src/org/apache/thrift/TDeserializer.java
+++ b/lib/java/src/org/apache/thrift/TDeserializer.java
@@ -29,6 +29,7 @@
 import org.apache.thrift.protocol.TProtocolUtil;
 import org.apache.thrift.protocol.TType;
 import org.apache.thrift.transport.TMemoryInputTransport;
+import org.apache.thrift.transport.TTransportException;
 
 /**
  * Generic utility for easily deserializing objects from a byte array or Java
@@ -42,7 +43,7 @@
   /**
    * Create a new TDeserializer that uses the TBinaryProtocol by default.
    */
-  public TDeserializer() {
+  public TDeserializer() throws TTransportException {
     this(new TBinaryProtocol.Factory());
   }
 
@@ -52,8 +53,8 @@
    *
    * @param protocolFactory Factory to create a protocol
    */
-  public TDeserializer(TProtocolFactory protocolFactory) {
-    trans_ = new TMemoryInputTransport();
+  public TDeserializer(TProtocolFactory protocolFactory) throws TTransportException {
+    trans_ = new TMemoryInputTransport(new TConfiguration());
     protocol_ = protocolFactory.getProtocol(trans_);
   }
 
@@ -105,19 +106,19 @@
 
   /**
    * Deserialize only a single Thrift object (addressed by recursively using field id)
-   * from a byte record.   
+   * from a byte record.
    * @param tb The object to read into
    * @param bytes The serialized object to read from
    * @param fieldIdPathFirst First of the FieldId's that define a path tb
    * @param fieldIdPathRest The rest FieldId's that define a path tb
-   * @throws TException 
+   * @throws TException
    */
   public void partialDeserialize(TBase tb, byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException {
     try {
       if (locateField(bytes, fieldIdPathFirst, fieldIdPathRest) != null) {
         // if this line is reached, iprot will be positioned at the start of tb.
         tb.read(protocol_);
-      }      
+      }
     } catch (Exception e) {
       throw new TException(e);
     } finally {
diff --git a/lib/java/src/org/apache/thrift/TNonblockingMultiFetchClient.java b/lib/java/src/org/apache/thrift/TNonblockingMultiFetchClient.java
index 9cf873c..78f3a57 100644
--- a/lib/java/src/org/apache/thrift/TNonblockingMultiFetchClient.java
+++ b/lib/java/src/org/apache/thrift/TNonblockingMultiFetchClient.java
@@ -75,7 +75,7 @@
  *
  */
 public class TNonblockingMultiFetchClient {
-  
+
   private static final Logger LOGGER = LoggerFactory.getLogger(
     TNonblockingMultiFetchClient.class);
 
@@ -86,7 +86,7 @@
   // time limit for fetching data from all servers (in second)
   private int fetchTimeoutSeconds;
 
-  // store request that will be sent to servers  
+  // store request that will be sent to servers
   private ByteBuffer requestBuf;
   private ByteBuffer requestBufDuplication;
 
@@ -104,7 +104,7 @@
     this.fetchTimeoutSeconds = fetchTimeoutSeconds;
     this.requestBuf = requestBuf;
     this.servers = servers;
-      
+
     stats = new TNonblockingMultiFetchStats();
     recvBuf = null;
   }
@@ -128,7 +128,7 @@
       if (requestBufDuplication == null) {
         requestBufDuplication = requestBuf.duplicate();
       }
-      return requestBufDuplication;  
+      return requestBufDuplication;
     }
   }
 
@@ -171,7 +171,7 @@
       task.cancel(true);
       LOGGER.error("Exception during fetch", ee);
     } catch (TimeoutException te) {
-      // attempt to cancel execution of the task.  
+      // attempt to cancel execution of the task.
       task.cancel(true);
       LOGGER.error("Timeout for fetch", te);
     }
@@ -207,10 +207,10 @@
       // buffer for receiving response from servers
       recvBuf                     = new ByteBuffer[numTotalServers];
       // buffer for sending request
-      ByteBuffer sendBuf[]        = new ByteBuffer[numTotalServers];
-      long numBytesRead[]         = new long[numTotalServers];
-      int frameSize[]             = new int[numTotalServers];
-      boolean hasReadFrameSize[]  = new boolean[numTotalServers];
+      ByteBuffer[] sendBuf = new ByteBuffer[numTotalServers];
+      long[] numBytesRead = new long[numTotalServers];
+      int[] frameSize = new int[numTotalServers];
+      boolean[] hasReadFrameSize = new boolean[numTotalServers];
 
       try {
         selector = Selector.open();
@@ -240,10 +240,11 @@
         } catch (Exception e) {
           stats.incNumConnectErrorServers();
           LOGGER.error("Set up socket to server {} error", server, e);
+
           // free resource
           if (s != null) {
             try {s.close();} catch (Exception ex) {}
-          }            
+          }
           if (key != null) {
              key.cancel();
           }
@@ -253,7 +254,7 @@
       // wait for events
       while (stats.getNumReadCompletedServers() +
         stats.getNumConnectErrorServers() < stats.getNumTotalServers()) {
-        // if the thread is interrupted (e.g., task is cancelled)  
+        // if the thread is interrupted (e.g., task is cancelled)
         if (Thread.currentThread().isInterrupted()) {
           return;
         }
@@ -380,4 +381,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/lib/java/src/org/apache/thrift/TSerializer.java b/lib/java/src/org/apache/thrift/TSerializer.java
index 4e1ce61..4bf057d 100644
--- a/lib/java/src/org/apache/thrift/TSerializer.java
+++ b/lib/java/src/org/apache/thrift/TSerializer.java
@@ -26,6 +26,7 @@
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.protocol.TProtocolFactory;
 import org.apache.thrift.transport.TIOStreamTransport;
+import org.apache.thrift.transport.TTransportException;
 
 /**
  * Generic utility for easily serializing objects into a byte array or Java
@@ -42,7 +43,7 @@
   /**
    * This transport wraps that byte array
    */
-  private final TIOStreamTransport transport_ = new TIOStreamTransport(baos_);
+  private final TIOStreamTransport transport_;
 
   /**
    * Internal protocol used for serializing objects.
@@ -52,7 +53,7 @@
   /**
    * Create a new TSerializer that uses the TBinaryProtocol by default.
    */
-  public TSerializer() {
+  public TSerializer() throws TTransportException {
     this(new TBinaryProtocol.Factory());
   }
 
@@ -62,7 +63,8 @@
    *
    * @param protocolFactory Factory to create a protocol
    */
-  public TSerializer(TProtocolFactory protocolFactory) {
+  public TSerializer(TProtocolFactory protocolFactory) throws TTransportException {
+    transport_ = new TIOStreamTransport(new TConfiguration(), baos_);
     protocol_ = protocolFactory.getProtocol(transport_);
   }
 
diff --git a/lib/java/src/org/apache/thrift/async/TAsyncMethodCall.java b/lib/java/src/org/apache/thrift/async/TAsyncMethodCall.java
index 3bf1747..d5c608d 100644
--- a/lib/java/src/org/apache/thrift/async/TAsyncMethodCall.java
+++ b/lib/java/src/org/apache/thrift/async/TAsyncMethodCall.java
@@ -27,7 +27,7 @@
 import org.apache.thrift.TException;
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.protocol.TProtocolFactory;
-import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.layered.TFramedTransport;
 import org.apache.thrift.transport.TMemoryBuffer;
 import org.apache.thrift.transport.TNonblockingTransport;
 import org.apache.thrift.transport.TTransportException;
@@ -98,7 +98,7 @@
   protected long getStartTime() {
     return startTime;
   }
-  
+
   protected long getSequenceId() {
     return sequenceId;
   }
@@ -106,11 +106,11 @@
   public TAsyncClient getClient() {
     return client;
   }
-  
+
   public boolean hasTimeout() {
     return timeout > 0;
   }
-  
+
   public long getTimeoutTimestamp() {
     return timeout + startTime;
   }
diff --git a/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java b/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java
index 7924e2f..fc46f7c 100644
--- a/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TBinaryProtocol.java
@@ -24,6 +24,7 @@
 
 import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
 
 /**
  * Binary protocol implementation for thrift.
@@ -279,6 +280,8 @@
   @Override
   public TMap readMapBegin() throws TException {
     TMap map = new TMap(readByte(), readByte(), readI32());
+
+    checkReadBytesAvailable(map);
     checkContainerReadLength(map.size);
     return map;
   }
@@ -289,6 +292,8 @@
   @Override
   public TList readListBegin() throws TException {
     TList list = new TList(readByte(), readI32());
+
+    checkReadBytesAvailable(list);
     checkContainerReadLength(list.size);
     return list;
   }
@@ -299,6 +304,8 @@
   @Override
   public TSet readSetBegin() throws TException {
     TSet set = new TSet(readByte(), readI32());
+
+    checkReadBytesAvailable(set);
     checkContainerReadLength(set.size);
     return set;
   }
@@ -393,8 +400,6 @@
   public String readString() throws TException {
     int size = readI32();
 
-    checkStringReadLength(size);
-
     if (trans_.getBytesRemainingInBuffer() >= size) {
       String s = new String(trans_.getBuffer(), trans_.getBufferPosition(),
           size, StandardCharsets.UTF_8);
@@ -429,11 +434,14 @@
     return ByteBuffer.wrap(buf);
   }
 
-  private void checkStringReadLength(int length) throws TProtocolException {
+  private void checkStringReadLength(int length) throws TException {
     if (length < 0) {
       throw new TProtocolException(TProtocolException.NEGATIVE_SIZE,
                                    "Negative length: " + length);
     }
+
+    getTransport().checkReadBytesAvailable(length);
+
     if (stringLengthLimit_ != NO_LENGTH_LIMIT && length > stringLengthLimit_) {
       throw new TProtocolException(TProtocolException.SIZE_LIMIT,
                                    "Length exceeded max allowed: " + length);
@@ -454,4 +462,28 @@
   private int readAll(byte[] buf, int off, int len) throws TException {
     return trans_.readAll(buf, off, len);
   }
+
+  /**
+   *
+   * Return the minimum number of bytes a type will consume on the wire
+   */
+  public int getMinSerializedSize(byte type) throws TTransportException {
+    switch (type)
+    {
+      case 0: return 0; // Stop
+      case 1: return 0; // Void
+      case 2: return 1; // Bool sizeof(byte)
+      case 3: return 1; // Byte sizeof(byte)
+      case 4: return 8; // Double sizeof(double)
+      case 6: return 2; // I16 sizeof(short)
+      case 8: return 4; // I32 sizeof(int)
+      case 10: return 8;// I64 sizeof(long)
+      case 11: return 4;  // string length sizeof(int)
+      case 12: return 0;  // empty struct
+      case 13: return 4;  // element count Map sizeof(int)
+      case 14: return 4;  // element count Set sizeof(int)
+      case 15: return 4;  // element count List sizeof(int)
+      default: throw new TTransportException(TTransportException.UNKNOWN, "unrecognized type code");
+    }
+  }
 }
diff --git a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
index ee05869..0dfcf25 100644
--- a/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TCompactProtocol.java
@@ -26,6 +26,7 @@
 
 import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
 
 /**
  * TCompactProtocol2 is the Java implementation of the compact protocol specified
@@ -579,7 +580,9 @@
     int size = readVarint32();
     checkContainerReadLength(size);
     byte keyAndValueType = size == 0 ? 0 : readByte();
-    return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
+    TMap map = new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
+    checkReadBytesAvailable(map);
+    return map;
   }
 
   /**
@@ -595,8 +598,9 @@
       size = readVarint32();
     }
     checkContainerReadLength(size);
-    byte type = getTType(size_and_type);
-    return new TList(type, size);
+    TList list = new TList(getTType(size_and_type), size);
+    checkReadBytesAvailable(list);
+    return list;
   }
 
   /**
@@ -694,9 +698,9 @@
    */
   public ByteBuffer readBinary() throws TException {
     int length = readVarint32();
-    checkStringReadLength(length);
+    
     if (length == 0) return EMPTY_BUFFER;
-
+    getTransport().checkReadBytesAvailable(length);
     if (trans_.getBytesRemainingInBuffer() >= length) {
       ByteBuffer bb = ByteBuffer.wrap(trans_.getBuffer(), trans_.getBufferPosition(), length);
       trans_.consumeBuffer(length);
@@ -719,11 +723,14 @@
     return buf;
   }
 
-  private void checkStringReadLength(int length) throws TProtocolException {
+  private void checkStringReadLength(int length) throws TException {
     if (length < 0) {
       throw new TProtocolException(TProtocolException.NEGATIVE_SIZE,
                                    "Negative length: " + length);
     }
+
+    getTransport().checkReadBytesAvailable(length);
+    
     if (stringLengthLimit_ != NO_LENGTH_LIMIT && length > stringLengthLimit_) {
       throw new TProtocolException(TProtocolException.SIZE_LIMIT,
                                    "Length exceeded max allowed: " + length);
@@ -901,4 +908,40 @@
   private byte getCompactType(byte ttype) {
     return ttypeToCompactType[ttype];
   }
+
+  /**
+   * Return the minimum number of bytes a type will consume on the wire
+   */
+  public int getMinSerializedSize(byte type) throws TTransportException {
+      switch (type) {
+          case 0:
+              return 0; // Stop
+          case 1:
+              return 0; // Void
+          case 2:
+              return 1; // Bool sizeof(byte)
+          case 3:
+              return 1; // Byte sizeof(byte)
+          case 4:
+              return 8; // Double sizeof(double)
+          case 6:
+              return 1; // I16 sizeof(byte)
+          case 8:
+              return 1; // I32 sizeof(byte)
+          case 10:
+              return 1;// I64 sizeof(byte)
+          case 11:
+              return 1;  // string length sizeof(byte)
+          case 12:
+              return 0;  // empty struct
+          case 13:
+              return 1;  // element count Map sizeof(byte)
+          case 14:
+              return 1;  // element count Set sizeof(byte)
+          case 15:
+              return 1;  // element count List sizeof(byte)
+          default:
+              throw new TTransportException(TTransportException.UNKNOWN, "unrecognized type code");
+      }
+  }
 }
diff --git a/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java b/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
index d37c493..6bb49cb 100644
--- a/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TJSONProtocol.java
@@ -28,6 +28,7 @@
 import org.apache.thrift.TByteArrayOutputStream;
 import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
 
 /**
  * JSON protocol implementation for thrift.
@@ -591,17 +592,17 @@
 
   @Override
   public void writeByte(byte b) throws TException {
-    writeJSONInteger((long)b);
+    writeJSONInteger(b);
   }
 
   @Override
   public void writeI16(short i16) throws TException {
-    writeJSONInteger((long)i16);
+    writeJSONInteger(i16);
   }
 
   @Override
   public void writeI32(int i32) throws TException {
-    writeJSONInteger((long)i32);
+    writeJSONInteger(i32);
   }
 
   @Override
@@ -895,7 +896,10 @@
     byte valueType = getTypeIDForTypeName(readJSONString(false).get());
     int size = (int)readJSONInteger();
     readJSONObjectStart();
-    return new TMap(keyType, valueType, size);
+    TMap map = new TMap(keyType, valueType, size);
+
+    checkReadBytesAvailable(map);
+    return map;
   }
 
   @Override
@@ -909,7 +913,10 @@
     readJSONArrayStart();
     byte elemType = getTypeIDForTypeName(readJSONString(false).get());
     int size = (int)readJSONInteger();
-    return new TList(elemType, size);
+    TList list = new TList(elemType, size);
+
+    checkReadBytesAvailable(list);
+    return list;
   }
 
   @Override
@@ -922,7 +929,10 @@
     readJSONArrayStart();
     byte elemType = getTypeIDForTypeName(readJSONString(false).get());
     int size = (int)readJSONInteger();
-    return new TSet(elemType, size);
+    TSet set = new TSet(elemType, size);
+
+    checkReadBytesAvailable(set);
+    return set;
   }
 
   @Override
@@ -932,7 +942,7 @@
 
   @Override
   public boolean readBool() throws TException {
-    return (readJSONInteger() == 0 ? false : true);
+    return (readJSONInteger() != 0);
   }
 
   @Override
@@ -952,7 +962,7 @@
 
   @Override
   public long readI64() throws TException {
-    return (long) readJSONInteger();
+    return readJSONInteger();
   }
 
   @Override
@@ -962,7 +972,9 @@
 
   @Override
   public String readString() throws TException {
-    return readJSONString(false).toString(StandardCharsets.UTF_8);
+    String str = readJSONString(false).toString(StandardCharsets.UTF_8);
+    getTransport().checkReadBytesAvailable(str.length() * getMinSerializedSize(TType.STRING));
+    return str;
   }
 
   @Override
@@ -970,4 +982,28 @@
     return ByteBuffer.wrap(readJSONBase64());
   }
 
+  /**
+   *
+   * Return the minimum number of bytes a type will consume on the wire
+   */
+  public int getMinSerializedSize(byte type) throws TTransportException {
+    switch (type)
+    {
+      case 0: return 0; // Stop
+      case 1: return 0; // Void
+      case 2: return 1; // Bool
+      case 3: return 1; // Byte
+      case 4: return 1; // Double
+      case 6: return 1; // I16
+      case 8: return 1; // I32
+      case 10: return 1;// I64
+      case 11: return 2;  // string length
+      case 12: return 2;  // empty struct
+      case 13: return 2;  // element count Map
+      case 14: return 2;  // element count Set
+      case 15: return 2;  // element count List
+      default: throw new TTransportException(TTransportException.UNKNOWN, "unrecognized type code");
+    }
+  }
+
 }
diff --git a/lib/java/src/org/apache/thrift/protocol/TProtocol.java b/lib/java/src/org/apache/thrift/protocol/TProtocol.java
index 0e96368..38c030e 100644
--- a/lib/java/src/org/apache/thrift/protocol/TProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TProtocol.java
@@ -57,6 +57,27 @@
     return trans_;
   }
 
+  protected void checkReadBytesAvailable(TMap map) throws TException {
+    long elemSize = getMinSerializedSize(map.keyType) + getMinSerializedSize(map.valueType);
+    trans_.checkReadBytesAvailable(map.size * elemSize);
+  }
+
+  protected void checkReadBytesAvailable(TList list) throws TException {
+    trans_.checkReadBytesAvailable(list.size * getMinSerializedSize(list.elemType));
+  }
+
+  protected void checkReadBytesAvailable(TSet set) throws TException {
+    trans_.checkReadBytesAvailable(set.size * getMinSerializedSize(set.elemType));
+  }
+
+  /**
+   * Return
+   * @param type  Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
+   * @return
+   * @throws TException
+   */
+  public abstract int getMinSerializedSize(byte type) throws TException;
+
   /**
    * Writing methods.
    */
@@ -152,7 +173,7 @@
    * be implemented for stateful protocols.
    */
   public void reset() {}
-  
+
   /**
    * Scheme accessor
    */
diff --git a/lib/java/src/org/apache/thrift/protocol/TProtocolDecorator.java b/lib/java/src/org/apache/thrift/protocol/TProtocolDecorator.java
index 2d29cd2..9d10962 100644
--- a/lib/java/src/org/apache/thrift/protocol/TProtocolDecorator.java
+++ b/lib/java/src/org/apache/thrift/protocol/TProtocolDecorator.java
@@ -31,7 +31,7 @@
  * the behaviour of the enclosed <code>TProtocol</code>.
  *
  * <p>See p.175 of Design Patterns (by Gamma et al.)</p>
- * 
+ *
  * @see org.apache.thrift.protocol.TMultiplexedProtocol
  */
 public abstract class TProtocolDecorator extends TProtocol {
@@ -210,4 +210,14 @@
     public ByteBuffer readBinary() throws TException {
         return concreteProtocol.readBinary();
     }
+
+    /**
+     *
+     * @param type  Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
+     * @return
+     * @throws TException
+     */
+    public int getMinSerializedSize(byte type) throws TException {
+        return concreteProtocol.getMinSerializedSize(type);
+    }
 }
diff --git a/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java b/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java
index eb7e23b..9413f61 100644
--- a/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java
@@ -25,6 +25,7 @@
 
 import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
 
 /**
  * JSON protocol implementation for thrift.
@@ -480,4 +481,28 @@
       super(message);
     }
   }
+
+  /**
+   *
+   * Return the minimum number of bytes a type will consume on the wire
+   */
+  public int getMinSerializedSize(byte type) throws TException {
+    switch (type)
+    {
+      case 0: return 0; // Stop
+      case 1: return 0; // Void
+      case 2: return 1; // Bool
+      case 3: return 1; // Byte
+      case 4: return 1; // Double
+      case 6: return 1; // I16
+      case 8: return 1; // I32
+      case 10: return 1;// I64
+      case 11: return 2;  // string length
+      case 12: return 2;  // empty struct
+      case 13: return 2;  // element count Map
+      case 14: return 2;  // element count Set
+      case 15: return 2;  // element count List
+      default: throw new TTransportException(TTransportException.UNKNOWN, "unrecognized type code");
+    }
+  }
 }
diff --git a/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java b/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java
index 74f5226..67d00ed 100644
--- a/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java
+++ b/lib/java/src/org/apache/thrift/protocol/TTupleProtocol.java
@@ -80,9 +80,9 @@
    * extension). The byte-ordering of the result is big-endian which means the
    * most significant bit is in element 0. The bit at index 0 of the bit set is
    * assumed to be the least significant bit.
-   * 
+   *
    * @param bits
-   * @param vectorWidth 
+   * @param vectorWidth
    * @return a byte array of at least length 1
    */
   public static byte[] toByteArray(BitSet bits, int vectorWidth) {
@@ -95,4 +95,27 @@
     return bytes;
   }
 
+  public TMap readMapBegin(byte keyType, byte valTyep) throws TException {
+    int size = super.readI32();
+    TMap map = new TMap(keyType, valTyep, size);
+
+    checkReadBytesAvailable(map);
+    return map;
+  }
+
+  public TList readListBegin(byte type) throws TException {
+    int size = super.readI32();
+    TList list = new TList(type, size);
+
+    checkReadBytesAvailable(list);
+    return list;
+  }
+
+  public TSet readSetBegin(byte type) throws TException {
+    return new TSet(readListBegin(type));
+  }
+
+  public void readMapEnd() throws TException {}
+  public void readListEnd() throws TException {}
+  public void readSetEnd() throws TException {}
 }
diff --git a/lib/java/src/org/apache/thrift/server/AbstractNonblockingServer.java b/lib/java/src/org/apache/thrift/server/AbstractNonblockingServer.java
index 8c206e4..4aae803 100644
--- a/lib/java/src/org/apache/thrift/server/AbstractNonblockingServer.java
+++ b/lib/java/src/org/apache/thrift/server/AbstractNonblockingServer.java
@@ -23,7 +23,7 @@
 import org.apache.thrift.TByteArrayOutputStream;
 import org.apache.thrift.TException;
 import org.apache.thrift.protocol.TProtocol;
-import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.layered.TFramedTransport;
 import org.apache.thrift.transport.TIOStreamTransport;
 import org.apache.thrift.transport.TMemoryInputTransport;
 import org.apache.thrift.transport.TNonblockingServerTransport;
@@ -305,7 +305,7 @@
 
     public FrameBuffer(final TNonblockingTransport trans,
         final SelectionKey selectionKey,
-        final AbstractSelectThread selectThread) {
+        final AbstractSelectThread selectThread) throws TTransportException {
       trans_ = trans;
       selectionKey_ = selectionKey;
       selectThread_ = selectThread;
@@ -542,10 +542,7 @@
      */
     private boolean internalRead() {
       try {
-        if (trans_.read(buffer_) < 0) {
-          return false;
-        }
-        return true;
+          return trans_.read(buffer_) >= 0;
       } catch (IOException e) {
         LOGGER.warn("Got an IOException in internalRead!", e);
         return false;
@@ -582,7 +579,7 @@
   } // FrameBuffer
 
   public class AsyncFrameBuffer extends FrameBuffer {
-    public AsyncFrameBuffer(TNonblockingTransport trans, SelectionKey selectionKey, AbstractSelectThread selectThread) {
+    public AsyncFrameBuffer(TNonblockingTransport trans, SelectionKey selectionKey, AbstractSelectThread selectThread) throws TTransportException {
       super(trans, selectionKey, selectThread);
     }
 
diff --git a/lib/java/src/org/apache/thrift/server/TNonblockingServer.java b/lib/java/src/org/apache/thrift/server/TNonblockingServer.java
index 79610b0..eac05a8 100644
--- a/lib/java/src/org/apache/thrift/server/TNonblockingServer.java
+++ b/lib/java/src/org/apache/thrift/server/TNonblockingServer.java
@@ -215,7 +215,7 @@
 
     protected FrameBuffer createFrameBuffer(final TNonblockingTransport trans,
         final SelectionKey selectionKey,
-        final AbstractSelectThread selectThread) {
+        final AbstractSelectThread selectThread) throws TTransportException {
         return processorFactory_.isAsyncProcessor() ?
                   new AsyncFrameBuffer(trans, selectionKey, selectThread) :
                   new FrameBuffer(trans, selectionKey, selectThread);
@@ -229,7 +229,7 @@
       TNonblockingTransport client = null;
       try {
         // accept the connection
-        client = (TNonblockingTransport)serverTransport.accept();
+        client = serverTransport.accept();
         clientKey = client.registerSelector(selector, SelectionKey.OP_READ);
 
         // add this key to the map
diff --git a/lib/java/src/org/apache/thrift/server/TThreadedSelectorServer.java b/lib/java/src/org/apache/thrift/server/TThreadedSelectorServer.java
index 038507e..095aacb 100644
--- a/lib/java/src/org/apache/thrift/server/TThreadedSelectorServer.java
+++ b/lib/java/src/org/apache/thrift/server/TThreadedSelectorServer.java
@@ -457,7 +457,7 @@
 
     private TNonblockingTransport doAccept() {
       try {
-        return (TNonblockingTransport) serverTransport.accept();
+        return serverTransport.accept();
       } catch (TTransportException tte) {
         // something went wrong accepting.
         LOGGER.warn("Exception trying to accept!", tte);
@@ -685,7 +685,7 @@
 
     protected FrameBuffer createFrameBuffer(final TNonblockingTransport trans,
         final SelectionKey selectionKey,
-        final AbstractSelectThread selectThread) {
+        final AbstractSelectThread selectThread) throws TTransportException {
         return processorFactory_.isAsyncProcessor() ?
                   new AsyncFrameBuffer(trans, selectionKey, selectThread) :
                   new FrameBuffer(trans, selectionKey, selectThread);
@@ -699,7 +699,7 @@
         FrameBuffer frameBuffer = createFrameBuffer(accepted, clientKey, SelectorThread.this);
 
         clientKey.attach(frameBuffer);
-      } catch (IOException e) {
+      } catch (IOException | TTransportException e) {
         LOGGER.warn("Failed to register accepted connection to selector!", e);
         if (clientKey != null) {
           cleanupSelectionKey(clientKey);
diff --git a/lib/java/src/org/apache/thrift/transport/AutoExpandingBuffer.java b/lib/java/src/org/apache/thrift/transport/AutoExpandingBuffer.java
index fc3aa92..b355d11 100644
--- a/lib/java/src/org/apache/thrift/transport/AutoExpandingBuffer.java
+++ b/lib/java/src/org/apache/thrift/transport/AutoExpandingBuffer.java
@@ -27,7 +27,7 @@
  * rate slightly faster than the requested capacity with the (untested)
  * objective of avoiding expensive buffer allocations and copies.
  */
-class AutoExpandingBuffer {
+public class AutoExpandingBuffer {
   private byte[] array;
 
   public AutoExpandingBuffer(int initialCapacity) {
diff --git a/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java b/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
index d06fec7..6fd4075 100644
--- a/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java
@@ -18,17 +18,20 @@
  */
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
+
 /**
  * TTransport for reading from an AutoExpandingBuffer.
  */
-public class AutoExpandingBufferReadTransport extends TTransport {
+public class AutoExpandingBufferReadTransport extends TEndpointTransport {
 
   private final AutoExpandingBuffer buf;
 
   private int pos = 0;
   private int limit = 0;
 
-  public AutoExpandingBufferReadTransport(int initialCapacity) {
+  public AutoExpandingBufferReadTransport(TConfiguration config, int initialCapacity) throws TTransportException {
+    super(config);
     this.buf = new AutoExpandingBuffer(initialCapacity);
   }
 
diff --git a/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java b/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java
index ec7e7d4..25f974a 100644
--- a/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java
@@ -18,10 +18,12 @@
  */
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
+
 /**
  * TTransport for writing to an AutoExpandingBuffer.
  */
-public final class AutoExpandingBufferWriteTransport extends TTransport {
+public final class AutoExpandingBufferWriteTransport extends TEndpointTransport {
 
   private final AutoExpandingBuffer buf;
   private int pos;
@@ -38,7 +40,8 @@
    * @throws IllegalArgumentException if frontReserve is less than zero
    * @throws IllegalArgumentException if frontReserve is greater than initialCapacity
    */
-  public AutoExpandingBufferWriteTransport(int initialCapacity, int frontReserve) {
+  public AutoExpandingBufferWriteTransport(TConfiguration config, int initialCapacity, int frontReserve) throws TTransportException {
+    super(config);
     if (initialCapacity < 1) {
       throw new IllegalArgumentException("initialCapacity");
     }
diff --git a/lib/java/src/org/apache/thrift/transport/TByteBuffer.java b/lib/java/src/org/apache/thrift/transport/TByteBuffer.java
index b6b0657..c792f3b 100644
--- a/lib/java/src/org/apache/thrift/transport/TByteBuffer.java
+++ b/lib/java/src/org/apache/thrift/transport/TByteBuffer.java
@@ -1,5 +1,7 @@
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
+
 import java.nio.BufferOverflowException;
 import java.nio.BufferUnderflowException;
 import java.nio.ByteBuffer;
@@ -7,14 +9,16 @@
 /**
  * ByteBuffer-backed implementation of TTransport.
  */
-public final class TByteBuffer extends TTransport {
+public final class TByteBuffer extends TEndpointTransport {
   private final ByteBuffer byteBuffer;
 
   /**
    * Creates a new TByteBuffer wrapping a given NIO ByteBuffer.
    */
-  public TByteBuffer(ByteBuffer byteBuffer) {
+  public TByteBuffer(ByteBuffer byteBuffer) throws TTransportException {
+    super(new TConfiguration());
     this.byteBuffer = byteBuffer;
+    updateKnownMessageSize(byteBuffer.capacity());
   }
 
   @Override
@@ -32,6 +36,9 @@
 
   @Override
   public int read(byte[] buf, int off, int len) throws TTransportException {
+    //
+    checkReadBytesAvailable(len);
+
     final int n = Math.min(byteBuffer.remaining(), len);
     if (n > 0) {
       try {
diff --git a/lib/java/src/org/apache/thrift/transport/TEndpointTransport.java b/lib/java/src/org/apache/thrift/transport/TEndpointTransport.java
new file mode 100644
index 0000000..f32efae
--- /dev/null
+++ b/lib/java/src/org/apache/thrift/transport/TEndpointTransport.java
@@ -0,0 +1,100 @@
+/*
+ * 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.
+ */
+package org.apache.thrift.transport;
+
+import org.apache.thrift.TConfiguration;
+
+import java.util.Objects;
+
+public abstract class TEndpointTransport extends TTransport{
+
+    protected long getMaxMessageSize() { return getConfiguration().getMaxMessageSize(); }
+
+    protected long knownMessageSize;
+    protected long remainingMessageSize;
+
+    private TConfiguration _configuration;
+    public TConfiguration getConfiguration() {
+        return _configuration;
+    }
+
+    public TEndpointTransport( TConfiguration config) throws TTransportException {
+        _configuration = Objects.isNull(config) ? new TConfiguration() : config;
+
+        resetConsumedMessageSize(-1);
+    }
+
+    /**
+     * Resets RemainingMessageSize to the configured maximum
+     * @param newSize
+     */
+    protected void resetConsumedMessageSize(long newSize) throws TTransportException {
+        // full reset
+        if (newSize < 0)
+        {
+            knownMessageSize = getMaxMessageSize();
+            remainingMessageSize = getMaxMessageSize();
+            return;
+        }
+
+        // update only: message size can shrink, but not grow
+        if (newSize > knownMessageSize)
+            throw new TTransportException(TTransportException.END_OF_FILE, "MaxMessageSize reached");
+
+        knownMessageSize = newSize;
+        remainingMessageSize = newSize;
+    }
+
+    /**
+     * Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport).
+     * Will throw if we already consumed too many bytes or if the new size is larger than allowed.
+     * @param size
+     */
+    public void updateKnownMessageSize(long size) throws TTransportException {
+        long consumed = knownMessageSize - remainingMessageSize;
+        resetConsumedMessageSize(size == 0 ? -1 : size);
+        countConsumedMessageBytes(consumed);
+    }
+
+    /**
+     * Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data
+     * @param numBytes
+     */
+    public void checkReadBytesAvailable(long numBytes) throws TTransportException {
+        if (remainingMessageSize < numBytes)
+            throw new TTransportException(TTransportException.END_OF_FILE, "MaxMessageSize reached");
+    }
+
+    /**
+     * Consumes numBytes from the RemainingMessageSize.
+     * @param numBytes
+     */
+    protected void countConsumedMessageBytes(long numBytes) throws TTransportException {
+        if (remainingMessageSize >= numBytes)
+        {
+            remainingMessageSize -= numBytes;
+        }
+        else
+        {
+            remainingMessageSize = 0;
+            throw new TTransportException(TTransportException.END_OF_FILE, "MaxMessageSize reached");
+        }
+    }
+
+}
diff --git a/lib/java/src/org/apache/thrift/transport/TFileTransport.java b/lib/java/src/org/apache/thrift/transport/TFileTransport.java
index 88b73e5..85f9708 100644
--- a/lib/java/src/org/apache/thrift/transport/TFileTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TFileTransport.java
@@ -26,13 +26,14 @@
 import java.io.IOException;
 import java.util.Random;
 
+import org.apache.thrift.TConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * FileTransport implementation of the TTransport interface.
  * Currently this is a straightforward port of the cpp implementation
- * 
+ *
  * It may make better sense to provide a basic stream access on top of the framed file format
  * The FileTransport can then be a user of this framed file format with some additional logic
  * for chunking.
@@ -44,7 +45,7 @@
   public static class TruncableBufferedInputStream extends BufferedInputStream {
     public void trunc() {
       pos = count = 0;
-    }        
+    }
     public TruncableBufferedInputStream(InputStream in) {
       super(in);
     }
@@ -62,7 +63,7 @@
     /**
      * Initialize an event. Initially, it has no valid contents
      *
-     * @param buf byte array buffer to store event 
+     * @param buf byte array buffer to store event
      */
     public Event(byte[] buf) {
       buf_ = buf;
@@ -88,9 +89,9 @@
 
       return(ndesired);
     }
-  };
+  }
 
-  public static class ChunkState {
+    public static class ChunkState {
     /**
      * Chunk Size. Must be same across all implementations
      */
@@ -111,7 +112,7 @@
     public long getOffset() { return (offset_);}
   }
 
-  public static enum TailPolicy {
+  public enum TailPolicy {
 
     NOWAIT(0, 0),
       WAIT_FOREVER(500, -1);
@@ -148,13 +149,13 @@
   TailPolicy currentPolicy_ = TailPolicy.NOWAIT;
 
 
-  /** 
+  /**
    * Underlying file being read
    */
   protected TSeekableFile inputFile_ = null;
 
-  /** 
-   * Underlying outputStream 
+  /**
+   * Underlying outputStream
    */
   protected OutputStream outputStream_ = null;
 
@@ -181,7 +182,7 @@
 
   /**
    * Get File Tailing Policy
-   * 
+   *
    * @return current read policy
    */
   public TailPolicy getTailPolicy() {
@@ -190,7 +191,7 @@
 
   /**
    * Set file Tailing Policy
-   * 
+   *
    * @param policy New policy to set
    * @return Old policy
    */
@@ -203,7 +204,7 @@
 
   /**
    * Initialize read input stream
-   * 
+   *
    * @return input stream to read from file
    */
   private InputStream createInputStream() throws TTransportException {
@@ -223,7 +224,7 @@
 
   /**
    * Read (potentially tailing) an input stream
-   * 
+   *
    * @param is InputStream to read from
    * @param buf Buffer to read into
    * @param off Offset in buffer to read into
@@ -232,7 +233,7 @@
    *
    * @return number of bytes read
    */
-  private int tailRead(InputStream is, byte[] buf, 
+  private int tailRead(InputStream is, byte[] buf,
                        int off, int len, TailPolicy tp) throws TTransportException {
     int orig_len = len;
     try {
@@ -322,7 +323,7 @@
       // check if event is corrupted and do recovery as required
       if(esize > cs.getRemaining()) {
         throw new TTransportException("FileTransport error: bad event size");
-        /*        
+        /*
                   if(performRecovery()) {
                   esize=0;
                   } else {
@@ -361,7 +362,7 @@
    * Files are not opened in ctor - but in explicit open call
    */
   public void open() throws TTransportException {
-    if (isOpen()) 
+    if (isOpen())
       throw new TTransportException(TTransportException.ALREADY_OPEN);
 
     try {
@@ -406,7 +407,7 @@
    *
    * @param path File path to read and write from
    * @param readOnly Whether this is a read-only transport
-   */ 
+   */
   public TFileTransport(final String path, boolean readOnly) throws IOException {
     inputFile_ = new TStandardFile(path);
     readOnly_ = readOnly;
@@ -457,8 +458,8 @@
    * @throws TTransportException if there was an error reading data
    */
   public int read(byte[] buf, int off, int len) throws TTransportException {
-    if(!isOpen()) 
-      throw new TTransportException(TTransportException.NOT_OPEN, 
+    if(!isOpen())
+      throw new TTransportException(TTransportException.NOT_OPEN,
                                     "Must open before reading");
 
     if(currentEvent_.getRemaining() == 0) {
@@ -471,14 +472,14 @@
   }
 
   public int getNumChunks() throws TTransportException {
-    if(!isOpen()) 
-      throw new TTransportException(TTransportException.NOT_OPEN, 
+    if(!isOpen())
+      throw new TTransportException(TTransportException.NOT_OPEN,
                                     "Must open before getNumChunks");
     try {
       long len = inputFile_.length();
       if(len == 0)
         return 0;
-      else 
+      else
         return (((int)(len/cs.getChunkSize())) + 1);
 
     } catch (IOException iox) {
@@ -487,8 +488,8 @@
   }
 
   public int getCurChunk() throws TTransportException {
-    if(!isOpen()) 
-      throw new TTransportException(TTransportException.NOT_OPEN, 
+    if(!isOpen())
+      throw new TTransportException(TTransportException.NOT_OPEN,
                                     "Must open before getCurChunk");
     return (cs.getChunkNum());
 
@@ -496,8 +497,8 @@
 
 
   public void seekToChunk(int chunk) throws TTransportException {
-    if(!isOpen()) 
-      throw new TTransportException(TTransportException.NOT_OPEN, 
+    if(!isOpen())
+      throw new TTransportException(TTransportException.NOT_OPEN,
                                     "Must open before seeking");
 
     int numChunks = getNumChunks();
@@ -527,7 +528,7 @@
     }
 
     if(chunk*cs.getChunkSize() != cs.getOffset()) {
-      try { inputFile_.seek((long)chunk*cs.getChunkSize()); } 
+      try { inputFile_.seek((long)chunk*cs.getChunkSize()); }
       catch (IOException iox) {
         throw new TTransportException("Seek to chunk " +
                                       chunk + " " +iox.getMessage(), iox);
@@ -549,8 +550,8 @@
   }
 
   public void seekToEnd() throws TTransportException {
-    if(!isOpen()) 
-      throw new TTransportException(TTransportException.NOT_OPEN, 
+    if(!isOpen())
+      throw new TTransportException(TTransportException.NOT_OPEN,
                                     "Must open before seeking");
     seekToChunk(getNumChunks());
   }
@@ -577,9 +578,25 @@
     throw new TTransportException("Not Supported");
   }
 
+
+  @Override
+  public TConfiguration getConfiguration() {
+    return null;
+  }
+
+  @Override
+  public void updateKnownMessageSize(long size) throws TTransportException {
+
+  }
+
+  @Override
+  public void checkReadBytesAvailable(long numBytes) throws TTransportException {
+
+  }
+
   /**
    * test program
-   * 
+   *
    */
   public static void main(String[] args) throws Exception {
 
@@ -594,7 +611,7 @@
       try {
         num_chunks = Integer.parseInt(args[1]);
       } catch (Exception e) {
-        LOGGER.error("Cannot parse " + args[1]); 
+        LOGGER.error("Cannot parse " + args[1]);
         printUsage();
       }
     }
diff --git a/lib/java/src/org/apache/thrift/transport/THttpClient.java b/lib/java/src/org/apache/thrift/transport/THttpClient.java
index c3063fe..7d61b5c 100644
--- a/lib/java/src/org/apache/thrift/transport/THttpClient.java
+++ b/lib/java/src/org/apache/thrift/transport/THttpClient.java
@@ -37,6 +37,7 @@
 import org.apache.http.client.methods.HttpPost;
 import org.apache.http.entity.ByteArrayEntity;
 import org.apache.http.params.CoreConnectionPNames;
+import org.apache.thrift.TConfiguration;
 
 /**
  * HTTP implementation of the TTransport interface. Used for working with a
@@ -51,7 +52,7 @@
  * HttpClient to THttpClient(String url, HttpClient client) will create an
  * instance which will use HttpURLConnection.
  *
- * When using HttpClient, the following configuration leads to 5-15% 
+ * When using HttpClient, the following configuration leads to 5-15%
  * better performance than the HttpURLConnection implementation:
  *
  * http.protocol.version=HttpVersion.HTTP_1_1
@@ -65,7 +66,7 @@
  * @see <a href="https://issues.apache.org/jira/browse/THRIFT-970">THRIFT-970</a>
  */
 
-public class THttpClient extends TTransport {
+public class THttpClient extends TEndpointTransport {
 
   private URL url_ = null;
 
@@ -80,14 +81,14 @@
   private Map<String,String> customHeaders_ = null;
 
   private final HttpHost host;
-  
+
   private final HttpClient client;
-  
+
   public static class Factory extends TTransportFactory {
-    
+
     private final String url;
     private final HttpClient client;
-    
+
     public Factory(String url) {
       this.url = url;
       this.client = null;
@@ -97,14 +98,14 @@
       this.url = url;
       this.client = client;
     }
-    
+
     @Override
     public TTransport getTransport(TTransport trans) {
       try {
         if (null != client) {
-          return new THttpClient(url, client);
+          return new THttpClient(trans.getConfiguration(), url, client);
         } else {
-          return new THttpClient(url);
+          return new THttpClient(trans.getConfiguration(), url);
         }
       } catch (TTransportException tte) {
         return null;
@@ -112,7 +113,8 @@
     }
   }
 
-  public THttpClient(String url) throws TTransportException {
+  public THttpClient(TConfiguration config, String url) throws TTransportException {
+    super(config);
     try {
       url_ = new URL(url);
       this.client = null;
@@ -122,7 +124,30 @@
     }
   }
 
+  public THttpClient(String url) throws TTransportException {
+    super(new TConfiguration());
+    try {
+      url_ = new URL(url);
+      this.client = null;
+      this.host = null;
+    } catch (IOException iox) {
+      throw new TTransportException(iox);
+    }
+  }
+
+  public THttpClient(TConfiguration config, String url, HttpClient client) throws TTransportException {
+    super(config);
+    try {
+      url_ = new URL(url);
+      this.client = client;
+      this.host = new HttpHost(url_.getHost(), -1 == url_.getPort() ? url_.getDefaultPort() : url_.getPort(), url_.getProtocol());
+    } catch (IOException iox) {
+      throw new TTransportException(iox);
+    }
+  }
+
   public THttpClient(String url, HttpClient client) throws TTransportException {
+    super(new TConfiguration());
     try {
       url_ = new URL(url);
       this.client = client;
@@ -168,7 +193,6 @@
       try {
         inputStream_.close();
       } catch (IOException ioe) {
-        ;
       }
       inputStream_ = null;
     }
@@ -182,11 +206,16 @@
     if (inputStream_ == null) {
       throw new TTransportException("Response buffer is empty, no request.");
     }
+
+    checkReadBytesAvailable(len);
+
     try {
       int ret = inputStream_.read(buf, off, len);
       if (ret == -1) {
         throw new TTransportException("No more data available.");
       }
+      countConsumedMessageBytes(ret);
+
       return ret;
     } catch (IOException iox) {
       throw new TTransportException(iox);
@@ -214,7 +243,7 @@
   }
 
   private void flushUsingHttpClient() throws TTransportException {
-    
+
     if (null == this.client) {
       throw new TTransportException("Null HttpClient, aborting.");
     }
@@ -224,22 +253,22 @@
     requestBuffer_.reset();
 
     HttpPost post = null;
-    
+
     InputStream is = null;
-    
-    try {      
+
+    try {
       // Set request to path + query string
       post = new HttpPost(this.url_.getFile());
-      
+
       //
       // Headers are added to the HttpPost instance, not
       // to HttpClient.
       //
-      
+
       post.setHeader("Content-Type", "application/x-thrift");
       post.setHeader("Accept", "application/x-thrift");
       post.setHeader("User-Agent", "Java/THttpClient/HC");
-      
+
       if (null != customHeaders_) {
         for (Map.Entry<String, String> header : customHeaders_.entrySet()) {
           post.setHeader(header.getKey(), header.getValue());
@@ -247,17 +276,17 @@
       }
 
       post.setEntity(new ByteArrayEntity(data));
-      
+
       HttpResponse response = this.client.execute(this.host, post);
       int responseCode = response.getStatusLine().getStatusCode();
 
-      //      
+      //
       // Retrieve the inputstream BEFORE checking the status code so
       // resources get freed in the finally clause.
       //
 
       is = response.getEntity().getContent();
-      
+
       if (responseCode != HttpStatus.SC_OK) {
         throw new TTransportException("HTTP Response code: " + responseCode);
       }
@@ -268,10 +297,10 @@
       // thrift struct is being read up the chain).
       // Proceeding differently might lead to exhaustion of connections and thus
       // to app failure.
-      
+
       byte[] buf = new byte[1024];
       ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      
+
       int len = 0;
       do {
         len = is.read(buf);
@@ -279,7 +308,7 @@
           baos.write(buf, 0, len);
         }
       } while (-1 != len);
-      
+
       try {
         // Indicate we're done with the content.
         consume(response.getEntity());
@@ -287,7 +316,7 @@
         // We ignore this exception, it might only mean the server has no
         // keep-alive capability.
       }
-            
+
       inputStream_ = new ByteArrayInputStream(baos.toByteArray());
     } catch (IOException ioe) {
       // Abort method so the connection gets released back to the connection manager
@@ -296,6 +325,7 @@
       }
       throw new TTransportException(ioe);
     } finally {
+      resetConsumedMessageSize(-1);
       if (null != is) {
         // Close the entity's input stream, this will release the underlying connection
         try {
@@ -357,6 +387,8 @@
 
     } catch (IOException iox) {
       throw new TTransportException(iox);
+    } finally {
+      resetConsumedMessageSize(-1);
     }
   }
 }
diff --git a/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java b/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java
index d97d506..763e66a 100644
--- a/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java
@@ -19,6 +19,7 @@
 
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,7 +34,7 @@
  * has to provide a variety of types of streams.
  *
  */
-public class TIOStreamTransport extends TTransport {
+public class TIOStreamTransport extends TEndpointTransport {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(TIOStreamTransport.class.getName());
 
@@ -47,23 +48,69 @@
    * Subclasses can invoke the default constructor and then assign the input
    * streams in the open method.
    */
-  protected TIOStreamTransport() {}
+  protected TIOStreamTransport(TConfiguration config) throws TTransportException {
+    super(config);
+  }
 
   /**
+   * Subclasses can invoke the default constructor and then assign the input
+   * streams in the open method.
+   */
+  protected TIOStreamTransport() throws TTransportException {
+    super(new TConfiguration());
+  }
+
+  /**
+   * Input stream constructor, constructs an input only transport.
+   *
+   * @param config
+   * @param is Input stream to read from
+   */
+  public TIOStreamTransport(TConfiguration config, InputStream is) throws TTransportException {
+    super(config);
+    inputStream_ = is;
+  }
+  /**
    * Input stream constructor, constructs an input only transport.
    *
    * @param is Input stream to read from
    */
-  public TIOStreamTransport(InputStream is) {
+  public TIOStreamTransport(InputStream is) throws TTransportException {
+    super(new TConfiguration());
     inputStream_ = is;
   }
 
   /**
    * Output stream constructor, constructs an output only transport.
    *
+   * @param config
+   * @param os Output stream to write to
+   */
+  public TIOStreamTransport(TConfiguration config, OutputStream os) throws TTransportException {
+    super(config);
+    outputStream_ = os;
+  }
+
+  /**
+   * Output stream constructor, constructs an output only transport.
+   *
    * @param os Output stream to write to
    */
-  public TIOStreamTransport(OutputStream os) {
+  public TIOStreamTransport(OutputStream os) throws TTransportException {
+    super(new TConfiguration());
+    outputStream_ = os;
+  }
+
+  /**
+   * Two-way stream constructor.
+   *
+   * @param config
+   * @param is Input stream to read from
+   * @param os Output stream to read from
+   */
+  public TIOStreamTransport(TConfiguration config, InputStream is, OutputStream os) throws TTransportException {
+    super(config);
+    inputStream_ = is;
     outputStream_ = os;
   }
 
@@ -73,7 +120,8 @@
    * @param is Input stream to read from
    * @param os Output stream to read from
    */
-  public TIOStreamTransport(InputStream is, OutputStream os) {
+  public TIOStreamTransport(InputStream is, OutputStream os) throws TTransportException {
+    super(new TConfiguration());
     inputStream_ = is;
     outputStream_ = os;
   }
@@ -158,6 +206,9 @@
     }
     try {
       outputStream_.flush();
+
+      resetConsumedMessageSize(-1);
+
     } catch (IOException iox) {
       throw new TTransportException(TTransportException.UNKNOWN, iox);
     }
diff --git a/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java b/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java
index b19ac86..c3a3eb4 100644
--- a/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java
+++ b/lib/java/src/org/apache/thrift/transport/TMemoryBuffer.java
@@ -20,12 +20,14 @@
 package org.apache.thrift.transport;
 
 import org.apache.thrift.TByteArrayOutputStream;
+import org.apache.thrift.TConfiguration;
+
 import java.nio.charset.Charset;
 
 /**
  * Memory buffer-based implementation of the TTransport interface.
  */
-public class TMemoryBuffer extends TTransport {
+public class TMemoryBuffer extends TEndpointTransport {
   /**
    * Create a TMemoryBuffer with an initial buffer size of <i>size</i>. The
    * internal buffer will grow as necessary to accommodate the size of the data
@@ -33,8 +35,24 @@
    *
    * @param size the initial size of the buffer
    */
-  public TMemoryBuffer(int size) {
+  public TMemoryBuffer(int size) throws TTransportException {
+    super(new TConfiguration());
     arr_ = new TByteArrayOutputStream(size);
+    updateKnownMessageSize(size);
+  }
+
+  /**
+   * Create a TMemoryBuffer with an initial buffer size of <i>size</i>. The
+   * internal buffer will grow as necessary to accommodate the size of the data
+   * being written to it.
+   *
+   * @param config
+   * @param size the initial size of the buffer
+   */
+  public TMemoryBuffer(TConfiguration config, int size) throws TTransportException {
+    super(config);
+    arr_ = new TByteArrayOutputStream(size);
+    updateKnownMessageSize(size);
   }
 
   @Override
@@ -53,9 +71,11 @@
   }
 
   @Override
-  public int read(byte[] buf, int off, int len) {
+  public int read(byte[] buf, int off, int len) throws TTransportException {
+    checkReadBytesAvailable(len);
     byte[] src = arr_.get();
     int amtToRead = (len > arr_.len() - pos_ ? arr_.len() - pos_ : len);
+
     if (amtToRead > 0) {
       System.arraycopy(src, pos_, buf, off, amtToRead);
       pos_ += amtToRead;
diff --git a/lib/java/src/org/apache/thrift/transport/TMemoryInputTransport.java b/lib/java/src/org/apache/thrift/transport/TMemoryInputTransport.java
index 2530dcc..6cb06fc 100644
--- a/lib/java/src/org/apache/thrift/transport/TMemoryInputTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TMemoryInputTransport.java
@@ -18,21 +18,38 @@
  */
 package org.apache.thrift.transport;
 
-public final class TMemoryInputTransport extends TTransport {
+import org.apache.thrift.TConfiguration;
+
+public final class TMemoryInputTransport extends TEndpointTransport {
 
   private byte[] buf_;
   private int pos_;
   private int endPos_;
 
-  public TMemoryInputTransport() {
+  public TMemoryInputTransport() throws TTransportException {
+    this(new TConfiguration());
   }
 
-  public TMemoryInputTransport(byte[] buf) {
-    reset(buf);
+  public TMemoryInputTransport(TConfiguration _configuration) throws TTransportException {
+    this(_configuration, new byte[0]);
   }
 
-  public TMemoryInputTransport(byte[] buf, int offset, int length) {
+  public TMemoryInputTransport(byte[] buf) throws TTransportException {
+    this(new TConfiguration(), buf);
+  }
+
+  public TMemoryInputTransport(TConfiguration _configuration, byte[] buf) throws TTransportException {
+    this(_configuration, buf, 0, buf.length);
+  }
+
+  public TMemoryInputTransport(byte[] buf, int offset, int length) throws TTransportException {
+    this(new TConfiguration(), buf, offset, length);
+  }
+
+  public TMemoryInputTransport(TConfiguration _configuration, byte[] buf, int offset, int length) throws TTransportException {
+    super(_configuration);
     reset(buf, offset, length);
+    updateKnownMessageSize(length);
   }
 
   public void reset(byte[] buf) {
@@ -43,10 +60,20 @@
     buf_ = buf;
     pos_ = offset;
     endPos_ = offset + length;
+    try {
+      resetConsumedMessageSize(-1);
+    } catch (TTransportException e) {
+      // ignore
+    }
   }
 
   public void clear() {
     buf_ = null;
+    try {
+      resetConsumedMessageSize(-1);
+    } catch (TTransportException e) {
+      // ignore
+    }
   }
 
   @Override
@@ -67,6 +94,7 @@
     if (amtToRead > 0) {
       System.arraycopy(buf_, pos_, buf, off, amtToRead);
       consumeBuffer(amtToRead);
+      countConsumedMessageBytes(amtToRead);
     }
     return amtToRead;
   }
diff --git a/lib/java/src/org/apache/thrift/transport/TMemoryTransport.java b/lib/java/src/org/apache/thrift/transport/TMemoryTransport.java
index f41bc09..0172ca8 100644
--- a/lib/java/src/org/apache/thrift/transport/TMemoryTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TMemoryTransport.java
@@ -22,18 +22,28 @@
 import java.nio.ByteBuffer;
 
 import org.apache.thrift.TByteArrayOutputStream;
+import org.apache.thrift.TConfiguration;
 
 /**
  * In memory transport with separate buffers for input and output.
  */
-public class TMemoryTransport extends TTransport {
+public class TMemoryTransport extends TEndpointTransport {
 
   private final ByteBuffer inputBuffer;
   private final TByteArrayOutputStream outputBuffer;
 
-  public TMemoryTransport(byte[] input) {
+  public TMemoryTransport(byte[] input) throws TTransportException {
+    super(new TConfiguration());
     inputBuffer = ByteBuffer.wrap(input);
     outputBuffer = new TByteArrayOutputStream(1024);
+    updateKnownMessageSize(input.length);
+  }
+
+  public TMemoryTransport(TConfiguration config, byte[] input) throws TTransportException {
+    super(config);
+    inputBuffer = ByteBuffer.wrap(input);
+    outputBuffer = new TByteArrayOutputStream(1024);
+    updateKnownMessageSize(input.length);
   }
 
   @Override
@@ -56,6 +66,7 @@
 
   @Override
   public int read(byte[] buf, int off, int len) throws TTransportException {
+    checkReadBytesAvailable(len);
     int remaining = inputBuffer.remaining();
     if (remaining < len) {
       throw new TTransportException(TTransportException.END_OF_FILE,
diff --git a/lib/java/src/org/apache/thrift/transport/TNonblockingSocket.java b/lib/java/src/org/apache/thrift/transport/TNonblockingSocket.java
index 37a66d6..76ed02c 100644
--- a/lib/java/src/org/apache/thrift/transport/TNonblockingSocket.java
+++ b/lib/java/src/org/apache/thrift/transport/TNonblockingSocket.java
@@ -30,6 +30,7 @@
 import java.nio.channels.Selector;
 import java.nio.channels.SocketChannel;
 
+import org.apache.thrift.TConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,7 +48,7 @@
 
   private final SocketChannel socketChannel_;
 
-  public TNonblockingSocket(String host, int port) throws IOException {
+  public TNonblockingSocket(String host, int port) throws IOException, TTransportException {
     this(host, port, 0);
   }
 
@@ -57,7 +58,7 @@
    * @param port
    * @throws IOException
    */
-  public TNonblockingSocket(String host, int port, int timeout) throws IOException {
+  public TNonblockingSocket(String host, int port, int timeout) throws IOException, TTransportException {
     this(SocketChannel.open(), timeout, new InetSocketAddress(host, port));
   }
 
@@ -67,13 +68,19 @@
    * @param socketChannel Already created SocketChannel object
    * @throws IOException if there is an error setting up the streams
    */
-  public TNonblockingSocket(SocketChannel socketChannel) throws IOException {
+  public TNonblockingSocket(SocketChannel socketChannel) throws IOException, TTransportException {
     this(socketChannel, 0, null);
     if (!socketChannel.isConnected()) throw new IOException("Socket must already be connected");
   }
 
   private TNonblockingSocket(SocketChannel socketChannel, int timeout, SocketAddress socketAddress)
-      throws IOException {
+          throws IOException, TTransportException {
+    this(new TConfiguration(), socketChannel, timeout, socketAddress);
+  }
+
+  private TNonblockingSocket(TConfiguration config, SocketChannel socketChannel, int timeout, SocketAddress socketAddress)
+          throws IOException, TTransportException {
+    super(config);
     socketChannel_ = socketChannel;
     socketAddress_ = socketAddress;
 
diff --git a/lib/java/src/org/apache/thrift/transport/TNonblockingTransport.java b/lib/java/src/org/apache/thrift/transport/TNonblockingTransport.java
index 43c1306..255595d 100644
--- a/lib/java/src/org/apache/thrift/transport/TNonblockingTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TNonblockingTransport.java
@@ -19,13 +19,19 @@
 
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
+
 import java.io.IOException;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 
-public abstract class TNonblockingTransport extends TTransport {
+public abstract class TNonblockingTransport extends TEndpointTransport {
+
+  public TNonblockingTransport(TConfiguration config) throws TTransportException {
+    super(config);
+  }
 
   /**
    * Non-blocking connection initialization.
diff --git a/lib/java/src/org/apache/thrift/transport/TSSLTransportFactory.java b/lib/java/src/org/apache/thrift/transport/TSSLTransportFactory.java
index 570f533..3389e4d 100644
--- a/lib/java/src/org/apache/thrift/transport/TSSLTransportFactory.java
+++ b/lib/java/src/org/apache/thrift/transport/TSSLTransportFactory.java
@@ -45,7 +45,7 @@
  *  TSocket and TServerSocket
  */
 public class TSSLTransportFactory {
-  
+
   private static final Logger LOGGER =
       LoggerFactory.getLogger(TSSLTransportFactory.class);
 
@@ -350,7 +350,7 @@
       }
       isKeyStoreSet = true;
     }
-    
+
     /**
      * Set the keystore, password, certificate type and the store type
      *
@@ -363,7 +363,7 @@
     	this.keyStoreStream = keyStoreStream;
     	setKeyStore("", keyPass, keyManagerType, keyStoreType);
     }
-    
+
     /**
      * Set the keystore and password
      *
@@ -373,7 +373,7 @@
     public void setKeyStore(String keyStore, String keyPass) {
       setKeyStore(keyStore, keyPass, null, null);
     }
-    
+
     /**
      * Set the keystore and password
      *
@@ -383,7 +383,7 @@
     public void setKeyStore(InputStream keyStoreStream, String keyPass) {
       setKeyStore(keyStoreStream, keyPass, null, null);
     }
-    
+
     /**
      * Set the truststore, password, certificate type and the store type
      *
@@ -403,7 +403,7 @@
       }
       isTrustStoreSet = true;
     }
-    
+
     /**
      * Set the truststore, password, certificate type and the store type
      *
@@ -426,7 +426,7 @@
     public void setTrustStore(String trustStore, String trustPass) {
       setTrustStore(trustStore, trustPass, null, null);
     }
-    
+
     /**
      * Set the truststore and password
      *
diff --git a/lib/java/src/org/apache/thrift/transport/TSaslClientTransport.java b/lib/java/src/org/apache/thrift/transport/TSaslClientTransport.java
index 5fc7cff..e5ca418 100644
--- a/lib/java/src/org/apache/thrift/transport/TSaslClientTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TSaslClientTransport.java
@@ -47,14 +47,14 @@
 
   /**
    * Uses the given <code>SaslClient</code>.
-   * 
+   *
    * @param saslClient
    *          The <code>SaslClient</code> to use for the subsequent SASL
    *          negotiation.
    * @param transport
    *          Transport underlying this one.
    */
-  public TSaslClientTransport(SaslClient saslClient, TTransport transport) {
+  public TSaslClientTransport(SaslClient saslClient, TTransport transport) throws TTransportException {
     super(saslClient, transport);
     mechanism = saslClient.getMechanismName();
   }
@@ -63,14 +63,14 @@
    * Creates a <code>SaslClient</code> using the given SASL-specific parameters.
    * See the Java documentation for <code>Sasl.createSaslClient</code> for the
    * details of the parameters.
-   * 
+   *
    * @param transport
    *          The underlying Thrift transport.
    * @throws SaslException
    */
   public TSaslClientTransport(String mechanism, String authorizationId, String protocol,
       String serverName, Map<String, String> props, CallbackHandler cbh, TTransport transport)
-      throws SaslException {
+          throws SaslException, TTransportException {
     super(Sasl.createSaslClient(new String[] { mechanism }, authorizationId, protocol, serverName,
         props, cbh), transport);
     this.mechanism = mechanism;
diff --git a/lib/java/src/org/apache/thrift/transport/TSaslServerTransport.java b/lib/java/src/org/apache/thrift/transport/TSaslServerTransport.java
index 31f309e..9111712 100644
--- a/lib/java/src/org/apache/thrift/transport/TSaslServerTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TSaslServerTransport.java
@@ -58,7 +58,7 @@
    * @param transport
    *          Transport underlying this one.
    */
-  public TSaslServerTransport(TTransport transport) {
+  public TSaslServerTransport(TTransport transport) throws TTransportException {
     super(transport);
   }
 
@@ -71,12 +71,12 @@
    *          The underlying Thrift transport.
    */
   public TSaslServerTransport(String mechanism, String protocol, String serverName,
-      Map<String, String> props, CallbackHandler cbh, TTransport transport) {
+      Map<String, String> props, CallbackHandler cbh, TTransport transport) throws TTransportException {
     super(transport);
     addServerDefinition(mechanism, protocol, serverName, props, cbh);
   }
 
-  private TSaslServerTransport(Map<String, TSaslServerDefinition> serverDefinitionMap, TTransport transport) {
+  private TSaslServerTransport(Map<String, TSaslServerDefinition> serverDefinitionMap, TTransport transport) throws TTransportException {
     super(transport);
     this.serverDefinitionMap.putAll(serverDefinitionMap);
   }
@@ -190,7 +190,7 @@
      * receives the same <code>TSaslServerTransport</code>.
      */
     @Override
-    public TTransport getTransport(TTransport base) {
+    public TTransport getTransport(TTransport base) throws TTransportException {
       WeakReference<TSaslServerTransport> ret = transportMap.get(base);
       if (ret == null || ret.get() == null) {
         LOGGER.debug("transport map does not contain key", base);
diff --git a/lib/java/src/org/apache/thrift/transport/TSaslTransport.java b/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
index d1a3d31..b106c70 100644
--- a/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
@@ -20,6 +20,7 @@
 package org.apache.thrift.transport;
 
 import java.nio.charset.StandardCharsets;
+import java.util.Objects;
 
 import javax.security.sasl.Sasl;
 import javax.security.sasl.SaslClient;
@@ -28,6 +29,8 @@
 
 import org.apache.thrift.EncodingUtils;
 import org.apache.thrift.TByteArrayOutputStream;
+import org.apache.thrift.TConfiguration;
+import org.apache.thrift.transport.layered.TFramedTransport;
 import org.apache.thrift.transport.sasl.NegotiationStatus;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -36,7 +39,7 @@
  * A superclass for SASL client/server thrift transports. A subclass need only
  * implement the <code>open</code> method.
  */
-abstract class TSaslTransport extends TTransport {
+abstract class TSaslTransport extends TEndpointTransport {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(TSaslTransport.class);
 
@@ -83,7 +86,8 @@
    * @param underlyingTransport
    *          The thrift transport which this transport is wrapping.
    */
-  protected TSaslTransport(TTransport underlyingTransport) {
+  protected TSaslTransport(TTransport underlyingTransport) throws TTransportException {
+    super(Objects.isNull(underlyingTransport.getConfiguration()) ? new TConfiguration() : underlyingTransport.getConfiguration());
     this.underlyingTransport = underlyingTransport;
   }
 
@@ -96,7 +100,8 @@
    * @param underlyingTransport
    *          The thrift transport which this transport is wrapping.
    */
-  protected TSaslTransport(SaslClient saslClient, TTransport underlyingTransport) {
+  protected TSaslTransport(SaslClient saslClient, TTransport underlyingTransport) throws TTransportException {
+    super(Objects.isNull(underlyingTransport.getConfiguration()) ? new TConfiguration() : underlyingTransport.getConfiguration());
     sasl = new SaslParticipant(saslClient);
     this.underlyingTransport = underlyingTransport;
   }
@@ -151,7 +156,7 @@
     }
 
     int payloadBytes = EncodingUtils.decodeBigEndian(messageHeader, STATUS_BYTES);
-    if (payloadBytes < 0 || payloadBytes > 104857600 /* 100 MB */) {
+    if (payloadBytes < 0 || payloadBytes > getConfiguration().getMaxMessageSize() /* 100 MB */) {
       throw sendAndThrowMessage(
         NegotiationStatus.ERROR, "Invalid payload header length: " + payloadBytes);
     }
diff --git a/lib/java/src/org/apache/thrift/transport/TSimpleFileTransport.java b/lib/java/src/org/apache/thrift/transport/TSimpleFileTransport.java
index 42102d9..c1bbd48 100644
--- a/lib/java/src/org/apache/thrift/transport/TSimpleFileTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TSimpleFileTransport.java
@@ -18,6 +18,8 @@
  */
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
+
 import java.io.IOException;
 import java.io.RandomAccessFile;
 
@@ -25,26 +27,43 @@
 /**
  * Basic file support for the TTransport interface
  */
-public final class TSimpleFileTransport extends TTransport {
+public final class TSimpleFileTransport extends TEndpointTransport {
 
-  private RandomAccessFile file = null;   
-  private boolean readable;               
-  private boolean writable;               
-  private String path_;               
+  private RandomAccessFile file = null;
+  private boolean readable;
+  private boolean writable;
+  private String path_;
 
 
   /**
-   * Create a transport backed by a simple file 
-   * 
+   * Create a transport backed by a simple file
+   *
    * @param path the path to the file to open/create
    * @param read true to support read operations
    * @param write true to support write operations
    * @param openFile true to open the file on construction
    * @throws TTransportException if file open fails
    */
-  public TSimpleFileTransport(String path, boolean read, 
+  public TSimpleFileTransport(String path, boolean read,
                               boolean write, boolean openFile)
           throws TTransportException {
+    this(new TConfiguration(), path, read, write, openFile);
+  }
+
+  /**
+   * Create a transport backed by a simple file
+   *
+   * @param config
+   * @param path the path to the file to open/create
+   * @param read true to support read operations
+   * @param write true to support write operations
+   * @param openFile true to open the file on construction
+   * @throws TTransportException if file open fails
+   */
+  public TSimpleFileTransport(TConfiguration config, String path, boolean read,
+                              boolean write, boolean openFile)
+          throws TTransportException {
+    super(config);
     if (path.length() <= 0) {
       throw new TTransportException("No path specified");
     }
@@ -58,11 +77,11 @@
       open();
     }
   }
-  
+
   /**
-   * Create a transport backed by a simple file 
+   * Create a transport backed by a simple file
    * Implicitly opens file to conform to C++ behavior.
-   * 
+   *
    * @param path the path to the file to open/create
    * @param read true to support read operations
    * @param write true to support write operations
@@ -72,7 +91,7 @@
           throws TTransportException {
     this(path, read, write, true);
   }
-  
+
   /**
    * Create a transport backed by a simple read only disk file (implicitly opens
    * file)
@@ -95,7 +114,7 @@
   }
 
   /**
-   * Open file if not previously opened. 
+   * Open file if not previously opened.
    *
    * @throws TTransportException if open fails
    */
@@ -111,7 +130,7 @@
       } catch (IOException ioe) {
         file = null;
         throw new TTransportException(ioe.getMessage());
-      }      
+      }
     }
   }
 
@@ -131,7 +150,7 @@
   }
 
   /**
-   * Read up to len many bytes into buf at offset 
+   * Read up to len many bytes into buf at offset
    *
    * @param buf houses bytes read
    * @param off offset into buff to begin writing to
@@ -144,6 +163,7 @@
     if (!readable) {
       throw new TTransportException("Read operation on write only file");
     }
+    checkReadBytesAvailable(len);
     int iBytesRead = 0;
     try {
       iBytesRead = file.read(buf, off, len);
@@ -155,7 +175,7 @@
   }
 
   /**
-   * Write len many bytes from buff starting at offset 
+   * Write len many bytes from buff starting at offset
    *
    * @param buf buffer containing bytes to write
    * @param off offset into buffer to begin writing from
@@ -213,4 +233,4 @@
       throw new TTransportException(ex.getMessage());
     }
   }
-}
\ No newline at end of file
+}
diff --git a/lib/java/src/org/apache/thrift/transport/TSocket.java b/lib/java/src/org/apache/thrift/transport/TSocket.java
index b20b32b..eb73e8e 100644
--- a/lib/java/src/org/apache/thrift/transport/TSocket.java
+++ b/lib/java/src/org/apache/thrift/transport/TSocket.java
@@ -19,6 +19,7 @@
 
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -69,6 +70,7 @@
    * @throws TTransportException if there is an error setting up the streams
    */
   public TSocket(Socket socket) throws TTransportException {
+    super(new TConfiguration());
     socket_ = socket;
     try {
       socket_.setSoLinger(false, 0);
@@ -93,23 +95,36 @@
    * Creates a new unconnected socket that will connect to the given host
    * on the given port.
    *
+   * @param config  check config
    * @param host Remote host
    * @param port Remote port
    */
-  public TSocket(String host, int port) {
-    this(host, port, 0);
+  public TSocket(TConfiguration config, String host, int port) throws TTransportException {
+    this(config, host, port, 0);
   }
 
   /**
    * Creates a new unconnected socket that will connect to the given host
    * on the given port.
    *
+   * @param host Remote host
+   * @param port Remote port
+   */
+  public TSocket(String host, int port) throws TTransportException {
+    this(new TConfiguration(), host, port, 0);
+  }
+
+  /**
+   * Creates a new unconnected socket that will connect to the given host
+   * on the given port.
+   *
+   * @param config  check config
    * @param host    Remote host
    * @param port    Remote port
    * @param timeout Socket timeout and connection timeout
    */
-  public TSocket(String host, int port, int timeout) {
-    this(host, port, timeout, timeout);
+  public TSocket(TConfiguration config, String host, int port, int timeout) throws TTransportException {
+    this(config, host, port, timeout, timeout);
   }
 
   /**
@@ -117,12 +132,14 @@
    * on the given port, with a specific connection timeout and a
    * specific socket timeout.
    *
+   * @param config          check config
    * @param host            Remote host
    * @param port            Remote port
    * @param socketTimeout   Socket timeout
    * @param connectTimeout  Connection timeout
    */
-  public TSocket(String host, int port, int socketTimeout, int connectTimeout) {
+  public TSocket(TConfiguration config, String host, int port, int socketTimeout, int connectTimeout) throws TTransportException {
+    super(config);
     host_ = host;
     port_ = port;
     socketTimeout_ = socketTimeout;
diff --git a/lib/java/src/org/apache/thrift/transport/TTransport.java b/lib/java/src/org/apache/thrift/transport/TTransport.java
index 73ad730..5645f7f 100644
--- a/lib/java/src/org/apache/thrift/transport/TTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TTransport.java
@@ -19,6 +19,8 @@
 
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
+
 import java.io.Closeable;
 
 /**
@@ -160,4 +162,10 @@
    * @param len
    */
   public void consumeBuffer(int len) {}
+
+  public abstract TConfiguration getConfiguration();
+
+  public abstract void updateKnownMessageSize(long size) throws TTransportException;
+
+  public abstract void checkReadBytesAvailable(long numBytes) throws TTransportException;
 }
diff --git a/lib/java/src/org/apache/thrift/transport/TTransportFactory.java b/lib/java/src/org/apache/thrift/transport/TTransportFactory.java
index 3e71630..e068b4b 100644
--- a/lib/java/src/org/apache/thrift/transport/TTransportFactory.java
+++ b/lib/java/src/org/apache/thrift/transport/TTransportFactory.java
@@ -34,7 +34,7 @@
    * @param trans The base transport
    * @return Wrapped Transport
    */
-  public TTransport getTransport(TTransport trans) {
+  public TTransport getTransport(TTransport trans) throws TTransportException {
     return trans;
   }
 
diff --git a/lib/java/src/org/apache/thrift/transport/TZlibTransport.java b/lib/java/src/org/apache/thrift/transport/TZlibTransport.java
index e755aa5..73b21aa 100644
--- a/lib/java/src/org/apache/thrift/transport/TZlibTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TZlibTransport.java
@@ -18,9 +18,12 @@
  */
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Objects;
 import java.util.zip.Deflater;
 import java.util.zip.DeflaterOutputStream;
 import java.util.zip.Inflater;
@@ -38,7 +41,7 @@
         }
 
         @Override
-        public TTransport getTransport(TTransport base) {
+        public TTransport getTransport(TTransport base) throws TTransportException {
             return new TZlibTransport(base);
         }
     }
@@ -47,7 +50,7 @@
      * Constructs a new TZlibTransport instance.
      * @param  transport the underlying transport to read from and write to
      */
-    public TZlibTransport(TTransport transport) {
+    public TZlibTransport(TTransport transport) throws TTransportException {
         this(transport, Deflater.BEST_COMPRESSION);
     }
 
@@ -56,7 +59,8 @@
      * @param  transport the underlying transport to read from and write to
      * @param  compressionLevel 0 for no compression, 9 for maximum compression
      */
-    public TZlibTransport(TTransport transport, int compressionLevel) {
+    public TZlibTransport(TTransport transport, int compressionLevel) throws TTransportException {
+        super(Objects.isNull(transport.getConfiguration()) ? new TConfiguration() : transport.getConfiguration());
         transport_ = transport;
         inputStream_ = new InflaterInputStream(new TTransportInputStream(transport_), new Inflater());
         outputStream_ = new DeflaterOutputStream(new TTransportOutputStream(transport_), new Deflater(compressionLevel, false), true);
diff --git a/lib/java/src/org/apache/thrift/transport/TFastFramedTransport.java b/lib/java/src/org/apache/thrift/transport/layered/TFastFramedTransport.java
similarity index 74%
rename from lib/java/src/org/apache/thrift/transport/TFastFramedTransport.java
rename to lib/java/src/org/apache/thrift/transport/layered/TFastFramedTransport.java
index a1fd249..29bf39c 100644
--- a/lib/java/src/org/apache/thrift/transport/TFastFramedTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/layered/TFastFramedTransport.java
@@ -16,7 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.thrift.transport;
+package org.apache.thrift.transport.layered;
+
+
+import org.apache.thrift.TConfiguration;
+import org.apache.thrift.transport.*;
+
+import java.util.Objects;
 
 /**
  * This transport is wire compatible with {@link TFramedTransport}, but makes
@@ -27,18 +33,18 @@
  *
  * This implementation is NOT threadsafe.
  */
-public class TFastFramedTransport extends TTransport {
+public class TFastFramedTransport extends TLayeredTransport {
 
   public static class Factory extends TTransportFactory {
     private final int initialCapacity;
     private final int maxLength;
 
     public Factory() {
-      this(DEFAULT_BUF_CAPACITY, DEFAULT_MAX_LENGTH);
+      this(DEFAULT_BUF_CAPACITY, TConfiguration.DEFAULT_MAX_FRAME_SIZE);
     }
 
     public Factory(int initialCapacity) {
-      this(initialCapacity, DEFAULT_MAX_LENGTH);
+      this(initialCapacity, TConfiguration.DEFAULT_MAX_FRAME_SIZE);
     }
 
     public Factory(int initialCapacity, int maxLength) {
@@ -47,7 +53,7 @@
     }
 
     @Override
-    public TTransport getTransport(TTransport trans) {
+    public TTransport getTransport(TTransport trans) throws TTransportException {
       return new TFastFramedTransport(trans,
           initialCapacity,
           maxLength);
@@ -58,12 +64,7 @@
    * How big should the default read and write buffers be?
    */
   public static final int DEFAULT_BUF_CAPACITY = 1024;
-  /**
-   * How big is the largest allowable frame? Defaults to 16MB.
-   */
-  public static final int DEFAULT_MAX_LENGTH = 16384000;
 
-  private final TTransport underlying;
   private final AutoExpandingBufferWriteTransport writeBuffer;
   private AutoExpandingBufferReadTransport readBuffer;
   private final int initialBufferCapacity;
@@ -75,8 +76,8 @@
    * for initial buffer size and max frame length.
    * @param underlying Transport that real reads and writes will go through to.
    */
-  public TFastFramedTransport(TTransport underlying) {
-    this(underlying, DEFAULT_BUF_CAPACITY, DEFAULT_MAX_LENGTH);
+  public TFastFramedTransport(TTransport underlying) throws TTransportException {
+    this(underlying, DEFAULT_BUF_CAPACITY, TConfiguration.DEFAULT_MAX_FRAME_SIZE);
   }
 
   /**
@@ -87,8 +88,8 @@
    * In practice, it's not critical to set this unless you know in advance that
    * your messages are going to be very large.
    */
-  public TFastFramedTransport(TTransport underlying, int initialBufferCapacity) {
-    this(underlying, initialBufferCapacity, DEFAULT_MAX_LENGTH);
+  public TFastFramedTransport(TTransport underlying, int initialBufferCapacity) throws TTransportException {
+    this(underlying, initialBufferCapacity, TConfiguration.DEFAULT_MAX_FRAME_SIZE);
   }
 
   /**
@@ -102,27 +103,29 @@
    * @param maxLength The max frame size you are willing to read. You can use
    * this parameter to limit how much memory can be allocated.
    */
-  public TFastFramedTransport(TTransport underlying, int initialBufferCapacity, int maxLength) {
-    this.underlying = underlying;
+  public TFastFramedTransport(TTransport underlying, int initialBufferCapacity, int maxLength) throws TTransportException {
+    super(underlying);
+    TConfiguration config = Objects.isNull(underlying.getConfiguration()) ? new TConfiguration() : underlying.getConfiguration();
     this.maxLength = maxLength;
+    config.setMaxFrameSize(maxLength);
     this.initialBufferCapacity = initialBufferCapacity;
-    readBuffer = new AutoExpandingBufferReadTransport(initialBufferCapacity);
-    writeBuffer = new AutoExpandingBufferWriteTransport(initialBufferCapacity, 4);
+    readBuffer = new AutoExpandingBufferReadTransport(config, initialBufferCapacity);
+    writeBuffer = new AutoExpandingBufferWriteTransport(config, initialBufferCapacity, 4);
   }
 
   @Override
   public void close() {
-    underlying.close();
+    getInnerTransport().close();
   }
 
   @Override
   public boolean isOpen() {
-    return underlying.isOpen();
+    return getInnerTransport().isOpen();
   }
 
   @Override
   public void open() throws TTransportException {
-    underlying.open();
+    getInnerTransport().open();
   }
 
   @Override
@@ -139,7 +142,7 @@
   }
 
   private void readFrame() throws TTransportException {
-    underlying.readAll(i32buf , 0, 4);
+    getInnerTransport().readAll(i32buf , 0, 4);
     int size = TFramedTransport.decodeFrameSize(i32buf);
 
     if (size < 0) {
@@ -147,13 +150,13 @@
       throw new TTransportException(TTransportException.CORRUPTED_DATA, "Read a negative frame size (" + size + ")!");
     }
 
-    if (size > maxLength) {
+    if (size > getInnerTransport().getConfiguration().getMaxFrameSize()) {
       close();
       throw new TTransportException(TTransportException.CORRUPTED_DATA,
           "Frame size (" + size + ") larger than max length (" + maxLength + ")!");
     }
 
-    readBuffer.fill(underlying, size);
+    readBuffer.fill(getInnerTransport(), size);
   }
 
   @Override
@@ -169,18 +172,18 @@
   /**
    * Only clears the read buffer!
    */
-  public void clear() {
-    readBuffer = new AutoExpandingBufferReadTransport(initialBufferCapacity);
+  public void clear() throws TTransportException {
+    readBuffer = new AutoExpandingBufferReadTransport(getConfiguration(), initialBufferCapacity);
   }
 
   @Override
   public void flush() throws TTransportException {
-    int payloadLength = writeBuffer.getLength() - 4;        
+    int payloadLength = writeBuffer.getLength() - 4;
     byte[] data = writeBuffer.getBuf().array();
     TFramedTransport.encodeFrameSize(payloadLength, data);
-    underlying.write(data, 0, payloadLength + 4);
+    getInnerTransport().write(data, 0, payloadLength + 4);
     writeBuffer.reset();
-    underlying.flush();
+    getInnerTransport().flush();
   }
 
   @Override
diff --git a/lib/java/src/org/apache/thrift/transport/TFramedTransport.java b/lib/java/src/org/apache/thrift/transport/layered/TFramedTransport.java
similarity index 72%
rename from lib/java/src/org/apache/thrift/transport/TFramedTransport.java
rename to lib/java/src/org/apache/thrift/transport/layered/TFramedTransport.java
index a006c3a..10a9a1c 100644
--- a/lib/java/src/org/apache/thrift/transport/TFramedTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/layered/TFramedTransport.java
@@ -17,24 +17,22 @@
  * under the License.
  */
 
-package org.apache.thrift.transport;
+package org.apache.thrift.transport.layered;
 
 import org.apache.thrift.TByteArrayOutputStream;
+import org.apache.thrift.TConfiguration;
+import org.apache.thrift.transport.TMemoryInputTransport;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+import org.apache.thrift.transport.TTransportFactory;
+
+import java.util.Objects;
 
 /**
  * TFramedTransport is a buffered TTransport that ensures a fully read message
  * every time by preceding messages with a 4-byte frame size.
  */
-public class TFramedTransport extends TTransport {
-
-  protected static final int DEFAULT_MAX_LENGTH = 16384000;
-
-  private int maxLength_;
-
-  /**
-   * Underlying transport
-   */
-  private TTransport transport_ = null;
+public class TFramedTransport extends TLayeredTransport {
 
   /**
    * Buffer for output
@@ -45,14 +43,13 @@
   /**
    * Buffer for input
    */
-  private final TMemoryInputTransport readBuffer_ =
-    new TMemoryInputTransport(new byte[0]);
+  private final TMemoryInputTransport readBuffer_;
 
   public static class Factory extends TTransportFactory {
     private int maxLength_;
 
     public Factory() {
-      maxLength_ = TFramedTransport.DEFAULT_MAX_LENGTH;
+      maxLength_ = TConfiguration.DEFAULT_MAX_FRAME_SIZE;
     }
 
     public Factory(int maxLength) {
@@ -60,7 +57,7 @@
     }
 
     @Override
-    public TTransport getTransport(TTransport base) {
+    public TTransport getTransport(TTransport base) throws TTransportException {
       return new TFramedTransport(base, maxLength_);
     }
   }
@@ -75,28 +72,28 @@
   /**
    * Constructor wraps around another transport
    */
-  public TFramedTransport(TTransport transport, int maxLength) {
-    transport_ = transport;
-    maxLength_ = maxLength;
+  public TFramedTransport(TTransport transport, int maxLength) throws TTransportException {
+    super(transport);
+    TConfiguration _configuration = Objects.isNull(transport.getConfiguration()) ? new TConfiguration() : transport.getConfiguration();
+    _configuration.setMaxFrameSize(maxLength);
     writeBuffer_.write(sizeFiller_, 0, 4);
+    readBuffer_= new TMemoryInputTransport(_configuration, new byte[0]);
   }
 
-  public TFramedTransport(TTransport transport) {
-    transport_ = transport;
-    maxLength_ = TFramedTransport.DEFAULT_MAX_LENGTH;
-    writeBuffer_.write(sizeFiller_, 0, 4);
+  public TFramedTransport(TTransport transport) throws TTransportException {
+    this(transport, TConfiguration.DEFAULT_MAX_FRAME_SIZE);
   }
 
   public void open() throws TTransportException {
-    transport_.open();
+    getInnerTransport().open();
   }
 
   public boolean isOpen() {
-    return transport_.isOpen();
+    return getInnerTransport().isOpen();
   }
 
   public void close() {
-    transport_.close();
+    getInnerTransport().close();
   }
 
   public int read(byte[] buf, int off, int len) throws TTransportException {
@@ -138,7 +135,7 @@
   private final byte[] i32buf = new byte[4];
 
   private void readFrame() throws TTransportException {
-    transport_.readAll(i32buf, 0, 4);
+    getInnerTransport().readAll(i32buf, 0, 4);
     int size = decodeFrameSize(i32buf);
 
     if (size < 0) {
@@ -146,14 +143,14 @@
       throw new TTransportException(TTransportException.CORRUPTED_DATA, "Read a negative frame size (" + size + ")!");
     }
 
-    if (size > maxLength_) {
+    if (size > getInnerTransport().getConfiguration().getMaxFrameSize()) {
       close();
       throw new TTransportException(TTransportException.CORRUPTED_DATA,
-          "Frame size (" + size + ") larger than max length (" + maxLength_ + ")!");
+          "Frame size (" + size + ") larger than max length (" + getInnerTransport().getConfiguration().getMaxFrameSize() + ")!");
     }
 
     byte[] buff = new byte[size];
-    transport_.readAll(buff, 0, size);
+    getInnerTransport().readAll(buff, 0, size);
     readBuffer_.reset(buff);
   }
 
@@ -169,8 +166,8 @@
     writeBuffer_.write(sizeFiller_, 0, 4);  // make room for the next frame's size data
 
     encodeFrameSize(len, buf);              // this is the frame length without the filler
-    transport_.write(buf, 0, len + 4);      // we have to write the frame size and frame data
-    transport_.flush();
+    getInnerTransport().write(buf, 0, len + 4);      // we have to write the frame size and frame data
+    getInnerTransport().flush();
   }
 
   public static final void encodeFrameSize(final int frameSize, final byte[] buf) {
diff --git a/lib/java/src/org/apache/thrift/transport/layered/TLayeredTransport.java b/lib/java/src/org/apache/thrift/transport/layered/TLayeredTransport.java
new file mode 100644
index 0000000..69ec824
--- /dev/null
+++ b/lib/java/src/org/apache/thrift/transport/layered/TLayeredTransport.java
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+package org.apache.thrift.transport.layered;
+
+import org.apache.thrift.TConfiguration;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TTransportException;
+
+import java.util.Objects;
+
+public abstract class TLayeredTransport extends TTransport{
+
+    private TTransport innerTransport;
+
+    public TConfiguration getConfiguration() {
+        return innerTransport.getConfiguration();
+    }
+
+    public TLayeredTransport(TTransport transport)
+    {
+        Objects.requireNonNull(transport, "TTransport cannot be null.");
+        innerTransport = transport;
+    }
+
+    public void updateKnownMessageSize(long size) throws TTransportException {
+        innerTransport.updateKnownMessageSize(size);
+    }
+
+    public void checkReadBytesAvailable(long numBytes) throws TTransportException {
+        innerTransport.checkReadBytesAvailable(numBytes);
+    }
+
+    public TTransport getInnerTransport() {
+        return innerTransport;
+    }
+}
diff --git a/lib/java/test/org/apache/thrift/TestOptionals.java b/lib/java/test/org/apache/thrift/TestOptionals.java
index d1591ee..f3d4cfc 100644
--- a/lib/java/test/org/apache/thrift/TestOptionals.java
+++ b/lib/java/test/org/apache/thrift/TestOptionals.java
@@ -34,8 +34,8 @@
     assertEquals(true, EncodingUtils.testBit((short)0x8, 3));
     assertEquals(false, EncodingUtils.testBit((short)0x8, 4));
 
-    assertEquals((short)Short.MIN_VALUE, EncodingUtils.setBit((short)0, 15, true));
-    assertEquals((short)0, EncodingUtils.setBit((short)Short.MIN_VALUE, 15, false));
+    assertEquals(Short.MIN_VALUE, EncodingUtils.setBit((short)0, 15, true));
+    assertEquals((short)0, EncodingUtils.setBit(Short.MIN_VALUE, 15, false));
     assertEquals(true, EncodingUtils.testBit(Short.MIN_VALUE, 15));
     assertEquals(false, EncodingUtils.testBit(Short.MIN_VALUE, 14));
   }
diff --git a/lib/java/test/org/apache/thrift/TestReuse.java b/lib/java/test/org/apache/thrift/TestReuse.java
index b44abd0..2482d39 100644
--- a/lib/java/test/org/apache/thrift/TestReuse.java
+++ b/lib/java/test/org/apache/thrift/TestReuse.java
@@ -35,21 +35,21 @@
 
     Reuse ru1 = new Reuse();
     HashSet<String> hs1 = new HashSet<String>();
-    byte[] serBytes;    
+    byte[] serBytes;
     String st1 = new String("string1");
     String st2 = new String("string2");
 
     ru1.setVal1(11);
     ru1.setVal2(hs1);
     ru1.addToVal2(st1);
-    
+
     serBytes = binarySerializer.serialize(ru1);
 
     // update hash set after serialization
     hs1.add(st2);
 
     binaryDeserializer.deserialize(ru1, serBytes);
-   
+
     assertTrue( ru1.getVal2() == hs1 );
     assertTrue( hs1.size() == 2 );
   }
diff --git a/lib/java/test/org/apache/thrift/async/TestTAsyncClientManager.java b/lib/java/test/org/apache/thrift/async/TestTAsyncClientManager.java
index c483cf2..0a20e52 100644
--- a/lib/java/test/org/apache/thrift/async/TestTAsyncClientManager.java
+++ b/lib/java/test/org/apache/thrift/async/TestTAsyncClientManager.java
@@ -40,6 +40,7 @@
 import org.apache.thrift.transport.TNonblockingServerSocket;
 import org.apache.thrift.transport.TNonblockingSocket;
 
+import org.apache.thrift.transport.TTransportException;
 import thrift.test.CompactProtoTestStruct;
 import thrift.test.ExceptionWithAMap;
 import thrift.test.Srv;
@@ -233,7 +234,7 @@
     assertEquals(numThreads * numCallsPerThread, numSuccesses);
   }
 
-  private Srv.AsyncClient getClient() throws IOException {
+  private Srv.AsyncClient getClient() throws IOException, TTransportException {
     TNonblockingSocket clientSocket = new TNonblockingSocket(ServerTestBase.HOST, ServerTestBase.PORT);
     return new Srv.AsyncClient(new TBinaryProtocol.Factory(), clientManager_, clientSocket);
   }
diff --git a/lib/java/test/org/apache/thrift/protocol/ProtocolTestBase.java b/lib/java/test/org/apache/thrift/protocol/ProtocolTestBase.java
index 0386d83..52b1074 100644
--- a/lib/java/test/org/apache/thrift/protocol/ProtocolTestBase.java
+++ b/lib/java/test/org/apache/thrift/protocol/ProtocolTestBase.java
@@ -18,24 +18,26 @@
  */
 package org.apache.thrift.protocol;
 
+import java.lang.Exception;
+import java.lang.Integer;
+import java.lang.String;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import junit.framework.TestCase;
 
-import org.apache.thrift.Fixtures;
-import org.apache.thrift.TBase;
-import org.apache.thrift.TDeserializer;
-import org.apache.thrift.TException;
-import org.apache.thrift.TSerializer;
+import org.apache.thrift.*;
+import org.apache.thrift.server.ServerTestBase;
 import org.apache.thrift.transport.TMemoryBuffer;
 
-import thrift.test.CompactProtoTestStruct;
-import thrift.test.HolyMoley;
-import thrift.test.Nesting;
-import thrift.test.OneOfEach;
-import thrift.test.Srv;
+import org.apache.thrift.transport.TTransportException;
+import thrift.test.*;
 
 public abstract class ProtocolTestBase extends TestCase {
 
@@ -409,7 +411,7 @@
       }
       long serEnd = System.currentTimeMillis();
       long serElapsed = serEnd - serStart;
-      System.out.println("Ser:\t" + serElapsed + "ms\t" 
+      System.out.println("Ser:\t" + serElapsed + "ms\t"
           + ((double)serElapsed / NUM_REPS) + "ms per serialization");
 
       HolyMoley cpts = new HolyMoley();
@@ -420,8 +422,109 @@
       }
       long deserEnd = System.currentTimeMillis();
       long deserElapsed = deserEnd - deserStart;
-      System.out.println("Des:\t" + deserElapsed + "ms\t" 
+      System.out.println("Des:\t" + deserElapsed + "ms\t"
           + ((double)deserElapsed / NUM_REPS) + "ms per deserialization");
     }
   }
+
+  private ServerTestBase.TestHandler testHandler = new ServerTestBase.TestHandler() {
+    @Override
+    public String testString(String thing) {
+      thing = thing + " Apache Thrift Java " + thing;
+      return thing;
+    }
+
+    @Override
+    public List<Integer> testList(List<Integer> thing) {
+      thing.addAll(thing);
+      thing.addAll(thing);
+      return thing;
+    }
+
+    @Override
+    public Set<Integer> testSet(Set<Integer> thing) {
+      thing.addAll(thing.stream().map( x -> x + 100).collect(Collectors.toSet()));
+      return thing;
+    }
+
+    @Override
+    public Map<String, String> testStringMap(Map<String, String> thing) {
+      thing.put("a", "123");
+      thing.put(" x y ", " with spaces ");
+      thing.put("same", "same");
+      thing.put("0", "numeric key");
+      thing.put("1", "");
+      thing.put("ok", "2355555");
+      thing.put("end", "0");
+      return thing;
+    }
+  };
+
+  private TProtocol initConfig(int maxSize) throws TException{
+    TConfiguration config = TConfiguration.custom().setMaxMessageSize(maxSize).build();
+    TMemoryBuffer bufferTrans = new TMemoryBuffer(config, 0);
+    return getFactory().getProtocol(bufferTrans);
+  }
+
+  public void testReadCheckMaxMessageRequestForString() throws TException{
+    TProtocol clientOutProto = initConfig(15);
+    TProtocol clientInProto = initConfig(15);
+    ThriftTest.Client testClient = new ThriftTest.Client(clientInProto, clientOutProto);
+    ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler);
+    try {
+      testClient.send_testString("test");
+      testProcessor.process(clientOutProto, clientInProto);
+      String result = testClient.recv_testString();
+      System.out.println("----result: "+result);
+    } catch (TException e) {
+      assertEquals("MaxMessageSize reached", e.getMessage());
+    }
+  }
+
+  public void testReadCheckMaxMessageRequestForList() throws TException{
+    TProtocol clientOutProto = initConfig(15);
+    TProtocol clientInProto = initConfig(15);
+    ThriftTest.Client testClient = new ThriftTest.Client(clientInProto, clientOutProto);
+    ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler);
+    try {
+      testClient.send_testList(Arrays.asList(1, 23242346, 888888, 90));
+      testProcessor.process(clientOutProto, clientInProto);
+      testClient.recv_testList();
+      fail("Limitations not achieved as expected");
+    } catch (TTransportException e) {
+      assertEquals("MaxMessageSize reached", e.getMessage());
+    }
+  }
+
+  public void testReadCheckMaxMessageRequestForMap() throws TException{
+    TProtocol clientOutProto = initConfig(13);
+    TProtocol clientInProto = initConfig(13);
+    ThriftTest.Client testClient = new ThriftTest.Client(clientInProto, clientOutProto);
+    ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler);
+    Map<String, String> thing = new HashMap<>();
+    thing.put("key", "Thrift");
+    try {
+      testClient.send_testStringMap(thing);
+      testProcessor.process(clientOutProto, clientInProto);
+      testClient.recv_testStringMap();
+      fail("Limitations not achieved as expected");
+    } catch (TTransportException e) {
+      assertEquals("MaxMessageSize reached", e.getMessage());
+    }
+  }
+
+  public void testReadCheckMaxMessageRequestForSet() throws TException{
+    TProtocol clientOutProto = initConfig(10);
+    TProtocol clientInProto = initConfig(10);
+    ThriftTest.Client testClient = new ThriftTest.Client(clientInProto, clientOutProto);
+    ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler);
+    try {
+      testClient.send_testSet(Stream.of(234, 0, 987087, 45, 88888888, 9).collect(Collectors.toSet()));
+      testProcessor.process(clientOutProto, clientInProto);
+      testClient.recv_testSet();
+      fail("Limitations not achieved as expected");
+    } catch (TTransportException e) {
+      assertEquals("MaxMessageSize reached", e.getMessage());
+    }
+  }
 }
diff --git a/lib/java/test/org/apache/thrift/protocol/TestTBinaryProtocol.java b/lib/java/test/org/apache/thrift/protocol/TestTBinaryProtocol.java
new file mode 100644
index 0000000..67220b0
--- /dev/null
+++ b/lib/java/test/org/apache/thrift/protocol/TestTBinaryProtocol.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+
+package org.apache.thrift.protocol;
+
+import org.apache.thrift.TDeserializer;
+import org.apache.thrift.TException;
+import thrift.test.Bonk;
+
+public class TestTBinaryProtocol extends ProtocolTestBase {
+  @Override
+  protected TProtocolFactory getFactory() {
+    return new TBinaryProtocol.Factory();
+  }
+
+  @Override
+  protected boolean canBeUsedNaked() {
+    return true;
+  }
+
+}
diff --git a/lib/java/test/org/apache/thrift/scheme/TestStandardScheme.java b/lib/java/test/org/apache/thrift/scheme/TestStandardScheme.java
index 33f229e..43e40c2 100644
--- a/lib/java/test/org/apache/thrift/scheme/TestStandardScheme.java
+++ b/lib/java/test/org/apache/thrift/scheme/TestStandardScheme.java
@@ -12,6 +12,7 @@
 import org.apache.thrift.transport.TMemoryBuffer;
 import org.apache.thrift.transport.TTransport;
 
+import org.apache.thrift.transport.TTransportException;
 import thrift.test.HolyMoley;
 import thrift.test.Nesting;
 import thrift.test.OneOfEach;
@@ -20,6 +21,9 @@
   TSerializer serializer = new TSerializer();
   TDeserializer deserializer = new TDeserializer();
 
+  public TestStandardScheme() throws TTransportException {
+  }
+
   /**
    * This tests whether the Standard Scheme properly reads structs serialized
    * using an older version of thrift.
diff --git a/lib/java/test/org/apache/thrift/server/ServerTestBase.java b/lib/java/test/org/apache/thrift/server/ServerTestBase.java
index 8348cbc..e2bf96a 100644
--- a/lib/java/test/org/apache/thrift/server/ServerTestBase.java
+++ b/lib/java/test/org/apache/thrift/server/ServerTestBase.java
@@ -37,11 +37,12 @@
 import org.apache.thrift.protocol.TCompactProtocol;
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.protocol.TProtocolFactory;
-import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.TTransportException;
+import org.apache.thrift.transport.layered.TFramedTransport;
 import org.apache.thrift.transport.TSocket;
 import org.apache.thrift.transport.TTransport;
 import org.apache.thrift.transport.TTransportFactory;
-import org.apache.thrift.transport.TFramedTransport.Factory;
+import org.apache.thrift.transport.layered.TFramedTransport.Factory;
 
 import thrift.test.Insanity;
 import thrift.test.Numberz;
@@ -203,7 +204,7 @@
       System.out.print("testInsanity()\n");
 
       HashMap<Numberz,Insanity> first_map = new HashMap<Numberz, Insanity>();
-      HashMap<Numberz,Insanity> second_map = new HashMap<Numberz, Insanity>();;
+      HashMap<Numberz,Insanity> second_map = new HashMap<Numberz, Insanity>();
 
       first_map.put(Numberz.TWO, argument);
       first_map.put(Numberz.THREE, argument);
@@ -222,7 +223,7 @@
     public Xtruct testMulti(byte arg0, int arg1, long arg2, Map<Short,String> arg3, Numberz arg4, long arg5) {
       System.out.print("testMulti()\n");
 
-      Xtruct hello = new Xtruct();;
+      Xtruct hello = new Xtruct();
       hello.string_thing = "Hello2";
       hello.byte_thing = arg0;
       hello.i32_thing = arg1;
@@ -268,7 +269,7 @@
     }
 
     public void testOneway(int sleepFor) {
-      System.out.println("testOneway(" + Integer.toString(sleepFor) +
+      System.out.println("testOneway(" + sleepFor +
                          ") => sleeping...");
       try {
         Thread.sleep(sleepFor * SLEEP_DELAY);
@@ -533,7 +534,7 @@
     }
 
     @Override
-    public TTransport getTransport(TTransport trans) {
+    public TTransport getTransport(TTransport trans) throws TTransportException {
       count++;
       return factory.getTransport(trans);
     }
diff --git a/lib/java/test/org/apache/thrift/server/TestNonblockingServer.java b/lib/java/test/org/apache/thrift/server/TestNonblockingServer.java
index 3df3bd8..2c77908 100644
--- a/lib/java/test/org/apache/thrift/server/TestNonblockingServer.java
+++ b/lib/java/test/org/apache/thrift/server/TestNonblockingServer.java
@@ -23,7 +23,7 @@
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.protocol.TProtocolFactory;
 import org.apache.thrift.server.TNonblockingServer.Args;
-import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.layered.TFramedTransport;
 import org.apache.thrift.transport.TNonblockingServerSocket;
 import org.apache.thrift.transport.TSocket;
 import org.apache.thrift.transport.TTransport;
diff --git a/lib/java/test/org/apache/thrift/test/SerializationBenchmark.java b/lib/java/test/org/apache/thrift/test/SerializationBenchmark.java
index 2b0db31..de22556 100644
--- a/lib/java/test/org/apache/thrift/test/SerializationBenchmark.java
+++ b/lib/java/test/org/apache/thrift/test/SerializationBenchmark.java
@@ -22,6 +22,7 @@
 
 import org.apache.thrift.Fixtures;
 import org.apache.thrift.TBase;
+import org.apache.thrift.TConfiguration;
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.protocol.TProtocolFactory;
@@ -34,34 +35,37 @@
 
 public class SerializationBenchmark {
   private final static int HOW_MANY = 10000000;
-  
+
   public static void main(String[] args) throws Exception {
     TProtocolFactory factory = new TBinaryProtocol.Factory();
 
     testSerialization(factory, Fixtures.oneOfEach);
     testDeserialization(factory, Fixtures.oneOfEach, OneOfEach.class);
   }
-  
+
   public static void testSerialization(TProtocolFactory factory, TBase object) throws Exception {
     TTransport trans = new TTransport() {
       public void write(byte[] bin, int x, int y) throws TTransportException {}
+      public TConfiguration getConfiguration() {return new TConfiguration(); }
+      public void updateKnownMessageSize(long size) throws TTransportException {}
+      public void checkReadBytesAvailable(long numBytes) throws TTransportException {}
       public int read(byte[] bin, int x, int y) throws TTransportException {return 0;}
       public void close() {}
       public void open() {}
       public boolean isOpen() {return true;}
     };
-    
+
     TProtocol proto = factory.getProtocol(trans);
-    
+
     long startTime = System.currentTimeMillis();
     for (int i = 0; i < HOW_MANY; i++) {
       object.write(proto);
     }
     long endTime = System.currentTimeMillis();
-    
+
     System.out.println("Serialization test time: " + (endTime - startTime) + " ms");
   }
-  
+
   public static <T extends TBase> void testDeserialization(TProtocolFactory factory, T object, Class<T> klass) throws Exception {
     TMemoryBuffer buf = new TMemoryBuffer(0);
     object.write(factory.getProtocol(buf));
@@ -71,10 +75,10 @@
     long startTime = System.currentTimeMillis();
     for (int i = 0; i < HOW_MANY; i++) {
       T o2 = klass.newInstance();
-      o2.read(factory.getProtocol(new TMemoryInputTransport(serialized)));
+      o2.read(factory.getProtocol(new TMemoryInputTransport(new TConfiguration(), serialized)));
     }
     long endTime = System.currentTimeMillis();
 
     System.out.println("Deserialization test time: " + (endTime - startTime) + " ms");
   }
-}
\ No newline at end of file
+}
diff --git a/lib/java/test/org/apache/thrift/test/TestClient.java b/lib/java/test/org/apache/thrift/test/TestClient.java
index b402854..2861a1d 100644
--- a/lib/java/test/org/apache/thrift/test/TestClient.java
+++ b/lib/java/test/org/apache/thrift/test/TestClient.java
@@ -37,8 +37,8 @@
 import org.apache.thrift.protocol.TMultiplexedProtocol;
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.protocol.TSimpleJSONProtocol;
-import org.apache.thrift.transport.TFastFramedTransport;
-import org.apache.thrift.transport.TFramedTransport;
+import org.apache.thrift.transport.layered.TFastFramedTransport;
+import org.apache.thrift.transport.layered.TFramedTransport;
 import org.apache.thrift.transport.THttpClient;
 import org.apache.thrift.transport.TSSLTransportFactory;
 import org.apache.thrift.transport.TSocket;
@@ -106,7 +106,7 @@
         } else if (args[i].equals("--zlib")) {
           zlib = true;
         } else if (args[i].equals("--client")) {
-          http_client = true;  
+          http_client = true;
         } else if (args[i].equals("--help")) {
           System.out.println("Allowed options:");
           System.out.println("  --help\t\t\tProduce help message");
@@ -157,7 +157,7 @@
       if (transport_type.equals("http")) {
         String url = "http://" + host + ":" + port + "/test/service";
         if (http_client == true) {
-          
+
           transport = new THttpClient(url, HttpClients.createDefault());
         } else {
           transport = new THttpClient(url);
@@ -775,7 +775,7 @@
         long onewayElapsedMillis = (System.nanoTime() - startOneway) / 1000000;
         if (onewayElapsedMillis > 200) {
           System.out.println("Oneway test took too long to execute failed: took " +
-                             Long.toString(onewayElapsedMillis) +
+                  onewayElapsedMillis +
                              "ms");
           System.out.println("oneway calls are 'fire and forget' and therefore should not cause blocking.");
           System.out.println("Some transports (HTTP) have a required response, and typically this failure");
@@ -786,7 +786,7 @@
           returnCode |= ERR_BASETYPES;
         } else {
           System.out.println("Success - fire and forget only took " +
-                             Long.toString(onewayElapsedMillis) +
+                  onewayElapsedMillis +
                              "ms");
         }
 
diff --git a/lib/java/test/org/apache/thrift/test/TestServer.java b/lib/java/test/org/apache/thrift/test/TestServer.java
index 25a329c..02e8ad7 100644
--- a/lib/java/test/org/apache/thrift/test/TestServer.java
+++ b/lib/java/test/org/apache/thrift/test/TestServer.java
@@ -19,29 +19,21 @@
 
 package org.apache.thrift.test;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
 import org.apache.thrift.protocol.TBinaryProtocol;
 import org.apache.thrift.protocol.TCompactProtocol;
 import org.apache.thrift.protocol.TJSONProtocol;
 import org.apache.thrift.protocol.TProtocol;
 import org.apache.thrift.protocol.TProtocolFactory;
-import org.apache.thrift.protocol.TMultiplexedProtocol;
 import org.apache.thrift.server.ServerContext;
 import org.apache.thrift.server.TServer;
-import org.apache.thrift.server.TServer.Args;
 import org.apache.thrift.server.TSimpleServer;
 import org.apache.thrift.server.TThreadPoolServer;
 import org.apache.thrift.server.ServerTestBase.TestHandler;
 import org.apache.thrift.server.TServerEventHandler;
 import org.apache.thrift.server.TThreadedSelectorServer;
 import org.apache.thrift.server.TNonblockingServer;
-import org.apache.thrift.transport.TFramedTransport;
-import org.apache.thrift.transport.TFastFramedTransport;
+import org.apache.thrift.transport.layered.TFramedTransport;
+import org.apache.thrift.transport.layered.TFastFramedTransport;
 import org.apache.thrift.transport.TZlibTransport;
 import org.apache.thrift.transport.TServerSocket;
 import org.apache.thrift.transport.TSSLTransportFactory;
@@ -50,14 +42,8 @@
 import org.apache.thrift.transport.TNonblockingServerSocket;
 import org.apache.thrift.TMultiplexedProcessor;
 
-import thrift.test.Insanity;
-import thrift.test.Numberz;
 import thrift.test.SecondService;
 import thrift.test.ThriftTest;
-import thrift.test.Xception;
-import thrift.test.Xception2;
-import thrift.test.Xtruct;
-import thrift.test.Xtruct2;
 
 public class TestServer {
 
diff --git a/lib/java/test/org/apache/thrift/transport/ReadCountingTransport.java b/lib/java/test/org/apache/thrift/transport/ReadCountingTransport.java
index 3c749f9..1b2073c 100644
--- a/lib/java/test/org/apache/thrift/transport/ReadCountingTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/ReadCountingTransport.java
@@ -19,6 +19,8 @@
 package org.apache.thrift.transport;
 
 
+import org.apache.thrift.TConfiguration;
+
 public class ReadCountingTransport extends TTransport {
   public int readCount = 0;
   private TTransport trans;
@@ -58,4 +60,19 @@
       throw new TTransportException(TTransportException.NOT_OPEN, "Transport is closed");
     }
   }
+
+  @Override
+  public TConfiguration getConfiguration() {
+    return trans.getConfiguration();
+  }
+
+  @Override
+  public void updateKnownMessageSize(long size) throws TTransportException {
+    trans.updateKnownMessageSize(size);
+  }
+
+  @Override
+  public void checkReadBytesAvailable(long numBytes) throws TTransportException {
+    trans.checkReadBytesAvailable(numBytes);
+  }
 }
diff --git a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java
index 83ebc2d..b635e60 100644
--- a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java
@@ -21,6 +21,7 @@
 import java.nio.ByteBuffer;
 
 import junit.framework.TestCase;
+import org.apache.thrift.TConfiguration;
 
 public class TestAutoExpandingBufferReadTransport extends TestCase {
   private static final byte[] HUNDRED_BYTES = new byte[100];
@@ -32,9 +33,9 @@
   }
 
   public void testIt() throws Exception {
-    AutoExpandingBufferReadTransport t = new AutoExpandingBufferReadTransport(150);
+    AutoExpandingBufferReadTransport t = new AutoExpandingBufferReadTransport(new TConfiguration(), 150);
 
-    TMemoryInputTransport membuf = new TMemoryInputTransport(HUNDRED_BYTES);
+    TMemoryInputTransport membuf = new TMemoryInputTransport(new TConfiguration(), HUNDRED_BYTES);
 
     t.fill(membuf, 100);
     assertEquals(100, t.getBytesRemainingInBuffer());
diff --git a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java
index 86b5b0d..c3e021c 100644
--- a/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java
@@ -19,14 +19,18 @@
 package org.apache.thrift.transport;
 
 import java.nio.ByteBuffer;
+
+import org.apache.thrift.TConfiguration;
 import org.junit.Test;
 import static org.junit.Assert.*;
 
 public class TestAutoExpandingBufferWriteTransport {
 
+  private TConfiguration config = new TConfiguration();
+
   @Test
   public void testIt() throws Exception {
-    AutoExpandingBufferWriteTransport t = new AutoExpandingBufferWriteTransport(1, 0);
+    AutoExpandingBufferWriteTransport t = new AutoExpandingBufferWriteTransport(config, 1, 0);
     assertEquals(0, t.getLength());
     assertEquals(1, t.getBuf().array().length);
     byte[] b1 = new byte[]{1,2,3};
@@ -43,7 +47,7 @@
     assertEquals(2, t.getLength());
     assertEquals(ByteBuffer.wrap(b2), ByteBuffer.wrap(t.getBuf().array(), 0, 2));
 
-    AutoExpandingBufferWriteTransport uut = new AutoExpandingBufferWriteTransport(8, 4);
+    AutoExpandingBufferWriteTransport uut = new AutoExpandingBufferWriteTransport(config, 8, 4);
     assertEquals(4, uut.getLength());
     assertEquals(8, uut.getBuf().array().length);
     uut.write(b1);
@@ -53,17 +57,17 @@
   }
 
   @Test(expected = IllegalArgumentException.class)
-  public void testBadInitialSize() throws IllegalArgumentException {
-    new AutoExpandingBufferWriteTransport(0, 0);
+  public void testBadInitialSize() throws IllegalArgumentException, TTransportException {
+    new AutoExpandingBufferWriteTransport(config, 0, 0);
   }
 
   @Test(expected = IllegalArgumentException.class)
-  public void testBadFrontReserveSize() throws IllegalArgumentException {
-    new AutoExpandingBufferWriteTransport(4, -1);
+  public void testBadFrontReserveSize() throws IllegalArgumentException, TTransportException {
+    new AutoExpandingBufferWriteTransport(config, 4, -1);
   }
 
   @Test(expected = IllegalArgumentException.class)
-  public void testTooSmallFrontReserveSize() throws IllegalArgumentException {
-    new AutoExpandingBufferWriteTransport(4, 5);
+  public void testTooSmallFrontReserveSize() throws IllegalArgumentException, TTransportException {
+    new AutoExpandingBufferWriteTransport(config, 4, 5);
   }
 }
diff --git a/lib/java/test/org/apache/thrift/transport/TestTFastFramedTransport.java b/lib/java/test/org/apache/thrift/transport/TestTFastFramedTransport.java
index 06ee206..6fa2380 100644
--- a/lib/java/test/org/apache/thrift/transport/TestTFastFramedTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestTFastFramedTransport.java
@@ -18,16 +18,18 @@
  */
 package org.apache.thrift.transport;
 
+import org.apache.thrift.transport.layered.TFastFramedTransport;
+
 public class TestTFastFramedTransport extends TestTFramedTransport {
   protected final static int INITIAL_CAPACITY = 50;
 
   @Override
-  protected TTransport getTransport(TTransport underlying) {
+  protected TTransport getTransport(TTransport underlying) throws TTransportException {
     return new TFastFramedTransport(underlying, INITIAL_CAPACITY, 10 * 1024 * 1024);
   }
 
   @Override
-  protected TTransport getTransport(TTransport underlying, int maxLength) {
+  protected TTransport getTransport(TTransport underlying, int maxLength) throws TTransportException {
     return new TFastFramedTransport(underlying, INITIAL_CAPACITY, maxLength);
   }
 }
diff --git a/lib/java/test/org/apache/thrift/transport/TestTFramedTransport.java b/lib/java/test/org/apache/thrift/transport/TestTFramedTransport.java
index e30d74b..fc3dd5b 100644
--- a/lib/java/test/org/apache/thrift/transport/TestTFramedTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestTFramedTransport.java
@@ -27,14 +27,16 @@
 import java.util.Arrays;
 
 import junit.framework.TestCase;
+import org.apache.thrift.transport.layered.TFastFramedTransport;
+import org.apache.thrift.transport.layered.TFramedTransport;
 
 public class TestTFramedTransport extends TestCase {
 
-  protected TTransport getTransport(TTransport underlying) {
+  protected TTransport getTransport(TTransport underlying) throws TTransportException {
     return new TFramedTransport(underlying);
   }
 
-  protected TTransport getTransport(TTransport underlying, int maxLength) {
+  protected TTransport getTransport(TTransport underlying, int maxLength) throws TTransportException {
     return new TFramedTransport(underlying, maxLength);
   }
 
@@ -73,6 +75,7 @@
     assertEquals(30, trans.read(new byte[30], 0, 30));
     assertEquals(2, countTrans.readCount);
 
+    // Known message size exceeded
     readBuf = new byte[220];
     assertEquals(220, trans.read(readBuf, 0, 220));
     assertTrue(Arrays.equals(readBuf, byteSequence(0, 219)));
@@ -149,8 +152,8 @@
     DataOutputStream dos = new DataOutputStream(baos);
     dos.writeInt(50);
     dos.write(byteSequence(0, 49));
-    dos.writeInt(75);
-    dos.write(byteSequence(125, 200));
+    dos.writeInt(50);
+    dos.write(byteSequence(125, 175));
 
     TMemoryBuffer membuf = new TMemoryBuffer(0);
     membuf.write(baos.toByteArray());
@@ -177,10 +180,11 @@
     assertEquals(0, trans.getBytesRemainingInBuffer());
     assertEquals(50, trans.getBufferPosition());
 
+    // Known message size exceeded
     trans.read(readBuf, 0, 10);
     assertEquals(4, countTrans.readCount);
     assertTrue(Arrays.equals(readBuf, byteSequence(125,134)));
-    assertEquals(65, trans.getBytesRemainingInBuffer());
+    assertEquals(40, trans.getBytesRemainingInBuffer());
     assertEquals(10, trans.getBufferPosition());
   }
 
diff --git a/lib/java/test/org/apache/thrift/transport/TestTMemoryInputTransport.java b/lib/java/test/org/apache/thrift/transport/TestTMemoryInputTransport.java
index 273145b..bd94436 100644
--- a/lib/java/test/org/apache/thrift/transport/TestTMemoryInputTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestTMemoryInputTransport.java
@@ -61,7 +61,7 @@
     assertEquals(3, trans.getBytesRemainingInBuffer());
   }
 
-  public void testWithOffsetAndLength() throws Exception {
+  public void testWithOffsetAndLength() throws TTransportException {
     byte[] input_buf = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     TMemoryInputTransport trans = new TMemoryInputTransport(input_buf, 1, 3);
     assertEquals(1, trans.getBufferPosition());
diff --git a/lib/java/test/org/apache/thrift/transport/TestTSaslTransports.java b/lib/java/test/org/apache/thrift/transport/TestTSaslTransports.java
index 6eb38e7..d384d7f 100644
--- a/lib/java/test/org/apache/thrift/transport/TestTSaslTransports.java
+++ b/lib/java/test/org/apache/thrift/transport/TestTSaslTransports.java
@@ -40,6 +40,7 @@
 
 import junit.framework.TestCase;
 
+import org.apache.thrift.TConfiguration;
 import org.apache.thrift.TProcessor;
 import org.apache.thrift.protocol.TProtocolFactory;
 import org.apache.thrift.server.ServerTestBase;
@@ -409,9 +410,10 @@
   private static class MockTTransport extends TTransport {
 
     byte[] badHeader = null;
-    private TMemoryInputTransport readBuffer = new TMemoryInputTransport();
+    private TMemoryInputTransport readBuffer;
 
-    public MockTTransport(int mode) {
+    public MockTTransport(int mode) throws TTransportException {
+      readBuffer = new TMemoryInputTransport();
       if (mode==1) {
         // Invalid status byte
         badHeader = new byte[] { (byte)0xFF, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05 };
@@ -443,25 +445,41 @@
 
     @Override
     public void write(byte[] buf, int off, int len) throws TTransportException {}
+
+    @Override
+    public TConfiguration getConfiguration() {
+      return readBuffer.getConfiguration();
+    }
+
+    @Override
+    public void updateKnownMessageSize(long size) throws TTransportException {
+      readBuffer.updateKnownMessageSize(size);
+    }
+
+    @Override
+    public void checkReadBytesAvailable(long numBytes) throws TTransportException {
+      readBuffer.checkReadBytesAvailable(numBytes);
+    }
   }
 
   public void testBadHeader() {
-    TSaslTransport saslTransport = new TSaslServerTransport(new MockTTransport(1));
+    TSaslTransport saslTransport;
     try {
+      saslTransport = new TSaslServerTransport(new MockTTransport(1));
       saslTransport.receiveSaslMessage();
       fail("Should have gotten an error due to incorrect status byte value.");
     } catch (TTransportException e) {
       assertEquals(e.getMessage(), "Invalid status -1");
     }
-    saslTransport = new TSaslServerTransport(new MockTTransport(2));
     try {
+      saslTransport = new TSaslServerTransport(new MockTTransport(2));
       saslTransport.receiveSaslMessage();
       fail("Should have gotten an error due to negative payload length.");
     } catch (TTransportException e) {
       assertEquals(e.getMessage(), "Invalid payload header length: -1");
     }
-    saslTransport = new TSaslServerTransport(new MockTTransport(3));
     try {
+      saslTransport = new TSaslServerTransport(new MockTTransport(3));
       saslTransport.receiveSaslMessage();
       fail("Should have gotten an error due to bogus (large) payload length.");
     } catch (TTransportException e) {
diff --git a/lib/java/test/org/apache/thrift/transport/TestTZlibTransport.java b/lib/java/test/org/apache/thrift/transport/TestTZlibTransport.java
index 3d7f9c1..1b39700 100644
--- a/lib/java/test/org/apache/thrift/transport/TestTZlibTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/TestTZlibTransport.java
@@ -33,7 +33,7 @@
 
 public class TestTZlibTransport extends TestCase {
 
-  protected TTransport getTransport(TTransport underlying) {
+  protected TTransport getTransport(TTransport underlying) throws TTransportException {
     return new TZlibTransport(underlying);
   }
 
diff --git a/lib/java/test/org/apache/thrift/transport/WriteCountingTransport.java b/lib/java/test/org/apache/thrift/transport/WriteCountingTransport.java
index 358f5c6..50b778b 100644
--- a/lib/java/test/org/apache/thrift/transport/WriteCountingTransport.java
+++ b/lib/java/test/org/apache/thrift/transport/WriteCountingTransport.java
@@ -19,6 +19,8 @@
 package org.apache.thrift.transport;
 
 
+import org.apache.thrift.TConfiguration;
+
 public class WriteCountingTransport extends TTransport {
   public int writeCount = 0;
   private final TTransport trans;
@@ -51,4 +53,19 @@
   public void flush() throws TTransportException {
     trans.flush();
   }
-}
\ No newline at end of file
+
+  @Override
+  public TConfiguration getConfiguration() {
+    return trans.getConfiguration();
+  }
+
+  @Override
+  public void updateKnownMessageSize(long size) throws TTransportException {
+    trans.updateKnownMessageSize(size);
+  }
+
+  @Override
+  public void checkReadBytesAvailable(long numBytes) throws TTransportException {
+    trans.checkReadBytesAvailable(numBytes);
+  }
+}
diff --git a/lib/lua/TCompactProtocol.lua b/lib/lua/TCompactProtocol.lua
index 8e7db8e..ca488dc 100644
--- a/lib/lua/TCompactProtocol.lua
+++ b/lib/lua/TCompactProtocol.lua
@@ -118,8 +118,8 @@
 end
 
 function TCompactProtocol:writeStructBegin(name)
-  self.lastFieldIndex = self.lastFieldIndex + 1
   self.lastField[self.lastFieldIndex] = self.lastFieldId
+  self.lastFieldIndex = self.lastFieldIndex + 1
   self.lastFieldId = 0
 end
 
diff --git a/lib/lua/TServer.lua b/lib/lua/TServer.lua
index 4e37d58..9afe19e 100644
--- a/lib/lua/TServer.lua
+++ b/lib/lua/TServer.lua
@@ -85,9 +85,17 @@
   end
 end
 
+function TServer:setExceptionHandler(exceptionHandler)
+  self.exceptionHandler = exceptionHandler
+end
+
 function TServer:_handleException(err)
   if string.find(err, 'TTransportException') == nil then
-    print(err)
+    if self.exceptionHandler then
+      self.exceptionHandler(err)
+    else
+      print(err)
+    end
   end
 end
 
diff --git a/lib/lua/src/usocket.c b/lib/lua/src/usocket.c
index 1a1b549..7c77651 100644
--- a/lib/lua/src/usocket.c
+++ b/lib/lua/src/usocket.c
@@ -89,12 +89,6 @@
     return TIMEOUT;
   }
 
-  // Verify that we can actually read from the remote host
-  if (mode & WAIT_MODE_C && FD_ISSET(*sock, &rfds) &&
-      recv(*sock, (char*) &rfds, 0, 0) != 0) {
-    return errno;
-  }
-
   return SUCCESS;
 }
 
diff --git a/lib/php/lib/Transport/TSocket.php b/lib/php/lib/Transport/TSocket.php
index 374037a..8fe60fd 100644
--- a/lib/php/lib/Transport/TSocket.php
+++ b/lib/php/lib/Transport/TSocket.php
@@ -251,8 +251,9 @@
         }
 
         if (function_exists('socket_import_stream') && function_exists('socket_set_option')) {
-            $socket = socket_import_stream($this->handle_);
-            socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1);
+            // warnings silenced due to bug https://bugs.php.net/bug.php?id=70939
+            $socket = @socket_import_stream($this->handle_);
+            @socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1);
         }
     }
 
diff --git a/lib/rs/Cargo.toml b/lib/rs/Cargo.toml
index 0626da8..674a4c3 100644
--- a/lib/rs/Cargo.toml
+++ b/lib/rs/Cargo.toml
@@ -1,6 +1,7 @@
 [package]
 name = "thrift"
 description = "Rust bindings for the Apache Thrift RPC system"
+edition = "2018"
 version = "0.14.0"
 license = "Apache-2.0"
 authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
diff --git a/lib/rs/README.md b/lib/rs/README.md
index f518f4e..1b608b2 100644
--- a/lib/rs/README.md
+++ b/lib/rs/README.md
@@ -46,6 +46,14 @@
 
 Breaking changes are minimized. When they are made they will be outlined below with transition guidelines.
 
+##### Thrift 0.14.0
+
+* **[THRIFT-5158]** - Rust library and generator now support Rust 2018 only
+
+    The Rust `thrift` library was updated to Rust 2018 via `cargo fix --edition`.
+    All test code in the repo was updated as well. The code generator was also updated
+    to support Rust 2018 only.
+
 ##### Thrift 0.13.0
 
 * **[THRIFT-4536]** - Use TryFrom from std, required rust 1.34.0 or higher
diff --git a/lib/rs/src/autogen.rs b/lib/rs/src/autogen.rs
index 6806a08..9e45272 100644
--- a/lib/rs/src/autogen.rs
+++ b/lib/rs/src/autogen.rs
@@ -22,7 +22,7 @@
 //! to implement required functionality. Users should never have to use code
 //! in this module directly.
 
-use protocol::{TInputProtocol, TOutputProtocol};
+use crate::protocol::{TInputProtocol, TOutputProtocol};
 
 /// Specifies the minimum functionality an auto-generated client should provide
 /// to communicate with a Thrift server.
diff --git a/lib/rs/src/errors.rs b/lib/rs/src/errors.rs
index 68cdc9c..2167875 100644
--- a/lib/rs/src/errors.rs
+++ b/lib/rs/src/errors.rs
@@ -21,7 +21,7 @@
 use std::{error, fmt, io, string};
 use std::convert::TryFrom;
 
-use protocol::{TFieldIdentifier, TInputProtocol, TOutputProtocol, TStructIdentifier, TType};
+use crate::protocol::{TFieldIdentifier, TInputProtocol, TOutputProtocol, TStructIdentifier, TType};
 
 // FIXME: should all my error structs impl error::Error as well?
 // FIXME: should all fields in TransportError, ProtocolError and ApplicationError be optional?
@@ -197,7 +197,7 @@
     /// Application code **should never** call this method directly.
     pub fn read_application_error_from_in_protocol(
         i: &mut dyn TInputProtocol,
-    ) -> ::Result<ApplicationError> {
+    ) -> crate::Result<ApplicationError> {
         let mut message = "general remote error".to_owned();
         let mut kind = ApplicationErrorKind::Unknown;
 
@@ -248,7 +248,7 @@
     pub fn write_application_error_to_out_protocol(
         e: &ApplicationError,
         o: &mut dyn TOutputProtocol,
-    ) -> ::Result<()> {
+    ) -> crate::Result<()> {
         o.write_struct_begin(&TStructIdentifier {
             name: "TApplicationException".to_owned(),
         })?;
diff --git a/lib/rs/src/lib.rs b/lib/rs/src/lib.rs
index cdd60f0..b762e05 100644
--- a/lib/rs/src/lib.rs
+++ b/lib/rs/src/lib.rs
@@ -76,10 +76,10 @@
 pub mod transport;
 
 mod errors;
-pub use errors::*;
+pub use crate::errors::*;
 
 mod autogen;
-pub use autogen::*;
+pub use crate::autogen::*;
 
 /// Result type returned by all runtime library functions.
 ///
diff --git a/lib/rs/src/protocol/binary.rs b/lib/rs/src/protocol/binary.rs
index 2069cf9..0ef65e5 100644
--- a/lib/rs/src/protocol/binary.rs
+++ b/lib/rs/src/protocol/binary.rs
@@ -23,8 +23,8 @@
     TMessageIdentifier, TMessageType,
 };
 use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
-use transport::{TReadTransport, TWriteTransport};
-use {ProtocolError, ProtocolErrorKind};
+use crate::transport::{TReadTransport, TWriteTransport};
+use crate::{ProtocolError, ProtocolErrorKind};
 
 const BINARY_PROTOCOL_VERSION_1: u32 = 0x80010000;
 
@@ -80,7 +80,7 @@
     T: TReadTransport,
 {
     #[cfg_attr(feature = "cargo-clippy", allow(collapsible_if))]
-    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+    fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
         let mut first_bytes = vec![0; 4];
         self.transport.read_exact(&mut first_bytes[..])?;
 
@@ -91,7 +91,7 @@
             // 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 {
+                Err(crate::Error::Protocol(ProtocolError {
                     kind: ProtocolErrorKind::BadVersion,
                     message: format!("received bad version: {:?}", &first_bytes[0..2]),
                 }))
@@ -107,7 +107,7 @@
             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 {
+                Err(crate::Error::Protocol(ProtocolError {
                     kind: ProtocolErrorKind::BadVersion,
                     message: format!("received bad version: {:?}", &first_bytes[0..2]),
                 }))
@@ -128,19 +128,19 @@
         }
     }
 
-    fn read_message_end(&mut self) -> ::Result<()> {
+    fn read_message_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+    fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
         Ok(None)
     }
 
-    fn read_struct_end(&mut self) -> ::Result<()> {
+    fn read_struct_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+    fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
         let field_type_byte = self.read_byte()?;
         let field_type = field_type_from_u8(field_type_byte)?;
         let id = match field_type {
@@ -152,11 +152,11 @@
         ))
     }
 
-    fn read_field_end(&mut self) -> ::Result<()> {
+    fn read_field_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+    fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
         let num_bytes = self.transport.read_i32::<BigEndian>()? as usize;
         let mut buf = vec![0u8; num_bytes];
         self.transport
@@ -165,7 +165,7 @@
             .map_err(From::from)
     }
 
-    fn read_bool(&mut self) -> ::Result<bool> {
+    fn read_bool(&mut self) -> crate::Result<bool> {
         let b = self.read_i8()?;
         match b {
             0 => Ok(false),
@@ -173,66 +173,66 @@
         }
     }
 
-    fn read_i8(&mut self) -> ::Result<i8> {
+    fn read_i8(&mut self) -> crate::Result<i8> {
         self.transport.read_i8().map_err(From::from)
     }
 
-    fn read_i16(&mut self) -> ::Result<i16> {
+    fn read_i16(&mut self) -> crate::Result<i16> {
         self.transport.read_i16::<BigEndian>().map_err(From::from)
     }
 
-    fn read_i32(&mut self) -> ::Result<i32> {
+    fn read_i32(&mut self) -> crate::Result<i32> {
         self.transport.read_i32::<BigEndian>().map_err(From::from)
     }
 
-    fn read_i64(&mut self) -> ::Result<i64> {
+    fn read_i64(&mut self) -> crate::Result<i64> {
         self.transport.read_i64::<BigEndian>().map_err(From::from)
     }
 
-    fn read_double(&mut self) -> ::Result<f64> {
+    fn read_double(&mut self) -> crate::Result<f64> {
         self.transport.read_f64::<BigEndian>().map_err(From::from)
     }
 
-    fn read_string(&mut self) -> ::Result<String> {
+    fn read_string(&mut self) -> crate::Result<String> {
         let bytes = self.read_bytes()?;
         String::from_utf8(bytes).map_err(From::from)
     }
 
-    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+    fn read_list_begin(&mut self) -> crate::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<()> {
+    fn read_list_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+    fn read_set_begin(&mut self) -> crate::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<()> {
+    fn read_set_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+    fn read_map_begin(&mut self) -> crate::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<()> {
+    fn read_map_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
     // utility
     //
 
-    fn read_byte(&mut self) -> ::Result<u8> {
+    fn read_byte(&mut self) -> crate::Result<u8> {
         self.transport.read_u8().map_err(From::from)
     }
 }
@@ -305,7 +305,7 @@
 where
     T: TWriteTransport,
 {
-    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
         if self.strict {
             let message_type: u8 = identifier.message_type.into();
             let header = BINARY_PROTOCOL_VERSION_1 | (message_type as u32);
@@ -319,21 +319,21 @@
         }
     }
 
-    fn write_message_end(&mut self) -> ::Result<()> {
+    fn write_message_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
+    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::Result<()> {
         Ok(())
     }
 
-    fn write_struct_end(&mut self) -> ::Result<()> {
+    fn write_struct_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
         if identifier.id.is_none() && identifier.field_type != TType::Stop {
-            return Err(::Error::Protocol(ProtocolError {
+            return Err(crate::Error::Protocol(ProtocolError {
                 kind: ProtocolErrorKind::Unknown,
                 message: format!(
                     "cannot write identifier {:?} without sequence number",
@@ -350,20 +350,20 @@
         }
     }
 
-    fn write_field_end(&mut self) -> ::Result<()> {
+    fn write_field_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn write_field_stop(&mut self) -> ::Result<()> {
+    fn write_field_stop(&mut self) -> crate::Result<()> {
         self.write_byte(field_type_to_u8(TType::Stop))
     }
 
-    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+    fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
         self.write_i32(b.len() as i32)?;
         self.transport.write_all(b).map_err(From::from)
     }
 
-    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+    fn write_bool(&mut self, b: bool) -> crate::Result<()> {
         if b {
             self.write_i8(1)
         } else {
@@ -371,49 +371,49 @@
         }
     }
 
-    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+    fn write_i8(&mut self, i: i8) -> crate::Result<()> {
         self.transport.write_i8(i).map_err(From::from)
     }
 
-    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+    fn write_i16(&mut self, i: i16) -> crate::Result<()> {
         self.transport.write_i16::<BigEndian>(i).map_err(From::from)
     }
 
-    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+    fn write_i32(&mut self, i: i32) -> crate::Result<()> {
         self.transport.write_i32::<BigEndian>(i).map_err(From::from)
     }
 
-    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+    fn write_i64(&mut self, i: i64) -> crate::Result<()> {
         self.transport.write_i64::<BigEndian>(i).map_err(From::from)
     }
 
-    fn write_double(&mut self, d: f64) -> ::Result<()> {
+    fn write_double(&mut self, d: f64) -> crate::Result<()> {
         self.transport.write_f64::<BigEndian>(d).map_err(From::from)
     }
 
-    fn write_string(&mut self, s: &str) -> ::Result<()> {
+    fn write_string(&mut self, s: &str) -> crate::Result<()> {
         self.write_bytes(s.as_bytes())
     }
 
-    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
         self.write_byte(field_type_to_u8(identifier.element_type))?;
         self.write_i32(identifier.size)
     }
 
-    fn write_list_end(&mut self) -> ::Result<()> {
+    fn write_list_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
         self.write_byte(field_type_to_u8(identifier.element_type))?;
         self.write_i32(identifier.size)
     }
 
-    fn write_set_end(&mut self) -> ::Result<()> {
+    fn write_set_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
         let key_type = identifier
             .key_type
             .expect("map identifier to write should contain key type");
@@ -425,18 +425,18 @@
         self.write_i32(identifier.size)
     }
 
-    fn write_map_end(&mut self) -> ::Result<()> {
+    fn write_map_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn flush(&mut self) -> ::Result<()> {
+    fn flush(&mut self) -> crate::Result<()> {
         self.transport.flush().map_err(From::from)
     }
 
     // utility
     //
 
-    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+    fn write_byte(&mut self, b: u8) -> crate::Result<()> {
         self.transport.write_u8(b).map_err(From::from)
     }
 }
@@ -478,7 +478,7 @@
     }
 }
 
-fn field_type_from_u8(b: u8) -> ::Result<TType> {
+fn field_type_from_u8(b: u8) -> crate::Result<TType> {
     match b {
         0x00 => Ok(TType::Stop),
         0x01 => Ok(TType::Void),
@@ -495,7 +495,7 @@
         0x0F => Ok(TType::List),
         0x10 => Ok(TType::Utf8),
         0x11 => Ok(TType::Utf16),
-        unkn => Err(::Error::Protocol(ProtocolError {
+        unkn => Err(crate::Error::Protocol(ProtocolError {
             kind: ProtocolErrorKind::InvalidData,
             message: format!("cannot convert {} to TType", unkn),
         })),
@@ -505,11 +505,11 @@
 #[cfg(test)]
 mod tests {
 
-    use protocol::{
+    use crate::protocol::{
         TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
         TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
     };
-    use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
+    use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
 
     use super::*;
 
@@ -947,7 +947,7 @@
 
     fn assert_no_write<F>(mut write_fn: F, strict: bool)
     where
-        F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> ::Result<()>,
+        F: FnMut(&mut TBinaryOutputProtocol<WriteHalf<TBufferChannel>>) -> crate::Result<()>,
     {
         let (_, mut o_prot) = test_objects(strict);
         assert!(write_fn(&mut o_prot).is_ok());
diff --git a/lib/rs/src/protocol/compact.rs b/lib/rs/src/protocol/compact.rs
index 029f850..f33c020 100644
--- a/lib/rs/src/protocol/compact.rs
+++ b/lib/rs/src/protocol/compact.rs
@@ -25,7 +25,7 @@
     TMessageIdentifier, TMessageType,
 };
 use super::{TOutputProtocol, TOutputProtocolFactory, TSetIdentifier, TStructIdentifier, TType};
-use transport::{TReadTransport, TWriteTransport};
+use crate::transport::{TReadTransport, TWriteTransport};
 
 const COMPACT_PROTOCOL_ID: u8 = 0x82;
 const COMPACT_VERSION: u8 = 0x01;
@@ -80,7 +80,7 @@
         }
     }
 
-    fn read_list_set_begin(&mut self) -> ::Result<(TType, i32)> {
+    fn read_list_set_begin(&mut self) -> crate::Result<(TType, i32)> {
         let header = self.read_byte()?;
         let element_type = collection_u8_to_type(header & 0x0F)?;
 
@@ -101,11 +101,11 @@
 where
     T: TReadTransport,
 {
-    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+    fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
         let compact_id = self.read_byte()?;
         if compact_id != COMPACT_PROTOCOL_ID {
-            Err(::Error::Protocol(::ProtocolError {
-                kind: ::ProtocolErrorKind::BadVersion,
+            Err(crate::Error::Protocol(crate::ProtocolError {
+                kind: crate::ProtocolErrorKind::BadVersion,
                 message: format!("invalid compact protocol header {:?}", compact_id),
             }))
         } else {
@@ -115,8 +115,8 @@
         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,
+            Err(crate::Error::Protocol(crate::ProtocolError {
+                kind: crate::ProtocolErrorKind::BadVersion,
                 message: format!(
                     "cannot process compact protocol version {:?}",
                     received_version
@@ -140,17 +140,17 @@
         ))
     }
 
-    fn read_message_end(&mut self) -> ::Result<()> {
+    fn read_message_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+    fn read_struct_begin(&mut self) -> crate::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<()> {
+    fn read_struct_end(&mut self) -> crate::Result<()> {
         self.last_read_field_id = self
             .read_field_id_stack
             .pop()
@@ -158,7 +158,7 @@
         Ok(())
     }
 
-    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+    fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
         // we can read at least one byte, which is:
         // - the type
         // - the field delta and the type
@@ -200,11 +200,11 @@
         }
     }
 
-    fn read_field_end(&mut self) -> ::Result<()> {
+    fn read_field_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_bool(&mut self) -> ::Result<bool> {
+    fn read_bool(&mut self) -> crate::Result<bool> {
         match self.pending_read_bool_value.take() {
             Some(b) => Ok(b),
             None => {
@@ -212,8 +212,8 @@
                 match b {
                     0x01 => Ok(true),
                     0x02 => Ok(false),
-                    unkn => Err(::Error::Protocol(::ProtocolError {
-                        kind: ::ProtocolErrorKind::InvalidData,
+                    unkn => Err(crate::Error::Protocol(crate::ProtocolError {
+                        kind: crate::ProtocolErrorKind::InvalidData,
                         message: format!("cannot convert {} into bool", unkn),
                     })),
                 }
@@ -221,7 +221,7 @@
         }
     }
 
-    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+    fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
         let len = self.transport.read_varint::<u32>()?;
         let mut buf = vec![0u8; len as usize];
         self.transport
@@ -230,50 +230,50 @@
             .map(|_| buf)
     }
 
-    fn read_i8(&mut self) -> ::Result<i8> {
+    fn read_i8(&mut self) -> crate::Result<i8> {
         self.read_byte().map(|i| i as i8)
     }
 
-    fn read_i16(&mut self) -> ::Result<i16> {
+    fn read_i16(&mut self) -> crate::Result<i16> {
         self.transport.read_varint::<i16>().map_err(From::from)
     }
 
-    fn read_i32(&mut self) -> ::Result<i32> {
+    fn read_i32(&mut self) -> crate::Result<i32> {
         self.transport.read_varint::<i32>().map_err(From::from)
     }
 
-    fn read_i64(&mut self) -> ::Result<i64> {
+    fn read_i64(&mut self) -> crate::Result<i64> {
         self.transport.read_varint::<i64>().map_err(From::from)
     }
 
-    fn read_double(&mut self) -> ::Result<f64> {
+    fn read_double(&mut self) -> crate::Result<f64> {
         self.transport.read_f64::<LittleEndian>().map_err(From::from)
     }
 
-    fn read_string(&mut self) -> ::Result<String> {
+    fn read_string(&mut self) -> crate::Result<String> {
         let bytes = self.read_bytes()?;
         String::from_utf8(bytes).map_err(From::from)
     }
 
-    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+    fn read_list_begin(&mut self) -> crate::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<()> {
+    fn read_list_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+    fn read_set_begin(&mut self) -> crate::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<()> {
+    fn read_set_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+    fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
         let element_count = self.transport.read_varint::<u32>()? as i32;
         if element_count == 0 {
             Ok(TMapIdentifier::new(None, None, 0))
@@ -285,14 +285,14 @@
         }
     }
 
-    fn read_map_end(&mut self) -> ::Result<()> {
+    fn read_map_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
     // utility
     //
 
-    fn read_byte(&mut self) -> ::Result<u8> {
+    fn read_byte(&mut self) -> crate::Result<u8> {
         let mut buf = [0u8; 1];
         self.transport
             .read_exact(&mut buf)
@@ -376,7 +376,7 @@
     }
 
     // FIXME: field_type as unconstrained u8 is bad
-    fn write_field_header(&mut self, field_type: u8, field_id: i16) -> ::Result<()> {
+    fn write_field_header(&mut self, field_type: u8, field_id: i16) -> crate::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)?;
@@ -388,7 +388,7 @@
         Ok(())
     }
 
-    fn write_list_set_begin(&mut self, element_type: TType, element_count: i32) -> ::Result<()> {
+    fn write_list_set_begin(&mut self, element_type: TType, element_count: i32) -> crate::Result<()> {
         let elem_identifier = collection_type_to_u8(element_type);
         if element_count <= 14 {
             let header = (element_count as u8) << 4 | elem_identifier;
@@ -414,7 +414,7 @@
 where
     T: TWriteTransport,
 {
-    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
         self.write_byte(COMPACT_PROTOCOL_ID)?;
         self.write_byte((u8::from(identifier.message_type) << 5) | COMPACT_VERSION)?;
         self.write_i32(identifier.sequence_number)?;
@@ -422,18 +422,18 @@
         Ok(())
     }
 
-    fn write_message_end(&mut self) -> ::Result<()> {
+    fn write_message_end(&mut self) -> crate::Result<()> {
         self.assert_no_pending_bool_write();
         Ok(())
     }
 
-    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> ::Result<()> {
+    fn write_struct_begin(&mut self, _: &TStructIdentifier) -> crate::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<()> {
+    fn write_struct_end(&mut self) -> crate::Result<()> {
         self.assert_no_pending_bool_write();
         self.last_write_field_id = self
             .write_field_id_stack
@@ -442,7 +442,7 @@
         Ok(())
     }
 
-    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
         match identifier.field_type {
             TType::Bool => {
                 if self.pending_write_bool_field_identifier.is_some() {
@@ -463,17 +463,17 @@
         }
     }
 
-    fn write_field_end(&mut self) -> ::Result<()> {
+    fn write_field_end(&mut self) -> crate::Result<()> {
         self.assert_no_pending_bool_write();
         Ok(())
     }
 
-    fn write_field_stop(&mut self) -> ::Result<()> {
+    fn write_field_stop(&mut self) -> crate::Result<()> {
         self.assert_no_pending_bool_write();
         self.write_byte(type_to_u8(TType::Stop))
     }
 
-    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+    fn write_bool(&mut self, b: bool) -> crate::Result<()> {
         match self.pending_write_bool_field_identifier.take() {
             Some(pending) => {
                 let field_id = pending.id.expect("bool field should have a field id");
@@ -490,61 +490,61 @@
         }
     }
 
-    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+    fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
         self.transport.write_varint(b.len() as u32)?;
         self.transport.write_all(b).map_err(From::from)
     }
 
-    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+    fn write_i8(&mut self, i: i8) -> crate::Result<()> {
         self.write_byte(i as u8)
     }
 
-    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+    fn write_i16(&mut self, i: i16) -> crate::Result<()> {
         self.transport
             .write_varint(i)
             .map_err(From::from)
             .map(|_| ())
     }
 
-    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+    fn write_i32(&mut self, i: i32) -> crate::Result<()> {
         self.transport
             .write_varint(i)
             .map_err(From::from)
             .map(|_| ())
     }
 
-    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+    fn write_i64(&mut self, i: i64) -> crate::Result<()> {
         self.transport
             .write_varint(i)
             .map_err(From::from)
             .map(|_| ())
     }
 
-    fn write_double(&mut self, d: f64) -> ::Result<()> {
+    fn write_double(&mut self, d: f64) -> crate::Result<()> {
         self.transport.write_f64::<LittleEndian>(d).map_err(From::from)
     }
 
-    fn write_string(&mut self, s: &str) -> ::Result<()> {
+    fn write_string(&mut self, s: &str) -> crate::Result<()> {
         self.write_bytes(s.as_bytes())
     }
 
-    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
         self.write_list_set_begin(identifier.element_type, identifier.size)
     }
 
-    fn write_list_end(&mut self) -> ::Result<()> {
+    fn write_list_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
         self.write_list_set_begin(identifier.element_type, identifier.size)
     }
 
-    fn write_set_end(&mut self) -> ::Result<()> {
+    fn write_set_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
         if identifier.size == 0 {
             self.write_byte(0)
         } else {
@@ -565,18 +565,18 @@
         }
     }
 
-    fn write_map_end(&mut self) -> ::Result<()> {
+    fn write_map_end(&mut self) -> crate::Result<()> {
         Ok(())
     }
 
-    fn flush(&mut self) -> ::Result<()> {
+    fn flush(&mut self) -> crate::Result<()> {
         self.transport.flush().map_err(From::from)
     }
 
     // utility
     //
 
-    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+    fn write_byte(&mut self, b: u8) -> crate::Result<()> {
         self.transport.write(&[b]).map_err(From::from).map(|_| ())
     }
 }
@@ -625,14 +625,14 @@
     }
 }
 
-fn collection_u8_to_type(b: u8) -> ::Result<TType> {
+fn collection_u8_to_type(b: u8) -> crate::Result<TType> {
     match b {
         0x01 => Ok(TType::Bool),
         o => u8_to_type(o),
     }
 }
 
-fn u8_to_type(b: u8) -> ::Result<TType> {
+fn u8_to_type(b: u8) -> crate::Result<TType> {
     match b {
         0x00 => Ok(TType::Stop),
         0x03 => Ok(TType::I08), // equivalent to TType::Byte
@@ -645,8 +645,8 @@
         0x0A => Ok(TType::Set),
         0x0B => Ok(TType::Map),
         0x0C => Ok(TType::Struct),
-        unkn => Err(::Error::Protocol(::ProtocolError {
-            kind: ::ProtocolErrorKind::InvalidData,
+        unkn => Err(crate::Error::Protocol(crate::ProtocolError {
+            kind: crate::ProtocolErrorKind::InvalidData,
             message: format!("cannot convert {} into TType", unkn),
         })),
     }
@@ -655,11 +655,11 @@
 #[cfg(test)]
 mod tests {
 
-    use protocol::{
+    use crate::protocol::{
         TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
         TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
     };
-    use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
+    use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
 
     use super::*;
 
@@ -2424,7 +2424,7 @@
 
     fn assert_no_write<F>(mut write_fn: F)
     where
-        F: FnMut(&mut TCompactOutputProtocol<WriteHalf<TBufferChannel>>) -> ::Result<()>,
+        F: FnMut(&mut TCompactOutputProtocol<WriteHalf<TBufferChannel>>) -> crate::Result<()>,
     {
         let (_, mut o_prot) = test_objects();
         assert!(write_fn(&mut o_prot).is_ok());
diff --git a/lib/rs/src/protocol/mod.rs b/lib/rs/src/protocol/mod.rs
index 2d8513f..b0e9118 100644
--- a/lib/rs/src/protocol/mod.rs
+++ b/lib/rs/src/protocol/mod.rs
@@ -61,8 +61,8 @@
 use std::fmt;
 use std::fmt::{Display, Formatter};
 
-use transport::{TReadTransport, TWriteTransport};
-use {ProtocolError, ProtocolErrorKind};
+use crate::transport::{TReadTransport, TWriteTransport};
+use crate::{ProtocolError, ProtocolErrorKind};
 
 #[cfg(test)]
 macro_rules! assert_eq_written_bytes {
@@ -138,54 +138,54 @@
 /// ```
 pub trait TInputProtocol {
     /// Read the beginning of a Thrift message.
-    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier>;
+    fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier>;
     /// Read the end of a Thrift message.
-    fn read_message_end(&mut self) -> ::Result<()>;
+    fn read_message_end(&mut self) -> crate::Result<()>;
     /// Read the beginning of a Thrift struct.
-    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>>;
+    fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>>;
     /// Read the end of a Thrift struct.
-    fn read_struct_end(&mut self) -> ::Result<()>;
+    fn read_struct_end(&mut self) -> crate::Result<()>;
     /// Read the beginning of a Thrift struct field.
-    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier>;
+    fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier>;
     /// Read the end of a Thrift struct field.
-    fn read_field_end(&mut self) -> ::Result<()>;
+    fn read_field_end(&mut self) -> crate::Result<()>;
     /// Read a bool.
-    fn read_bool(&mut self) -> ::Result<bool>;
+    fn read_bool(&mut self) -> crate::Result<bool>;
     /// Read a fixed-length byte array.
-    fn read_bytes(&mut self) -> ::Result<Vec<u8>>;
+    fn read_bytes(&mut self) -> crate::Result<Vec<u8>>;
     /// Read a word.
-    fn read_i8(&mut self) -> ::Result<i8>;
+    fn read_i8(&mut self) -> crate::Result<i8>;
     /// Read a 16-bit signed integer.
-    fn read_i16(&mut self) -> ::Result<i16>;
+    fn read_i16(&mut self) -> crate::Result<i16>;
     /// Read a 32-bit signed integer.
-    fn read_i32(&mut self) -> ::Result<i32>;
+    fn read_i32(&mut self) -> crate::Result<i32>;
     /// Read a 64-bit signed integer.
-    fn read_i64(&mut self) -> ::Result<i64>;
+    fn read_i64(&mut self) -> crate::Result<i64>;
     /// Read a 64-bit float.
-    fn read_double(&mut self) -> ::Result<f64>;
+    fn read_double(&mut self) -> crate::Result<f64>;
     /// Read a fixed-length string (not null terminated).
-    fn read_string(&mut self) -> ::Result<String>;
+    fn read_string(&mut self) -> crate::Result<String>;
     /// Read the beginning of a list.
-    fn read_list_begin(&mut self) -> ::Result<TListIdentifier>;
+    fn read_list_begin(&mut self) -> crate::Result<TListIdentifier>;
     /// Read the end of a list.
-    fn read_list_end(&mut self) -> ::Result<()>;
+    fn read_list_end(&mut self) -> crate::Result<()>;
     /// Read the beginning of a set.
-    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier>;
+    fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier>;
     /// Read the end of a set.
-    fn read_set_end(&mut self) -> ::Result<()>;
+    fn read_set_end(&mut self) -> crate::Result<()>;
     /// Read the beginning of a map.
-    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier>;
+    fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier>;
     /// Read the end of a map.
-    fn read_map_end(&mut self) -> ::Result<()>;
+    fn read_map_end(&mut self) -> crate::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<()> {
+    fn skip(&mut self, field_type: TType) -> crate::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<()> {
+    fn skip_till_depth(&mut self, field_type: TType, depth: i8) -> crate::Result<()> {
         if depth == 0 {
-            return Err(::Error::Protocol(ProtocolError {
+            return Err(crate::Error::Protocol(ProtocolError {
                 kind: ProtocolErrorKind::DepthLimit,
                 message: format!("cannot parse past {:?}", field_type),
             }));
@@ -238,7 +238,7 @@
                 }
                 self.read_map_end()
             }
-            u => Err(::Error::Protocol(ProtocolError {
+            u => Err(crate::Error::Protocol(ProtocolError {
                 kind: ProtocolErrorKind::Unknown,
                 message: format!("cannot skip field type {:?}", &u),
             })),
@@ -251,7 +251,7 @@
     /// Read an unsigned byte.
     ///
     /// This method should **never** be used in generated code.
-    fn read_byte(&mut self) -> ::Result<u8>;
+    fn read_byte(&mut self) -> crate::Result<u8>;
 }
 
 /// Converts Thrift identifiers, primitives, containers or structs into a
@@ -287,50 +287,50 @@
 /// ```
 pub trait TOutputProtocol {
     /// Write the beginning of a Thrift message.
-    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()>;
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()>;
     /// Write the end of a Thrift message.
-    fn write_message_end(&mut self) -> ::Result<()>;
+    fn write_message_end(&mut self) -> crate::Result<()>;
     /// Write the beginning of a Thrift struct.
-    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> ::Result<()>;
+    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()>;
     /// Write the end of a Thrift struct.
-    fn write_struct_end(&mut self) -> ::Result<()>;
+    fn write_struct_end(&mut self) -> crate::Result<()>;
     /// Write the beginning of a Thrift field.
-    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()>;
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()>;
     /// Write the end of a Thrift field.
-    fn write_field_end(&mut self) -> ::Result<()>;
+    fn write_field_end(&mut self) -> crate::Result<()>;
     /// Write a STOP field indicating that all the fields in a struct have been
     /// written.
-    fn write_field_stop(&mut self) -> ::Result<()>;
+    fn write_field_stop(&mut self) -> crate::Result<()>;
     /// Write a bool.
-    fn write_bool(&mut self, b: bool) -> ::Result<()>;
+    fn write_bool(&mut self, b: bool) -> crate::Result<()>;
     /// Write a fixed-length byte array.
-    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()>;
+    fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()>;
     /// Write an 8-bit signed integer.
-    fn write_i8(&mut self, i: i8) -> ::Result<()>;
+    fn write_i8(&mut self, i: i8) -> crate::Result<()>;
     /// Write a 16-bit signed integer.
-    fn write_i16(&mut self, i: i16) -> ::Result<()>;
+    fn write_i16(&mut self, i: i16) -> crate::Result<()>;
     /// Write a 32-bit signed integer.
-    fn write_i32(&mut self, i: i32) -> ::Result<()>;
+    fn write_i32(&mut self, i: i32) -> crate::Result<()>;
     /// Write a 64-bit signed integer.
-    fn write_i64(&mut self, i: i64) -> ::Result<()>;
+    fn write_i64(&mut self, i: i64) -> crate::Result<()>;
     /// Write a 64-bit float.
-    fn write_double(&mut self, d: f64) -> ::Result<()>;
+    fn write_double(&mut self, d: f64) -> crate::Result<()>;
     /// Write a fixed-length string.
-    fn write_string(&mut self, s: &str) -> ::Result<()>;
+    fn write_string(&mut self, s: &str) -> crate::Result<()>;
     /// Write the beginning of a list.
-    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()>;
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()>;
     /// Write the end of a list.
-    fn write_list_end(&mut self) -> ::Result<()>;
+    fn write_list_end(&mut self) -> crate::Result<()>;
     /// Write the beginning of a set.
-    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()>;
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()>;
     /// Write the end of a set.
-    fn write_set_end(&mut self) -> ::Result<()>;
+    fn write_set_end(&mut self) -> crate::Result<()>;
     /// Write the beginning of a map.
-    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()>;
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()>;
     /// Write the end of a map.
-    fn write_map_end(&mut self) -> ::Result<()>;
+    fn write_map_end(&mut self) -> crate::Result<()>;
     /// Flush buffered bytes to the underlying transport.
-    fn flush(&mut self) -> ::Result<()>;
+    fn flush(&mut self) -> crate::Result<()>;
 
     // utility (DO NOT USE IN GENERATED CODE!!!!)
     //
@@ -338,94 +338,94 @@
     /// Write an unsigned byte.
     ///
     /// This method should **never** be used in generated code.
-    fn write_byte(&mut self, b: u8) -> ::Result<()>; // FIXME: REMOVE
+    fn write_byte(&mut self, b: u8) -> crate::Result<()>; // FIXME: REMOVE
 }
 
 impl<P> TInputProtocol for Box<P>
 where
     P: TInputProtocol + ?Sized,
 {
-    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+    fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
         (**self).read_message_begin()
     }
 
-    fn read_message_end(&mut self) -> ::Result<()> {
+    fn read_message_end(&mut self) -> crate::Result<()> {
         (**self).read_message_end()
     }
 
-    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+    fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
         (**self).read_struct_begin()
     }
 
-    fn read_struct_end(&mut self) -> ::Result<()> {
+    fn read_struct_end(&mut self) -> crate::Result<()> {
         (**self).read_struct_end()
     }
 
-    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+    fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
         (**self).read_field_begin()
     }
 
-    fn read_field_end(&mut self) -> ::Result<()> {
+    fn read_field_end(&mut self) -> crate::Result<()> {
         (**self).read_field_end()
     }
 
-    fn read_bool(&mut self) -> ::Result<bool> {
+    fn read_bool(&mut self) -> crate::Result<bool> {
         (**self).read_bool()
     }
 
-    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+    fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
         (**self).read_bytes()
     }
 
-    fn read_i8(&mut self) -> ::Result<i8> {
+    fn read_i8(&mut self) -> crate::Result<i8> {
         (**self).read_i8()
     }
 
-    fn read_i16(&mut self) -> ::Result<i16> {
+    fn read_i16(&mut self) -> crate::Result<i16> {
         (**self).read_i16()
     }
 
-    fn read_i32(&mut self) -> ::Result<i32> {
+    fn read_i32(&mut self) -> crate::Result<i32> {
         (**self).read_i32()
     }
 
-    fn read_i64(&mut self) -> ::Result<i64> {
+    fn read_i64(&mut self) -> crate::Result<i64> {
         (**self).read_i64()
     }
 
-    fn read_double(&mut self) -> ::Result<f64> {
+    fn read_double(&mut self) -> crate::Result<f64> {
         (**self).read_double()
     }
 
-    fn read_string(&mut self) -> ::Result<String> {
+    fn read_string(&mut self) -> crate::Result<String> {
         (**self).read_string()
     }
 
-    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+    fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
         (**self).read_list_begin()
     }
 
-    fn read_list_end(&mut self) -> ::Result<()> {
+    fn read_list_end(&mut self) -> crate::Result<()> {
         (**self).read_list_end()
     }
 
-    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+    fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
         (**self).read_set_begin()
     }
 
-    fn read_set_end(&mut self) -> ::Result<()> {
+    fn read_set_end(&mut self) -> crate::Result<()> {
         (**self).read_set_end()
     }
 
-    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+    fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
         (**self).read_map_begin()
     }
 
-    fn read_map_end(&mut self) -> ::Result<()> {
+    fn read_map_end(&mut self) -> crate::Result<()> {
         (**self).read_map_end()
     }
 
-    fn read_byte(&mut self) -> ::Result<u8> {
+    fn read_byte(&mut self) -> crate::Result<u8> {
         (**self).read_byte()
     }
 }
@@ -434,95 +434,95 @@
 where
     P: TOutputProtocol + ?Sized,
 {
-    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
         (**self).write_message_begin(identifier)
     }
 
-    fn write_message_end(&mut self) -> ::Result<()> {
+    fn write_message_end(&mut self) -> crate::Result<()> {
         (**self).write_message_end()
     }
 
-    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> ::Result<()> {
+    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()> {
         (**self).write_struct_begin(identifier)
     }
 
-    fn write_struct_end(&mut self) -> ::Result<()> {
+    fn write_struct_end(&mut self) -> crate::Result<()> {
         (**self).write_struct_end()
     }
 
-    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
         (**self).write_field_begin(identifier)
     }
 
-    fn write_field_end(&mut self) -> ::Result<()> {
+    fn write_field_end(&mut self) -> crate::Result<()> {
         (**self).write_field_end()
     }
 
-    fn write_field_stop(&mut self) -> ::Result<()> {
+    fn write_field_stop(&mut self) -> crate::Result<()> {
         (**self).write_field_stop()
     }
 
-    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+    fn write_bool(&mut self, b: bool) -> crate::Result<()> {
         (**self).write_bool(b)
     }
 
-    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+    fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
         (**self).write_bytes(b)
     }
 
-    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+    fn write_i8(&mut self, i: i8) -> crate::Result<()> {
         (**self).write_i8(i)
     }
 
-    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+    fn write_i16(&mut self, i: i16) -> crate::Result<()> {
         (**self).write_i16(i)
     }
 
-    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+    fn write_i32(&mut self, i: i32) -> crate::Result<()> {
         (**self).write_i32(i)
     }
 
-    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+    fn write_i64(&mut self, i: i64) -> crate::Result<()> {
         (**self).write_i64(i)
     }
 
-    fn write_double(&mut self, d: f64) -> ::Result<()> {
+    fn write_double(&mut self, d: f64) -> crate::Result<()> {
         (**self).write_double(d)
     }
 
-    fn write_string(&mut self, s: &str) -> ::Result<()> {
+    fn write_string(&mut self, s: &str) -> crate::Result<()> {
         (**self).write_string(s)
     }
 
-    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
         (**self).write_list_begin(identifier)
     }
 
-    fn write_list_end(&mut self) -> ::Result<()> {
+    fn write_list_end(&mut self) -> crate::Result<()> {
         (**self).write_list_end()
     }
 
-    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
         (**self).write_set_begin(identifier)
     }
 
-    fn write_set_end(&mut self) -> ::Result<()> {
+    fn write_set_end(&mut self) -> crate::Result<()> {
         (**self).write_set_end()
     }
 
-    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
         (**self).write_map_begin(identifier)
     }
 
-    fn write_map_end(&mut self) -> ::Result<()> {
+    fn write_map_end(&mut self) -> crate::Result<()> {
         (**self).write_map_end()
     }
 
-    fn flush(&mut self) -> ::Result<()> {
+    fn flush(&mut self) -> crate::Result<()> {
         (**self).flush()
     }
 
-    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+    fn write_byte(&mut self, b: u8) -> crate::Result<()> {
         (**self).write_byte(b)
     }
 }
@@ -769,14 +769,14 @@
 }
 
 impl TryFrom<u8> for TMessageType {
-    type Error = ::Error;
+    type Error = crate::Error;
     fn try_from(b: u8) -> Result<Self, Self::Error> {
         match b {
             0x01 => Ok(TMessageType::Call),
             0x02 => Ok(TMessageType::Reply),
             0x03 => Ok(TMessageType::Exception),
             0x04 => Ok(TMessageType::OneWay),
-            unkn => Err(::Error::Protocol(ProtocolError {
+            unkn => Err(crate::Error::Protocol(ProtocolError {
                 kind: ProtocolErrorKind::InvalidData,
                 message: format!("cannot convert {} to TMessageType", unkn),
             })),
@@ -848,12 +848,12 @@
 /// message sequence number `actual`.
 ///
 /// Return `()` if `actual == expected`, `Err` otherwise.
-pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> ::Result<()> {
+pub fn verify_expected_sequence_number(expected: i32, actual: i32) -> crate::Result<()> {
     if expected == actual {
         Ok(())
     } else {
-        Err(::Error::Application(::ApplicationError {
-            kind: ::ApplicationErrorKind::BadSequenceId,
+        Err(crate::Error::Application(crate::ApplicationError {
+            kind: crate::ApplicationErrorKind::BadSequenceId,
             message: format!("expected {} got {}", expected, actual),
         }))
     }
@@ -863,12 +863,12 @@
 /// service-call name `actual`.
 ///
 /// Return `()` if `actual == expected`, `Err` otherwise.
-pub fn verify_expected_service_call(expected: &str, actual: &str) -> ::Result<()> {
+pub fn verify_expected_service_call(expected: &str, actual: &str) -> crate::Result<()> {
     if expected == actual {
         Ok(())
     } else {
-        Err(::Error::Application(::ApplicationError {
-            kind: ::ApplicationErrorKind::WrongMethodName,
+        Err(crate::Error::Application(crate::ApplicationError {
+            kind: crate::ApplicationErrorKind::WrongMethodName,
             message: format!("expected {} got {}", expected, actual),
         }))
     }
@@ -878,12 +878,12 @@
 /// `actual`.
 ///
 /// Return `()` if `actual == expected`, `Err` otherwise.
-pub fn verify_expected_message_type(expected: TMessageType, actual: TMessageType) -> ::Result<()> {
+pub fn verify_expected_message_type(expected: TMessageType, actual: TMessageType) -> crate::Result<()> {
     if expected == actual {
         Ok(())
     } else {
-        Err(::Error::Application(::ApplicationError {
-            kind: ::ApplicationErrorKind::InvalidMessageType,
+        Err(crate::Error::Application(crate::ApplicationError {
+            kind: crate::ApplicationErrorKind::InvalidMessageType,
             message: format!("expected {} got {}", expected, actual),
         }))
     }
@@ -892,11 +892,11 @@
 /// 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<()> {
+pub fn verify_required_field_exists<T>(field_name: &str, field: &Option<T>) -> crate::Result<()> {
     match *field {
         Some(_) => Ok(()),
-        None => Err(::Error::Protocol(::ProtocolError {
-            kind: ::ProtocolErrorKind::Unknown,
+        None => Err(crate::Error::Protocol(crate::ProtocolError {
+            kind: crate::ProtocolErrorKind::Unknown,
             message: format!("missing required field {}", field_name),
         })),
     }
@@ -907,10 +907,10 @@
 /// `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> {
+pub fn field_id(field_ident: &TFieldIdentifier) -> crate::Result<i16> {
     field_ident.id.ok_or_else(|| {
-        ::Error::Protocol(::ProtocolError {
-            kind: ::ProtocolErrorKind::Unknown,
+        crate::Error::Protocol(crate::ProtocolError {
+            kind: crate::ProtocolErrorKind::Unknown,
             message: format!("missing field in in {:?}", field_ident),
         })
     })
@@ -922,7 +922,7 @@
     use std::io::Cursor;
 
     use super::*;
-    use transport::{TReadTransport, TWriteTransport};
+    use crate::transport::{TReadTransport, TWriteTransport};
 
     #[test]
     fn must_create_usable_input_protocol_from_concrete_input_protocol() {
diff --git a/lib/rs/src/protocol/multiplexed.rs b/lib/rs/src/protocol/multiplexed.rs
index aaee44f..9c3ba7c 100644
--- a/lib/rs/src/protocol/multiplexed.rs
+++ b/lib/rs/src/protocol/multiplexed.rs
@@ -82,7 +82,7 @@
 where
     P: TOutputProtocol,
 {
-    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> ::Result<()> {
+    fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
         match identifier.message_type {
             // FIXME: is there a better way to override identifier here?
             TMessageType::Call | TMessageType::OneWay => {
@@ -96,94 +96,94 @@
         }
     }
 
-    fn write_message_end(&mut self) -> ::Result<()> {
+    fn write_message_end(&mut self) -> crate::Result<()> {
         self.inner.write_message_end()
     }
 
-    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> ::Result<()> {
+    fn write_struct_begin(&mut self, identifier: &TStructIdentifier) -> crate::Result<()> {
         self.inner.write_struct_begin(identifier)
     }
 
-    fn write_struct_end(&mut self) -> ::Result<()> {
+    fn write_struct_end(&mut self) -> crate::Result<()> {
         self.inner.write_struct_end()
     }
 
-    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> ::Result<()> {
+    fn write_field_begin(&mut self, identifier: &TFieldIdentifier) -> crate::Result<()> {
         self.inner.write_field_begin(identifier)
     }
 
-    fn write_field_end(&mut self) -> ::Result<()> {
+    fn write_field_end(&mut self) -> crate::Result<()> {
         self.inner.write_field_end()
     }
 
-    fn write_field_stop(&mut self) -> ::Result<()> {
+    fn write_field_stop(&mut self) -> crate::Result<()> {
         self.inner.write_field_stop()
     }
 
-    fn write_bytes(&mut self, b: &[u8]) -> ::Result<()> {
+    fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
         self.inner.write_bytes(b)
     }
 
-    fn write_bool(&mut self, b: bool) -> ::Result<()> {
+    fn write_bool(&mut self, b: bool) -> crate::Result<()> {
         self.inner.write_bool(b)
     }
 
-    fn write_i8(&mut self, i: i8) -> ::Result<()> {
+    fn write_i8(&mut self, i: i8) -> crate::Result<()> {
         self.inner.write_i8(i)
     }
 
-    fn write_i16(&mut self, i: i16) -> ::Result<()> {
+    fn write_i16(&mut self, i: i16) -> crate::Result<()> {
         self.inner.write_i16(i)
     }
 
-    fn write_i32(&mut self, i: i32) -> ::Result<()> {
+    fn write_i32(&mut self, i: i32) -> crate::Result<()> {
         self.inner.write_i32(i)
     }
 
-    fn write_i64(&mut self, i: i64) -> ::Result<()> {
+    fn write_i64(&mut self, i: i64) -> crate::Result<()> {
         self.inner.write_i64(i)
     }
 
-    fn write_double(&mut self, d: f64) -> ::Result<()> {
+    fn write_double(&mut self, d: f64) -> crate::Result<()> {
         self.inner.write_double(d)
     }
 
-    fn write_string(&mut self, s: &str) -> ::Result<()> {
+    fn write_string(&mut self, s: &str) -> crate::Result<()> {
         self.inner.write_string(s)
     }
 
-    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> ::Result<()> {
+    fn write_list_begin(&mut self, identifier: &TListIdentifier) -> crate::Result<()> {
         self.inner.write_list_begin(identifier)
     }
 
-    fn write_list_end(&mut self) -> ::Result<()> {
+    fn write_list_end(&mut self) -> crate::Result<()> {
         self.inner.write_list_end()
     }
 
-    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> ::Result<()> {
+    fn write_set_begin(&mut self, identifier: &TSetIdentifier) -> crate::Result<()> {
         self.inner.write_set_begin(identifier)
     }
 
-    fn write_set_end(&mut self) -> ::Result<()> {
+    fn write_set_end(&mut self) -> crate::Result<()> {
         self.inner.write_set_end()
     }
 
-    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> ::Result<()> {
+    fn write_map_begin(&mut self, identifier: &TMapIdentifier) -> crate::Result<()> {
         self.inner.write_map_begin(identifier)
     }
 
-    fn write_map_end(&mut self) -> ::Result<()> {
+    fn write_map_end(&mut self) -> crate::Result<()> {
         self.inner.write_map_end()
     }
 
-    fn flush(&mut self) -> ::Result<()> {
+    fn flush(&mut self) -> crate::Result<()> {
         self.inner.flush()
     }
 
     // utility
     //
 
-    fn write_byte(&mut self, b: u8) -> ::Result<()> {
+    fn write_byte(&mut self, b: u8) -> crate::Result<()> {
         self.inner.write_byte(b)
     }
 }
@@ -191,8 +191,8 @@
 #[cfg(test)]
 mod tests {
 
-    use protocol::{TBinaryOutputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
-    use transport::{TBufferChannel, TIoChannel, WriteHalf};
+    use crate::protocol::{TBinaryOutputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
+    use crate::transport::{TBufferChannel, TIoChannel, WriteHalf};
 
     use super::*;
 
diff --git a/lib/rs/src/protocol/stored.rs b/lib/rs/src/protocol/stored.rs
index bf2d8ba..c5e02fe 100644
--- a/lib/rs/src/protocol/stored.rs
+++ b/lib/rs/src/protocol/stored.rs
@@ -21,7 +21,7 @@
     TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
     TSetIdentifier, TStructIdentifier,
 };
-use ProtocolErrorKind;
+use crate::ProtocolErrorKind;
 
 /// `TInputProtocol` required to use a `TMultiplexedProcessor`.
 ///
@@ -101,95 +101,95 @@
 }
 
 impl<'a> TInputProtocol for TStoredInputProtocol<'a> {
-    fn read_message_begin(&mut self) -> ::Result<TMessageIdentifier> {
+    fn read_message_begin(&mut self) -> crate::Result<TMessageIdentifier> {
         self.message_ident.take().ok_or_else(|| {
-            ::errors::new_protocol_error(
+            crate::errors::new_protocol_error(
                 ProtocolErrorKind::Unknown,
                 "message identifier already read",
             )
         })
     }
 
-    fn read_message_end(&mut self) -> ::Result<()> {
+    fn read_message_end(&mut self) -> crate::Result<()> {
         self.inner.read_message_end()
     }
 
-    fn read_struct_begin(&mut self) -> ::Result<Option<TStructIdentifier>> {
+    fn read_struct_begin(&mut self) -> crate::Result<Option<TStructIdentifier>> {
         self.inner.read_struct_begin()
     }
 
-    fn read_struct_end(&mut self) -> ::Result<()> {
+    fn read_struct_end(&mut self) -> crate::Result<()> {
         self.inner.read_struct_end()
     }
 
-    fn read_field_begin(&mut self) -> ::Result<TFieldIdentifier> {
+    fn read_field_begin(&mut self) -> crate::Result<TFieldIdentifier> {
         self.inner.read_field_begin()
     }
 
-    fn read_field_end(&mut self) -> ::Result<()> {
+    fn read_field_end(&mut self) -> crate::Result<()> {
         self.inner.read_field_end()
     }
 
-    fn read_bytes(&mut self) -> ::Result<Vec<u8>> {
+    fn read_bytes(&mut self) -> crate::Result<Vec<u8>> {
         self.inner.read_bytes()
     }
 
-    fn read_bool(&mut self) -> ::Result<bool> {
+    fn read_bool(&mut self) -> crate::Result<bool> {
         self.inner.read_bool()
     }
 
-    fn read_i8(&mut self) -> ::Result<i8> {
+    fn read_i8(&mut self) -> crate::Result<i8> {
         self.inner.read_i8()
     }
 
-    fn read_i16(&mut self) -> ::Result<i16> {
+    fn read_i16(&mut self) -> crate::Result<i16> {
         self.inner.read_i16()
     }
 
-    fn read_i32(&mut self) -> ::Result<i32> {
+    fn read_i32(&mut self) -> crate::Result<i32> {
         self.inner.read_i32()
     }
 
-    fn read_i64(&mut self) -> ::Result<i64> {
+    fn read_i64(&mut self) -> crate::Result<i64> {
         self.inner.read_i64()
     }
 
-    fn read_double(&mut self) -> ::Result<f64> {
+    fn read_double(&mut self) -> crate::Result<f64> {
         self.inner.read_double()
     }
 
-    fn read_string(&mut self) -> ::Result<String> {
+    fn read_string(&mut self) -> crate::Result<String> {
         self.inner.read_string()
     }
 
-    fn read_list_begin(&mut self) -> ::Result<TListIdentifier> {
+    fn read_list_begin(&mut self) -> crate::Result<TListIdentifier> {
         self.inner.read_list_begin()
     }
 
-    fn read_list_end(&mut self) -> ::Result<()> {
+    fn read_list_end(&mut self) -> crate::Result<()> {
         self.inner.read_list_end()
     }
 
-    fn read_set_begin(&mut self) -> ::Result<TSetIdentifier> {
+    fn read_set_begin(&mut self) -> crate::Result<TSetIdentifier> {
         self.inner.read_set_begin()
     }
 
-    fn read_set_end(&mut self) -> ::Result<()> {
+    fn read_set_end(&mut self) -> crate::Result<()> {
         self.inner.read_set_end()
     }
 
-    fn read_map_begin(&mut self) -> ::Result<TMapIdentifier> {
+    fn read_map_begin(&mut self) -> crate::Result<TMapIdentifier> {
         self.inner.read_map_begin()
     }
 
-    fn read_map_end(&mut self) -> ::Result<()> {
+    fn read_map_end(&mut self) -> crate::Result<()> {
         self.inner.read_map_end()
     }
 
     // utility
     //
 
-    fn read_byte(&mut self) -> ::Result<u8> {
+    fn read_byte(&mut self) -> crate::Result<u8> {
         self.inner.read_byte()
     }
 }
diff --git a/lib/rs/src/server/mod.rs b/lib/rs/src/server/mod.rs
index f24c113..050feee 100644
--- a/lib/rs/src/server/mod.rs
+++ b/lib/rs/src/server/mod.rs
@@ -17,8 +17,8 @@
 
 //! Types used to implement a Thrift server.
 
-use protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
-use {ApplicationError, ApplicationErrorKind};
+use crate::protocol::{TInputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
+use crate::{ApplicationError, ApplicationErrorKind};
 
 mod multiplexed;
 mod threaded;
@@ -91,19 +91,19 @@
     /// the response to `o`.
     ///
     /// Returns `()` if the handler was executed; `Err` otherwise.
-    fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol) -> ::Result<()>;
+    fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol) -> crate::Result<()>;
 }
 
 /// Convenience function used in generated `TProcessor` implementations to
 /// return an `ApplicationError` if thrift message processing failed.
 pub fn handle_process_result(
     msg_ident: &TMessageIdentifier,
-    res: ::Result<()>,
+    res: crate::Result<()>,
     o_prot: &mut dyn TOutputProtocol,
-) -> ::Result<()> {
+) -> crate::Result<()> {
     if let Err(e) = res {
         let e = match e {
-            ::Error::Application(a) => a,
+            crate::Error::Application(a) => a,
             _ => ApplicationError::new(ApplicationErrorKind::Unknown, format!("{:?}", e)),
         };
 
@@ -114,7 +114,7 @@
         );
 
         o_prot.write_message_begin(&ident)?;
-        ::Error::write_application_error_to_out_protocol(&e, o_prot)?;
+        crate::Error::write_application_error_to_out_protocol(&e, o_prot)?;
         o_prot.write_message_end()?;
         o_prot.flush()
     } else {
diff --git a/lib/rs/src/server/multiplexed.rs b/lib/rs/src/server/multiplexed.rs
index 3f9bc78..3d688fa 100644
--- a/lib/rs/src/server/multiplexed.rs
+++ b/lib/rs/src/server/multiplexed.rs
@@ -21,7 +21,7 @@
 use std::fmt::{Debug, Formatter};
 use std::sync::{Arc, Mutex};
 
-use protocol::{TInputProtocol, TMessageIdentifier, TOutputProtocol, TStoredInputProtocol};
+use crate::protocol::{TInputProtocol, TMessageIdentifier, TOutputProtocol, TStoredInputProtocol};
 
 use super::{handle_process_result, TProcessor};
 
@@ -76,7 +76,7 @@
         service_name: S,
         processor: Box<dyn TProcessor + Send + Sync>,
         as_default: bool,
-    ) -> ::Result<()> {
+    ) -> crate::Result<()> {
         let mut stored = self.stored.lock().unwrap();
 
         let name = service_name.into();
@@ -105,7 +105,7 @@
         msg_ident: &TMessageIdentifier,
         i_prot: &mut dyn TInputProtocol,
         o_prot: &mut dyn TOutputProtocol,
-    ) -> ::Result<()> {
+    ) -> crate::Result<()> {
         let (svc_name, svc_call) = split_ident_name(&msg_ident.name);
         debug!("routing svc_name {:?} svc_call {}", &svc_name, &svc_call);
 
@@ -134,7 +134,7 @@
 }
 
 impl TProcessor for TMultiplexedProcessor {
-    fn process(&self, i_prot: &mut dyn TInputProtocol, o_prot: &mut dyn TOutputProtocol) -> ::Result<()> {
+    fn process(&self, i_prot: &mut dyn TInputProtocol, o_prot: &mut dyn TOutputProtocol) -> crate::Result<()> {
         let msg_ident = i_prot.read_message_begin()?;
 
         debug!("process incoming msg id:{:?}", &msg_ident);
@@ -181,9 +181,9 @@
     use std::sync::atomic::{AtomicBool, Ordering};
     use std::sync::Arc;
 
-    use protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TMessageIdentifier, TMessageType};
-    use transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
-    use {ApplicationError, ApplicationErrorKind};
+    use crate::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TMessageIdentifier, TMessageType};
+    use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
+    use crate::{ApplicationError, ApplicationErrorKind};
 
     use super::*;
 
@@ -220,7 +220,7 @@
         let rcvd_ident = i.read_message_begin().unwrap();
         let expected_ident = TMessageIdentifier::new("foo", TMessageType::Exception, 10);
         assert_eq!(rcvd_ident, expected_ident);
-        let rcvd_err = ::Error::read_application_error_from_in_protocol(&mut i).unwrap();
+        let rcvd_err = crate::Error::read_application_error_from_in_protocol(&mut i).unwrap();
         let expected_err = ApplicationError::new(
             ApplicationErrorKind::Unknown,
             MISSING_SEPARATOR_AND_NO_DEFAULT,
@@ -245,7 +245,7 @@
         let rcvd_ident = i.read_message_begin().unwrap();
         let expected_ident = TMessageIdentifier::new("missing:call", TMessageType::Exception, 10);
         assert_eq!(rcvd_ident, expected_ident);
-        let rcvd_err = ::Error::read_application_error_from_in_protocol(&mut i).unwrap();
+        let rcvd_err = crate::Error::read_application_error_from_in_protocol(&mut i).unwrap();
         let expected_err = ApplicationError::new(
             ApplicationErrorKind::Unknown,
             missing_processor_message(Some("missing")),
@@ -259,7 +259,7 @@
     }
 
     impl TProcessor for Service {
-        fn process(&self, _: &mut dyn TInputProtocol, _: &mut dyn TOutputProtocol) -> ::Result<()> {
+        fn process(&self, _: &mut dyn TInputProtocol, _: &mut dyn TOutputProtocol) -> crate::Result<()> {
             let res = self
                 .invoked
                 .compare_and_swap(false, true, Ordering::Relaxed);
diff --git a/lib/rs/src/server/threaded.rs b/lib/rs/src/server/threaded.rs
index 5e253f7..8373c46 100644
--- a/lib/rs/src/server/threaded.rs
+++ b/lib/rs/src/server/threaded.rs
@@ -19,12 +19,12 @@
 use std::sync::Arc;
 use threadpool::ThreadPool;
 
-use protocol::{TInputProtocol, TInputProtocolFactory, TOutputProtocol, TOutputProtocolFactory};
-use transport::{TIoChannel, TReadTransportFactory, TTcpChannel, TWriteTransportFactory};
-use {ApplicationError, ApplicationErrorKind};
+use crate::protocol::{TInputProtocol, TInputProtocolFactory, TOutputProtocol, TOutputProtocolFactory};
+use crate::transport::{TIoChannel, TReadTransportFactory, TTcpChannel, TWriteTransportFactory};
+use crate::{ApplicationError, ApplicationErrorKind};
 
 use super::TProcessor;
-use TransportErrorKind;
+use crate::TransportErrorKind;
 
 /// Fixed-size thread-pool blocking Thrift server.
 ///
@@ -169,7 +169,7 @@
     ///
     /// Return `Err` when the server cannot bind to `listen_address` or there
     /// is an unrecoverable error.
-    pub fn listen<A: ToSocketAddrs>(&mut self, listen_address: A) -> ::Result<()> {
+    pub fn listen<A: ToSocketAddrs>(&mut self, listen_address: A) -> crate::Result<()> {
         let listener = TcpListener::bind(listen_address)?;
         for stream in listener.incoming() {
             match stream {
@@ -185,7 +185,7 @@
             }
         }
 
-        Err(::Error::Application(ApplicationError {
+        Err(crate::Error::Application(ApplicationError {
             kind: ApplicationErrorKind::Unknown,
             message: "aborted listen loop".into(),
         }))
@@ -194,7 +194,7 @@
     fn new_protocols_for_connection(
         &mut self,
         stream: TcpStream,
-    ) -> ::Result<(Box<dyn TInputProtocol + Send>, Box<dyn TOutputProtocol + Send>)> {
+    ) -> crate::Result<(Box<dyn TInputProtocol + Send>, Box<dyn TOutputProtocol + Send>)> {
         // create the shared tcp stream
         let channel = TTcpChannel::with_stream(stream);
 
@@ -228,7 +228,7 @@
             Ok(()) => {},
             Err(err) => {
                 match err {
-                    ::Error::Transport(ref transport_err) if transport_err.kind == TransportErrorKind::EndOfFile => {},
+                    crate::Error::Transport(ref transport_err) if transport_err.kind == TransportErrorKind::EndOfFile => {},
                     other => warn!("processor completed with error: {:?}", other),
                 }
                 break;
diff --git a/lib/rs/src/transport/buffered.rs b/lib/rs/src/transport/buffered.rs
index b33eb4f..914a19b 100644
--- a/lib/rs/src/transport/buffered.rs
+++ b/lib/rs/src/transport/buffered.rs
@@ -264,7 +264,7 @@
     use std::io::{Read, Write};
 
     use super::*;
-    use transport::TBufferChannel;
+    use crate::transport::TBufferChannel;
 
     #[test]
     fn must_return_zero_if_read_buffer_is_empty() {
diff --git a/lib/rs/src/transport/framed.rs b/lib/rs/src/transport/framed.rs
index 98ad1bb..c30ccd9 100644
--- a/lib/rs/src/transport/framed.rs
+++ b/lib/rs/src/transport/framed.rs
@@ -239,7 +239,7 @@
 #[cfg(test)]
 mod tests {
     use super::*;
-    use transport::mem::TBufferChannel;
+    use crate::transport::mem::TBufferChannel;
 
     // FIXME: test a forced reserve
 
diff --git a/lib/rs/src/transport/mem.rs b/lib/rs/src/transport/mem.rs
index 9874257..68fb265 100644
--- a/lib/rs/src/transport/mem.rs
+++ b/lib/rs/src/transport/mem.rs
@@ -139,7 +139,7 @@
 }
 
 impl TIoChannel for TBufferChannel {
-    fn split(self) -> ::Result<(ReadHalf<Self>, WriteHalf<Self>)>
+    fn split(self) -> crate::Result<(ReadHalf<Self>, WriteHalf<Self>)>
     where
         Self: Sized,
     {
diff --git a/lib/rs/src/transport/mod.rs b/lib/rs/src/transport/mod.rs
index 32c0799..d02a87c 100644
--- a/lib/rs/src/transport/mod.rs
+++ b/lib/rs/src/transport/mod.rs
@@ -111,7 +111,7 @@
     /// Returned halves may share the underlying OS channel or buffer resources.
     /// Implementations **should ensure** that these two halves can be safely
     /// used independently by concurrent threads.
-    fn split(self) -> ::Result<(::transport::ReadHalf<Self>, ::transport::WriteHalf<Self>)>
+    fn split(self) -> crate::Result<(crate::transport::ReadHalf<Self>, crate::transport::WriteHalf<Self>)>
     where
         Self: Sized;
 }
diff --git a/lib/rs/src/transport/socket.rs b/lib/rs/src/transport/socket.rs
index a2e567e..275bcd4 100644
--- a/lib/rs/src/transport/socket.rs
+++ b/lib/rs/src/transport/socket.rs
@@ -21,7 +21,7 @@
 use std::net::{Shutdown, TcpStream, ToSocketAddrs};
 
 use super::{ReadHalf, TIoChannel, WriteHalf};
-use {new_transport_error, TransportErrorKind};
+use crate::{new_transport_error, TransportErrorKind};
 
 /// Bidirectional TCP/IP channel.
 ///
@@ -82,7 +82,7 @@
     }
 
     /// Connect to `remote_address`, which should implement `ToSocketAddrs` trait.
-    pub fn open<A: ToSocketAddrs>(&mut self, remote_address: A) -> ::Result<()> {
+    pub fn open<A: ToSocketAddrs>(&mut self, remote_address: A) -> crate::Result<()> {
         if self.stream.is_some() {
             Err(new_transport_error(
                 TransportErrorKind::AlreadyOpen,
@@ -103,7 +103,7 @@
     ///
     /// Both send and receive halves are closed, and this instance can no
     /// longer be used to communicate with another endpoint.
-    pub fn close(&mut self) -> ::Result<()> {
+    pub fn close(&mut self) -> crate::Result<()> {
         self.if_set(|s| s.shutdown(Shutdown::Both))
             .map_err(From::from)
     }
@@ -124,7 +124,7 @@
 }
 
 impl TIoChannel for TTcpChannel {
-    fn split(self) -> ::Result<(ReadHalf<Self>, WriteHalf<Self>)>
+    fn split(self) -> crate::Result<(ReadHalf<Self>, WriteHalf<Self>)>
     where
         Self: Sized,
     {
diff --git a/lib/rs/test/Cargo.toml b/lib/rs/test/Cargo.toml
index dc4ffe3..decc985 100644
--- a/lib/rs/test/Cargo.toml
+++ b/lib/rs/test/Cargo.toml
@@ -1,6 +1,7 @@
 [package]
 name = "kitchen-sink"
 version = "0.1.0"
+edition = "2018"
 license = "Apache-2.0"
 authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
 publish = false
diff --git a/lib/rs/test/Makefile.am b/lib/rs/test/Makefile.am
index 486188c..5dc4f56 100644
--- a/lib/rs/test/Makefile.am
+++ b/lib/rs/test/Makefile.am
@@ -41,6 +41,8 @@
 	-$(RM) src/base_two.rs
 	-$(RM) src/midlayer.rs
 	-$(RM) src/ultimate.rs
+	-$(RM) src/recursive.rs
+	-$(RM) src/identifiers.rs
 	-$(RM) -r bin
 
 EXTRA_DIST = \
diff --git a/lib/rs/test/src/bin/kitchen_sink_client.rs b/lib/rs/test/src/bin/kitchen_sink_client.rs
index d295c88..a777920 100644
--- a/lib/rs/test/src/bin/kitchen_sink_client.rs
+++ b/lib/rs/test/src/bin/kitchen_sink_client.rs
@@ -69,7 +69,7 @@
         TFramedWriteTransport::new(o_chan),
     );
 
-    let (i_prot, o_prot): (Box<TInputProtocol>, Box<TOutputProtocol>) = match protocol {
+    let (i_prot, o_prot): (Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>) = match protocol {
         "binary" => (
             Box::new(TBinaryInputProtocol::new(i_tran, true)),
             Box::new(TBinaryOutputProtocol::new(o_tran, true)),
@@ -86,8 +86,8 @@
 
 fn run_client(
     service: &str,
-    i_prot: Box<TInputProtocol>,
-    o_prot: Box<TOutputProtocol>,
+    i_prot: Box<dyn TInputProtocol>,
+    o_prot: Box<dyn TOutputProtocol>,
 ) -> thrift::Result<()> {
     match service {
         "full" => exec_full_meal_client(i_prot, o_prot),
@@ -110,8 +110,8 @@
 }
 
 fn exec_meal_client(
-    i_prot: Box<TInputProtocol>,
-    o_prot: Box<TOutputProtocol>,
+    i_prot: Box<dyn TInputProtocol>,
+    o_prot: Box<dyn TOutputProtocol>,
 ) -> thrift::Result<()> {
     let mut client = MealServiceSyncClient::new(i_prot, o_prot);
 
@@ -127,8 +127,8 @@
 }
 
 fn exec_full_meal_client(
-    i_prot: Box<TInputProtocol>,
-    o_prot: Box<TOutputProtocol>,
+    i_prot: Box<dyn TInputProtocol>,
+    o_prot: Box<dyn TOutputProtocol>,
 ) -> thrift::Result<()> {
     let mut client = FullMealServiceSyncClient::new(i_prot, o_prot);
 
@@ -141,8 +141,8 @@
 }
 
 fn exec_recursive_client(
-    i_prot: Box<TInputProtocol>,
-    o_prot: Box<TOutputProtocol>,
+    i_prot: Box<dyn TInputProtocol>,
+    o_prot: Box<dyn TOutputProtocol>,
 ) -> thrift::Result<()> {
     let mut client = recursive::TestServiceSyncClient::new(i_prot, o_prot);
 
diff --git a/lib/rs/test/src/bin/kitchen_sink_server.rs b/lib/rs/test/src/bin/kitchen_sink_server.rs
index 73801ea..c53e887 100644
--- a/lib/rs/test/src/bin/kitchen_sink_server.rs
+++ b/lib/rs/test/src/bin/kitchen_sink_server.rs
@@ -76,8 +76,8 @@
     let w_transport_factory = TFramedWriteTransportFactory::new();
 
     let (i_protocol_factory, o_protocol_factory): (
-        Box<TInputProtocolFactory>,
-        Box<TOutputProtocolFactory>,
+        Box<dyn TInputProtocolFactory>,
+        Box<dyn TOutputProtocolFactory>,
     ) = match &*protocol {
         "binary" => (
             Box::new(TBinaryInputProtocolFactory::new()),
diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json
index 5b78803..ff227c4 100644
--- a/test/known_failures_Linux.json
+++ b/test/known_failures_Linux.json
@@ -1,8 +1,4 @@
 [
-  "c_glib-rs_multi_buffered-ip",
-  "c_glib-rs_multi_framed-ip",
-  "c_glib-rs_multic_buffered-ip",
-  "c_glib-rs_multic_framed-ip",
   "cl-c_glib_binary_buffered-ip",
   "cl-c_glib_binary_framed-ip",
   "cl-c_glib_multi-binary_buffered-ip",
@@ -11,6 +7,8 @@
   "cl-c_glib_multi_framed-ip",
   "cl-go_binary_buffered-ip",
   "cl-go_binary_framed-ip",
+  "cl-netstd_binary_buffered-ip",
+  "cl-netstd_binary_framed-ip",
   "cl-rb_binary-accel_buffered-ip",
   "cl-rb_binary-accel_framed-ip",
   "cl-rb_binary_buffered-ip",
@@ -36,9 +34,6 @@
   "cpp-cpp_multi-binary_websocket-domain",
   "cpp-cpp_multi-binary_websocket-ip",
   "cpp-cpp_multi-binary_websocket-ip-ssl",
-  "cpp-cpp_multi_websocket-domain",
-  "cpp-cpp_multi_websocket-ip",
-  "cpp-cpp_multi_websocket-ip-ssl",
   "cpp-cpp_multic-compact_websocket-domain",
   "cpp-cpp_multic-compact_websocket-ip",
   "cpp-cpp_multic-compact_websocket-ip-ssl",
@@ -57,6 +52,9 @@
   "cpp-cpp_multij_websocket-domain",
   "cpp-cpp_multij_websocket-ip",
   "cpp-cpp_multij_websocket-ip-ssl",
+  "cpp-cpp_multi_websocket-domain",
+  "cpp-cpp_multi_websocket-ip",
+  "cpp-cpp_multi_websocket-ip-ssl",
   "cpp-dart_binary_http-ip",
   "cpp-dart_compact_http-ip",
   "cpp-dart_json_http-ip",
@@ -87,8 +85,6 @@
   "cpp-java_json_http-ip-ssl",
   "cpp-java_multi-binary_http-ip",
   "cpp-java_multi-binary_http-ip-ssl",
-  "cpp-java_multi_http-ip",
-  "cpp-java_multi_http-ip-ssl",
   "cpp-java_multic-compact_http-ip",
   "cpp-java_multic-compact_http-ip-ssl",
   "cpp-java_multic_http-ip",
@@ -97,10 +93,28 @@
   "cpp-java_multij-json_http-ip-ssl",
   "cpp-java_multij_http-ip",
   "cpp-java_multij_http-ip-ssl",
+  "cpp-java_multi_http-ip",
+  "cpp-java_multi_http-ip-ssl",
+  "cpp-netstd_binary_buffered-ip",
+  "cpp-netstd_binary_buffered-ip-ssl",
+  "cpp-netstd_binary_framed-ip",
+  "cpp-netstd_binary_framed-ip-ssl",
+  "cpp-netstd_compact_buffered-ip",
+  "cpp-netstd_compact_buffered-ip-ssl",
+  "cpp-netstd_compact_framed-ip",
+  "cpp-netstd_compact_framed-ip-ssl",
   "cpp-netstd_json_buffered-ip",
   "cpp-netstd_json_buffered-ip-ssl",
   "cpp-netstd_json_framed-ip",
   "cpp-netstd_json_framed-ip-ssl",
+  "cpp-netstd_multi-binary_buffered-ip",
+  "cpp-netstd_multi-binary_buffered-ip-ssl",
+  "cpp-netstd_multi-binary_framed-ip",
+  "cpp-netstd_multi-binary_framed-ip-ssl",
+  "cpp-netstd_multic-compact_buffered-ip",
+  "cpp-netstd_multic-compact_buffered-ip-ssl",
+  "cpp-netstd_multic-compact_framed-ip",
+  "cpp-netstd_multic-compact_framed-ip-ssl",
   "cpp-netstd_multij-json_buffered-ip",
   "cpp-netstd_multij-json_buffered-ip-ssl",
   "cpp-netstd_multij-json_framed-ip",
@@ -176,9 +190,6 @@
   "cpp-py3_multi-multia_http-domain",
   "cpp-py3_multi-multia_http-ip",
   "cpp-py3_multi-multia_http-ip-ssl",
-  "cpp-py3_multi_http-domain",
-  "cpp-py3_multi_http-ip",
-  "cpp-py3_multi_http-ip-ssl",
   "cpp-py3_multic-accelc_http-domain",
   "cpp-py3_multic-accelc_http-ip",
   "cpp-py3_multic-accelc_http-ip-ssl",
@@ -203,6 +214,9 @@
   "cpp-py3_multij_http-domain",
   "cpp-py3_multij_http-ip",
   "cpp-py3_multij_http-ip-ssl",
+  "cpp-py3_multi_http-domain",
+  "cpp-py3_multi_http-ip",
+  "cpp-py3_multi_http-ip-ssl",
   "cpp-py_binary-accel_http-domain",
   "cpp-py_binary-accel_http-ip",
   "cpp-py_binary-accel_http-ip-ssl",
@@ -230,9 +244,6 @@
   "cpp-py_multi-multia_http-domain",
   "cpp-py_multi-multia_http-ip",
   "cpp-py_multi-multia_http-ip-ssl",
-  "cpp-py_multi_http-domain",
-  "cpp-py_multi_http-ip",
-  "cpp-py_multi_http-ip-ssl",
   "cpp-py_multic-accelc_http-domain",
   "cpp-py_multic-accelc_http-ip",
   "cpp-py_multic-accelc_http-ip-ssl",
@@ -257,22 +268,25 @@
   "cpp-py_multij_http-domain",
   "cpp-py_multij_http-ip",
   "cpp-py_multij_http-ip-ssl",
-  "cpp-rs_multi_buffered-ip",
-  "cpp-rs_multi_framed-ip",
+  "cpp-py_multi_http-domain",
+  "cpp-py_multi_http-ip",
+  "cpp-py_multi_http-ip-ssl",
   "cpp-rs_multic_buffered-ip",
   "cpp-rs_multic_framed-ip",
-  "netstd-erl_binary_buffered-ip-ssl",
-  "netstd-erl_binary_framed-ip-ssl",
-  "netstd-erl_compact_buffered-ip-ssl",
-  "netstd-erl_compact_framed-ip-ssl",
-  "netstd-rb_binary-accel_buffered-ip-ssl",
-  "netstd-rb_binary-accel_framed-ip-ssl",
-  "netstd-rb_binary_buffered-ip-ssl",
-  "netstd-rb_binary_framed-ip-ssl",
-  "netstd-rb_compact_buffered-ip-ssl",
-  "netstd-rb_compact_framed-ip-ssl",
-  "netstd-rb_json_buffered-ip-ssl",
-  "netstd-rb_json_framed-ip-ssl",
+  "cpp-rs_multi_buffered-ip",
+  "cpp-rs_multi_framed-ip",
+  "c_glib-netstd_binary_buffered-ip",
+  "c_glib-netstd_binary_framed-ip",
+  "c_glib-netstd_compact_buffered-ip",
+  "c_glib-netstd_compact_framed-ip",
+  "c_glib-netstd_multi-binary_buffered-ip",
+  "c_glib-netstd_multi-binary_framed-ip",
+  "c_glib-netstd_multic-compact_buffered-ip",
+  "c_glib-netstd_multic-compact_framed-ip",
+  "c_glib-rs_multic_buffered-ip",
+  "c_glib-rs_multic_framed-ip",
+  "c_glib-rs_multi_buffered-ip",
+  "c_glib-rs_multi_framed-ip",
   "d-cl_binary_buffered-ip",
   "d-cl_binary_framed-ip",
   "d-cpp_binary_buffered-ip",
@@ -299,12 +313,12 @@
   "d-cpp_json_http-ip-ssl",
   "d-cpp_json_zlib-ip",
   "d-cpp_json_zlib-ip-ssl",
-  "d-d_binary_http-ip",
-  "d-d_compact_http-ip",
-  "d-d_json_http-ip",
   "d-dart_binary_http-ip",
   "d-dart_compact_http-ip",
   "d-dart_json_http-ip",
+  "d-d_binary_http-ip",
+  "d-d_compact_http-ip",
+  "d-d_json_http-ip",
   "d-go_binary_http-ip",
   "d-go_binary_http-ip-ssl",
   "d-go_compact_http-ip",
@@ -318,6 +332,18 @@
   "d-java_json_http-ip",
   "d-java_json_http-ip-ssl",
   "d-js_json_http-ip",
+  "d-netstd_binary_buffered-ip",
+  "d-netstd_binary_buffered-ip-ssl",
+  "d-netstd_binary_framed-ip",
+  "d-netstd_binary_framed-ip-ssl",
+  "d-netstd_compact_buffered-ip",
+  "d-netstd_compact_buffered-ip-ssl",
+  "d-netstd_compact_framed-ip",
+  "d-netstd_compact_framed-ip-ssl",
+  "d-netstd_json_buffered-ip",
+  "d-netstd_json_buffered-ip-ssl",
+  "d-netstd_json_framed-ip",
+  "d-netstd_json_framed-ip-ssl",
   "d-nodejs_binary_buffered-ip",
   "d-nodejs_binary_buffered-ip-ssl",
   "d-nodejs_binary_framed-ip",
@@ -421,9 +447,11 @@
   "erl-cpp_compact_buffered-ip",
   "erl-netstd_binary_buffered-ip",
   "erl-netstd_binary_buffered-ip-ssl",
+  "erl-netstd_binary_framed-ip",
   "erl-netstd_binary_framed-ip-ssl",
   "erl-netstd_compact_buffered-ip",
   "erl-netstd_compact_buffered-ip-ssl",
+  "erl-netstd_compact_framed-ip",
   "erl-netstd_compact_framed-ip-ssl",
   "erl-nodejs_binary_buffered-ip",
   "erl-nodejs_compact_buffered-ip",
@@ -448,21 +476,33 @@
   "go-cpp_header_http-ip-ssl",
   "go-cpp_json_http-ip",
   "go-cpp_json_http-ip-ssl",
+  "go-dart_binary_http-ip",
+  "go-dart_compact_http-ip",
+  "go-dart_json_http-ip",
   "go-d_binary_http-ip",
   "go-d_binary_http-ip-ssl",
   "go-d_compact_http-ip",
   "go-d_compact_http-ip-ssl",
   "go-d_json_http-ip",
   "go-d_json_http-ip-ssl",
-  "go-dart_binary_http-ip",
-  "go-dart_compact_http-ip",
-  "go-dart_json_http-ip",
   "go-java_binary_http-ip",
   "go-java_binary_http-ip-ssl",
   "go-java_compact_http-ip",
   "go-java_compact_http-ip-ssl",
   "go-java_json_http-ip",
   "go-java_json_http-ip-ssl",
+  "go-netstd_binary_buffered-ip",
+  "go-netstd_binary_buffered-ip-ssl",
+  "go-netstd_binary_framed-ip",
+  "go-netstd_binary_framed-ip-ssl",
+  "go-netstd_compact_buffered-ip",
+  "go-netstd_compact_buffered-ip-ssl",
+  "go-netstd_compact_framed-ip",
+  "go-netstd_compact_framed-ip-ssl",
+  "go-netstd_json_buffered-ip",
+  "go-netstd_json_buffered-ip-ssl",
+  "go-netstd_json_framed-ip",
+  "go-netstd_json_framed-ip-ssl",
   "go-py3_binary-accel_zlib-ip-ssl",
   "go-py3_compact-accelc_zlib-ip-ssl",
   "go-py_binary-accel_zlib-ip-ssl",
@@ -477,11 +517,29 @@
   "hs-php_binary-accel_framed-ip",
   "hs-php_json_buffered-ip",
   "hs-php_json_framed-ip",
+  "java-erl-binary_buffered-ip-ssl",
+  "java-erl-binary_fastframed-framed-ip-ssl",
+  "java-erl-binary_framed-ip-ssl",
+  "java-erl-compact_buffered-ip-ssl",
+  "java-erl-compact_fastframed-framed-ip-ssl",
+  "java-erl-compact_framed-ip-ssl",
+  "java-erl-multi-binary_buffered-ip-ssl",
+  "java-erl-multi-binary_fastframed-framed-ip-ssl",
+  "java-erl-multi-binary_framed-ip-ssl",
+  "java-erl-multic-compact_buffered-ip-ssl",
+  "java-erl-multic-compact_fastframed-framed-ip-ssl",
+  "java-erl-multic-compact_framed-ip-ssl",
+  "java-netstd_binary_buffered-ip",
   "java-netstd_binary_buffered-ip-ssl",
+  "java-netstd_binary_fastframed-framed-ip",
   "java-netstd_binary_fastframed-framed-ip-ssl",
+  "java-netstd_binary_framed-ip",
   "java-netstd_binary_framed-ip-ssl",
+  "java-netstd_compact_buffered-ip",
   "java-netstd_compact_buffered-ip-ssl",
+  "java-netstd_compact_fastframed-framed-ip",
   "java-netstd_compact_fastframed-framed-ip-ssl",
+  "java-netstd_compact_framed-ip",
   "java-netstd_compact_framed-ip-ssl",
   "java-netstd_json_buffered-ip",
   "java-netstd_json_buffered-ip-ssl",
@@ -489,11 +547,17 @@
   "java-netstd_json_fastframed-framed-ip-ssl",
   "java-netstd_json_framed-ip",
   "java-netstd_json_framed-ip-ssl",
+  "java-netstd_multi-binary_buffered-ip",
   "java-netstd_multi-binary_buffered-ip-ssl",
+  "java-netstd_multi-binary_fastframed-framed-ip",
   "java-netstd_multi-binary_fastframed-framed-ip-ssl",
+  "java-netstd_multi-binary_framed-ip",
   "java-netstd_multi-binary_framed-ip-ssl",
+  "java-netstd_multic-compact_buffered-ip",
   "java-netstd_multic-compact_buffered-ip-ssl",
+  "java-netstd_multic-compact_fastframed-framed-ip",
   "java-netstd_multic-compact_fastframed-framed-ip-ssl",
+  "java-netstd_multic-compact_framed-ip",
   "java-netstd_multic-compact_framed-ip-ssl",
   "java-netstd_multij-json_buffered-ip",
   "java-netstd_multij-json_buffered-ip-ssl",
@@ -513,38 +577,193 @@
   "java-php_multij-json_buffered-ip",
   "java-php_multij-json_fastframed-framed-ip",
   "java-php_multij-json_framed-ip",
+  "netstd-cl_binary_buffered-ip",
+  "netstd-cl_binary_framed-ip",
+  "netstd-cpp_binary_buffered-ip",
+  "netstd-cpp_binary_buffered-ip-ssl",
+  "netstd-cpp_binary_framed-ip",
+  "netstd-cpp_binary_framed-ip-ssl",
+  "netstd-cpp_compact_buffered-ip",
+  "netstd-cpp_compact_buffered-ip-ssl",
+  "netstd-cpp_compact_framed-ip",
+  "netstd-cpp_compact_framed-ip-ssl",
+  "netstd-cpp_json_buffered-ip",
+  "netstd-cpp_json_buffered-ip-ssl",
+  "netstd-cpp_json_framed-ip",
+  "netstd-cpp_json_framed-ip-ssl",
+  "netstd-c_glib_binary_buffered-ip",
+  "netstd-c_glib_binary_buffered-ip-ssl",
+  "netstd-c_glib_binary_framed-ip",
+  "netstd-c_glib_binary_framed-ip-ssl",
+  "netstd-c_glib_compact_buffered-ip",
+  "netstd-c_glib_compact_buffered-ip-ssl",
+  "netstd-c_glib_compact_framed-ip",
+  "netstd-c_glib_compact_framed-ip-ssl",
+  "netstd-dart_binary_buffered-ip",
+  "netstd-dart_binary_framed-ip",
+  "netstd-dart_compact_buffered-ip",
+  "netstd-dart_compact_framed-ip",
+  "netstd-dart_json_buffered-ip",
+  "netstd-dart_json_framed-ip",
+  "netstd-d_binary_buffered-ip",
+  "netstd-d_binary_buffered-ip-ssl",
+  "netstd-d_binary_framed-ip",
+  "netstd-d_binary_framed-ip-ssl",
+  "netstd-d_compact_buffered-ip",
+  "netstd-d_compact_buffered-ip-ssl",
+  "netstd-d_compact_framed-ip",
+  "netstd-d_compact_framed-ip-ssl",
+  "netstd-d_json_buffered-ip",
+  "netstd-d_json_buffered-ip-ssl",
+  "netstd-d_json_framed-ip",
+  "netstd-d_json_framed-ip-ssl",
+  "netstd-erl_binary_buffered-ip",
+  "netstd-erl_binary_buffered-ip-ssl",
+  "netstd-erl_binary_framed-ip",
+  "netstd-erl_binary_framed-ip-ssl",
+  "netstd-erl_compact_buffered-ip",
+  "netstd-erl_compact_buffered-ip-ssl",
+  "netstd-erl_compact_framed-ip",
+  "netstd-erl_compact_framed-ip-ssl",
+  "netstd-go_binary_buffered-ip",
+  "netstd-go_binary_buffered-ip-ssl",
+  "netstd-go_binary_framed-ip",
+  "netstd-go_binary_framed-ip-ssl",
+  "netstd-go_compact_buffered-ip",
+  "netstd-go_compact_buffered-ip-ssl",
+  "netstd-go_compact_framed-ip",
+  "netstd-go_compact_framed-ip-ssl",
+  "netstd-go_json_buffered-ip",
+  "netstd-go_json_buffered-ip-ssl",
+  "netstd-go_json_framed-ip",
+  "netstd-go_json_framed-ip-ssl",
+  "netstd-hs_binary_buffered-ip",
+  "netstd-hs_binary_framed-ip",
+  "netstd-hs_compact_buffered-ip",
+  "netstd-hs_compact_framed-ip",
+  "netstd-hs_json_buffered-ip",
+  "netstd-hs_json_framed-ip",
+  "netstd-java_binary_buffered-ip",
+  "netstd-java_binary_buffered-ip-ssl",
+  "netstd-java_binary_framed-fastframed-ip",
+  "netstd-java_binary_framed-fastframed-ip-ssl",
+  "netstd-java_binary_framed-ip",
+  "netstd-java_binary_framed-ip-ssl",
+  "netstd-java_compact_buffered-ip",
+  "netstd-java_compact_buffered-ip-ssl",
+  "netstd-java_compact_framed-fastframed-ip",
+  "netstd-java_compact_framed-fastframed-ip-ssl",
+  "netstd-java_compact_framed-ip",
+  "netstd-java_compact_framed-ip-ssl",
+  "netstd-java_json_buffered-ip",
+  "netstd-java_json_buffered-ip-ssl",
+  "netstd-java_json_framed-fastframed-ip",
+  "netstd-java_json_framed-fastframed-ip-ssl",
+  "netstd-java_json_framed-ip",
+  "netstd-java_json_framed-ip-ssl",
+  "netstd-lua_binary_buffered-ip",
+  "netstd-lua_binary_framed-ip",
+  "netstd-lua_compact_buffered-ip",
+  "netstd-lua_compact_framed-ip",
+  "netstd-lua_json_buffered-ip",
+  "netstd-lua_json_framed-ip",
+  "netstd-netstd_binary_buffered-ip",
   "netstd-netstd_binary_buffered-ip-ssl",
+  "netstd-netstd_binary_framed-ip",
   "netstd-netstd_binary_framed-ip-ssl",
+  "netstd-netstd_compact_buffered-ip",
   "netstd-netstd_compact_buffered-ip-ssl",
+  "netstd-netstd_compact_framed-ip",
   "netstd-netstd_compact_framed-ip-ssl",
   "netstd-netstd_json_buffered-ip",
   "netstd-netstd_json_buffered-ip-ssl",
   "netstd-netstd_json_framed-ip",
   "netstd-netstd_json_framed-ip-ssl",
+  "netstd-nodejs_binary_buffered-ip",
+  "netstd-nodejs_binary_buffered-ip-ssl",
+  "netstd-nodejs_binary_framed-ip",
+  "netstd-nodejs_binary_framed-ip-ssl",
+  "netstd-nodejs_compact_buffered-ip",
+  "netstd-nodejs_compact_buffered-ip-ssl",
+  "netstd-nodejs_compact_framed-ip",
+  "netstd-nodejs_compact_framed-ip-ssl",
+  "netstd-nodejs_json_buffered-ip",
+  "netstd-nodejs_json_buffered-ip-ssl",
+  "netstd-nodejs_json_framed-ip",
+  "netstd-nodejs_json_framed-ip-ssl",
+  "netstd-nodets_binary_buffered-ip",
+  "netstd-perl_binary_buffered-ip",
+  "netstd-perl_binary_buffered-ip-ssl",
+  "netstd-perl_binary_framed-ip",
+  "netstd-perl_binary_framed-ip-ssl",
   "netstd-php_binary-accel_buffered-ip",
   "netstd-php_binary-accel_framed-ip",
+  "netstd-php_binary_buffered-ip",
+  "netstd-php_binary_framed-ip",
+  "netstd-php_compact_buffered-ip",
+  "netstd-php_compact_framed-ip",
   "netstd-php_json_buffered-ip",
   "netstd-php_json_framed-ip",
+  "netstd-py3_binary-accel_buffered-ip",
+  "netstd-py3_binary-accel_buffered-ip-ssl",
   "netstd-py3_binary-accel_framed-ip",
   "netstd-py3_binary-accel_framed-ip-ssl",
+  "netstd-py3_binary_buffered-ip",
+  "netstd-py3_binary_buffered-ip-ssl",
   "netstd-py3_binary_framed-ip",
   "netstd-py3_binary_framed-ip-ssl",
+  "netstd-py3_compact-accelc_buffered-ip",
+  "netstd-py3_compact-accelc_buffered-ip-ssl",
   "netstd-py3_compact-accelc_framed-ip",
   "netstd-py3_compact-accelc_framed-ip-ssl",
+  "netstd-py3_compact_buffered-ip",
+  "netstd-py3_compact_buffered-ip-ssl",
   "netstd-py3_compact_framed-ip",
   "netstd-py3_compact_framed-ip-ssl",
+  "netstd-py3_json_buffered-ip",
+  "netstd-py3_json_buffered-ip-ssl",
   "netstd-py3_json_framed-ip",
   "netstd-py3_json_framed-ip-ssl",
+  "netstd-py_binary-accel_buffered-ip",
+  "netstd-py_binary-accel_buffered-ip-ssl",
   "netstd-py_binary-accel_framed-ip",
   "netstd-py_binary-accel_framed-ip-ssl",
+  "netstd-py_binary_buffered-ip",
+  "netstd-py_binary_buffered-ip-ssl",
   "netstd-py_binary_framed-ip",
   "netstd-py_binary_framed-ip-ssl",
+  "netstd-py_compact-accelc_buffered-ip",
+  "netstd-py_compact-accelc_buffered-ip-ssl",
   "netstd-py_compact-accelc_framed-ip",
   "netstd-py_compact-accelc_framed-ip-ssl",
+  "netstd-py_compact_buffered-ip",
+  "netstd-py_compact_buffered-ip-ssl",
   "netstd-py_compact_framed-ip",
   "netstd-py_compact_framed-ip-ssl",
+  "netstd-py_json_buffered-ip",
+  "netstd-py_json_buffered-ip-ssl",
   "netstd-py_json_framed-ip",
   "netstd-py_json_framed-ip-ssl",
+  "netstd-rb_binary-accel_buffered-ip",
+  "netstd-rb_binary-accel_buffered-ip-ssl",
+  "netstd-rb_binary-accel_framed-ip",
+  "netstd-rb_binary-accel_framed-ip-ssl",
+  "netstd-rb_binary_buffered-ip",
+  "netstd-rb_binary_buffered-ip-ssl",
+  "netstd-rb_binary_framed-ip",
+  "netstd-rb_binary_framed-ip-ssl",
+  "netstd-rb_compact_buffered-ip",
+  "netstd-rb_compact_buffered-ip-ssl",
+  "netstd-rb_compact_framed-ip",
+  "netstd-rb_compact_framed-ip-ssl",
+  "netstd-rb_json_buffered-ip",
+  "netstd-rb_json_buffered-ip-ssl",
+  "netstd-rb_json_framed-ip",
+  "netstd-rb_json_framed-ip-ssl",
+  "netstd-rs_binary_buffered-ip",
+  "netstd-rs_binary_framed-ip",
+  "netstd-rs_compact_buffered-ip",
+  "netstd-rs_compact_framed-ip",
   "nodejs-cpp_binary_http-domain",
   "nodejs-cpp_binary_http-ip",
   "nodejs-cpp_binary_http-ip-ssl",
@@ -570,15 +789,15 @@
   "nodejs-cpp_json_websocket-domain",
   "nodejs-cpp_json_websocket-ip",
   "nodejs-cpp_json_websocket-ip-ssl",
+  "nodejs-dart_binary_http-ip",
+  "nodejs-dart_compact_http-ip",
+  "nodejs-dart_json_http-ip",
   "nodejs-d_binary_http-ip",
   "nodejs-d_binary_http-ip-ssl",
   "nodejs-d_compact_http-ip",
   "nodejs-d_compact_http-ip-ssl",
   "nodejs-d_json_http-ip",
   "nodejs-d_json_http-ip-ssl",
-  "nodejs-dart_binary_http-ip",
-  "nodejs-dart_compact_http-ip",
-  "nodejs-dart_json_http-ip",
   "nodejs-go_binary_http-ip",
   "nodejs-go_binary_http-ip-ssl",
   "nodejs-go_compact_http-ip",
@@ -601,9 +820,13 @@
   "nodejs-lua_binary_http-ip",
   "nodejs-lua_compact_http-ip",
   "nodejs-lua_json_http-ip",
+  "nodejs-netstd_binary_buffered-ip",
   "nodejs-netstd_binary_buffered-ip-ssl",
+  "nodejs-netstd_binary_framed-ip",
   "nodejs-netstd_binary_framed-ip-ssl",
+  "nodejs-netstd_compact_buffered-ip",
   "nodejs-netstd_compact_buffered-ip-ssl",
+  "nodejs-netstd_compact_framed-ip",
   "nodejs-netstd_compact_framed-ip-ssl",
   "nodejs-netstd_json_buffered-ip",
   "nodejs-netstd_json_buffered-ip-ssl",
@@ -653,7 +876,16 @@
   "nodejs-py_json_http-domain",
   "nodejs-py_json_http-ip",
   "nodejs-py_json_http-ip-ssl",
+  "nodets-netstd_binary_buffered-ip",
   "nodets-php_binary-accel_buffered-ip",
+  "perl-netstd_binary_buffered-ip",
+  "perl-netstd_binary_buffered-ip-ssl",
+  "perl-netstd_binary_framed-ip",
+  "perl-netstd_binary_framed-ip-ssl",
+  "perl-netstd_multi-binary_buffered-ip",
+  "perl-netstd_multi-binary_buffered-ip-ssl",
+  "perl-netstd_multi-binary_framed-ip",
+  "perl-netstd_multi-binary_framed-ip-ssl",
   "perl-rs_multi_buffered-ip",
   "perl-rs_multi_framed-ip",
   "py-cpp_accel-binary_http-domain",
@@ -683,9 +915,6 @@
   "py-cpp_multi-binary_http-domain",
   "py-cpp_multi-binary_http-ip",
   "py-cpp_multi-binary_http-ip-ssl",
-  "py-cpp_multi_http-domain",
-  "py-cpp_multi_http-ip",
-  "py-cpp_multi_http-ip-ssl",
   "py-cpp_multia-binary_http-domain",
   "py-cpp_multia-binary_http-ip",
   "py-cpp_multia-binary_http-ip-ssl",
@@ -716,18 +945,26 @@
   "py-cpp_multic_http-domain",
   "py-cpp_multic_http-ip",
   "py-cpp_multic_http-ip-ssl",
-  "py-cpp_multih_http-domain",
   "py-cpp_multih-header_http-domain",
   "py-cpp_multih-header_http-ip",
   "py-cpp_multih-header_http-ip-ssl",
-  "py-cpp_multij_http-domain",
+  "py-cpp_multih_http-domain",
   "py-cpp_multih_http-ip",
   "py-cpp_multih_http-ip-ssl",
   "py-cpp_multij-json_http-domain",
   "py-cpp_multij-json_http-ip",
   "py-cpp_multij-json_http-ip-ssl",
+  "py-cpp_multij_http-domain",
   "py-cpp_multij_http-ip",
   "py-cpp_multij_http-ip-ssl",
+  "py-cpp_multi_http-domain",
+  "py-cpp_multi_http-ip",
+  "py-cpp_multi_http-ip-ssl",
+  "py-dart_accel-binary_http-ip",
+  "py-dart_accelc-compact_http-ip",
+  "py-dart_binary_http-ip",
+  "py-dart_compact_http-ip",
+  "py-dart_json_http-ip",
   "py-d_accel-binary_http-ip",
   "py-d_accel-binary_http-ip-ssl",
   "py-d_accelc-compact_http-ip",
@@ -738,11 +975,6 @@
   "py-d_compact_http-ip-ssl",
   "py-d_json_http-ip",
   "py-d_json_http-ip-ssl",
-  "py-dart_accel-binary_http-ip",
-  "py-dart_accelc-compact_http-ip",
-  "py-dart_binary_http-ip",
-  "py-dart_compact_http-ip",
-  "py-dart_json_http-ip",
   "py-hs_accel-binary_http-ip",
   "py-hs_accelc-compact_http-ip",
   "py-hs_binary_http-ip",
@@ -755,7 +987,6 @@
   "py-java_compact_http-ip-ssl",
   "py-java_json_http-ip-ssl",
   "py-java_multi-binary_http-ip-ssl",
-  "py-java_multi_http-ip-ssl",
   "py-java_multia-binary_http-ip-ssl",
   "py-java_multia-multi_http-ip-ssl",
   "py-java_multiac-compact_http-ip-ssl",
@@ -764,17 +995,27 @@
   "py-java_multic_http-ip-ssl",
   "py-java_multij-json_http-ip-ssl",
   "py-java_multij_http-ip-ssl",
+  "py-java_multi_http-ip-ssl",
   "py-lua_accel-binary_http-ip",
   "py-lua_accelc-compact_http-ip",
   "py-lua_binary_http-ip",
   "py-lua_compact_http-ip",
   "py-lua_json_http-ip",
+  "py-netstd_accel-binary_buffered-ip",
+  "py-netstd_accel-binary_buffered-ip-ssl",
+  "py-netstd_accel-binary_framed-ip",
   "py-netstd_accel-binary_framed-ip-ssl",
+  "py-netstd_accelc-compact_buffered-ip",
   "py-netstd_accelc-compact_buffered-ip-ssl",
+  "py-netstd_accelc-compact_framed-ip",
   "py-netstd_accelc-compact_framed-ip-ssl",
+  "py-netstd_binary_buffered-ip",
   "py-netstd_binary_buffered-ip-ssl",
+  "py-netstd_binary_framed-ip",
   "py-netstd_binary_framed-ip-ssl",
+  "py-netstd_compact_buffered-ip",
   "py-netstd_compact_buffered-ip-ssl",
+  "py-netstd_compact_framed-ip",
   "py-netstd_compact_framed-ip-ssl",
   "py-netstd_json_buffered-ip",
   "py-netstd_json_buffered-ip-ssl",
@@ -784,10 +1025,8 @@
   "py-nodejs_accelc-compact_http-domain",
   "py-nodejs_binary_http-domain",
   "py-nodejs_compact_http-domain",
-  "py-nodejs_json_http-domain",
   "py-nodejs_header_http-domain",
-  "py-rs_multi_buffered-ip",
-  "py-rs_multi_framed-ip",
+  "py-nodejs_json_http-domain",
   "py-php_accel_buffered-ip",
   "py-php_accel_framed-ip",
   "py-php_binary-accel_buffered-ip",
@@ -800,6 +1039,8 @@
   "py-rs_multiac-multic_framed-ip",
   "py-rs_multic_buffered-ip",
   "py-rs_multic_framed-ip",
+  "py-rs_multi_buffered-ip",
+  "py-rs_multi_framed-ip",
   "py3-cpp_accel-binary_http-domain",
   "py3-cpp_accel-binary_http-ip",
   "py3-cpp_accel-binary_http-ip-ssl",
@@ -827,9 +1068,6 @@
   "py3-cpp_multi-binary_http-domain",
   "py3-cpp_multi-binary_http-ip",
   "py3-cpp_multi-binary_http-ip-ssl",
-  "py3-cpp_multi_http-domain",
-  "py3-cpp_multi_http-ip",
-  "py3-cpp_multi_http-ip-ssl",
   "py3-cpp_multia-binary_http-domain",
   "py3-cpp_multia-binary_http-ip",
   "py3-cpp_multia-binary_http-ip-ssl",
@@ -872,6 +1110,14 @@
   "py3-cpp_multij_http-domain",
   "py3-cpp_multij_http-ip",
   "py3-cpp_multij_http-ip-ssl",
+  "py3-cpp_multi_http-domain",
+  "py3-cpp_multi_http-ip",
+  "py3-cpp_multi_http-ip-ssl",
+  "py3-dart_accel-binary_http-ip",
+  "py3-dart_accelc-compact_http-ip",
+  "py3-dart_binary_http-ip",
+  "py3-dart_compact_http-ip",
+  "py3-dart_json_http-ip",
   "py3-d_accel-binary_http-ip",
   "py3-d_accel-binary_http-ip-ssl",
   "py3-d_accelc-compact_http-ip",
@@ -882,11 +1128,6 @@
   "py3-d_compact_http-ip-ssl",
   "py3-d_json_http-ip",
   "py3-d_json_http-ip-ssl",
-  "py3-dart_accel-binary_http-ip",
-  "py3-dart_accelc-compact_http-ip",
-  "py3-dart_binary_http-ip",
-  "py3-dart_compact_http-ip",
-  "py3-dart_json_http-ip",
   "py3-hs_accel-binary_http-ip",
   "py3-hs_accelc-compact_http-ip",
   "py3-hs_binary_http-ip",
@@ -899,7 +1140,6 @@
   "py3-java_compact_http-ip-ssl",
   "py3-java_json_http-ip-ssl",
   "py3-java_multi-binary_http-ip-ssl",
-  "py3-java_multi_http-ip-ssl",
   "py3-java_multia-binary_http-ip-ssl",
   "py3-java_multia-multi_http-ip-ssl",
   "py3-java_multiac-compact_http-ip-ssl",
@@ -908,17 +1148,27 @@
   "py3-java_multic_http-ip-ssl",
   "py3-java_multij-json_http-ip-ssl",
   "py3-java_multij_http-ip-ssl",
+  "py3-java_multi_http-ip-ssl",
   "py3-lua_accel-binary_http-ip",
   "py3-lua_accelc-compact_http-ip",
   "py3-lua_binary_http-ip",
   "py3-lua_compact_http-ip",
   "py3-lua_json_http-ip",
+  "py3-netstd_accel-binary_buffered-ip",
+  "py3-netstd_accel-binary_buffered-ip-ssl",
+  "py3-netstd_accel-binary_framed-ip",
   "py3-netstd_accel-binary_framed-ip-ssl",
+  "py3-netstd_accelc-compact_buffered-ip",
   "py3-netstd_accelc-compact_buffered-ip-ssl",
+  "py3-netstd_accelc-compact_framed-ip",
   "py3-netstd_accelc-compact_framed-ip-ssl",
+  "py3-netstd_binary_buffered-ip",
   "py3-netstd_binary_buffered-ip-ssl",
+  "py3-netstd_binary_framed-ip",
   "py3-netstd_binary_framed-ip-ssl",
+  "py3-netstd_compact_buffered-ip",
   "py3-netstd_compact_buffered-ip-ssl",
+  "py3-netstd_compact_framed-ip",
   "py3-netstd_compact_framed-ip-ssl",
   "py3-netstd_json_buffered-ip",
   "py3-netstd_json_buffered-ip-ssl",
@@ -928,10 +1178,8 @@
   "py3-nodejs_accelc-compact_http-domain",
   "py3-nodejs_binary_http-domain",
   "py3-nodejs_compact_http-domain",
-  "py3-nodejs_json_http-domain",
   "py3-nodejs_header_http-domain",
-  "py3-rs_multi_buffered-ip",
-  "py3-rs_multi_framed-ip",
+  "py3-nodejs_json_http-domain",
   "py3-php_accel_buffered-ip",
   "py3-php_accel_framed-ip",
   "py3-php_binary-accel_buffered-ip",
@@ -944,273 +1192,37 @@
   "py3-rs_multiac-multic_framed-ip",
   "py3-rs_multic_buffered-ip",
   "py3-rs_multic_framed-ip",
-  "d-netstd_json_framed-ip",
-  "d-netstd_json_buffered-ip",
-  "d-netstd_json_framed-ip-ssl",
-  "d-netstd_json_buffered-ip-ssl",
-  "go-netstd_json_buffered-ip-ssl",
-  "go-netstd_json_framed-ip-ssl",
-  "go-netstd_json_buffered-ip",
-  "go-netstd_json_framed-ip",
-  "rb-netstd_json_framed-ip",
-  "rb-netstd_json_buffered-ip",
-  "rb-netstd_json_framed-ip-ssl",
-  "rb-netstd_json_buffered-ip-ssl",
-  "netstd-d_json_framed-ip",
-  "netstd-d_json_framed-ip-ssl",
-  "netstd-d_json_buffered-ip",
-  "netstd-d_json_buffered-ip-ssl",
-  "netstd-go_json_framed-ip-ssl",
-  "netstd-go_json_framed-ip",
-  "netstd-go_json_buffered-ip",
-  "netstd-go_json_buffered-ip-ssl",
-  "netstd-java_json_framed-fastframed-ip",
-  "netstd-java_json_framed-fastframed-ip-ssl",
-  "netstd-java_json_framed-ip",
-  "netstd-java_json_framed-ip-ssl",
-  "netstd-java_json_buffered-ip",
-  "netstd-java_json_buffered-ip-ssl",
-  "netstd-nodejs_json_framed-ip",
-  "netstd-nodejs_json_framed-ip-ssl",
-  "netstd-nodejs_json_buffered-ip",
-  "netstd-nodejs_json_buffered-ip-ssl",
-  "netstd-hs_json_framed-ip",
-  "netstd-py_json_buffered-ip",
-  "netstd-hs_json_buffered-ip",
-  "netstd-py_json_buffered-ip-ssl",
-  "netstd-cpp_json_framed-ip",
-  "netstd-py3_json_buffered-ip",
-  "netstd-py3_json_buffered-ip-ssl",
-  "netstd-cpp_json_framed-ip-ssl",
-  "netstd-cpp_json_buffered-ip-ssl",
-  "netstd-cpp_json_buffered-ip",
-  "netstd-rb_json_framed-ip",
-  "netstd-rb_json_buffered-ip",
-  "netstd-lua_json_framed-ip",
-  "netstd-lua_json_buffered-ip",
-  "netstd-dart_json_framed-ip",
-  "netstd-dart_json_buffered-ip",
-  "c_glib-netstd_multi-binary_framed-ip",
-  "c_glib-netstd_binary_buffered-ip",
-  "c_glib-netstd_binary_framed-ip",
-  "c_glib-netstd_multi-binary_buffered-ip",
-  "cl-netstd_binary_buffered-ip",
-  "cl-netstd_binary_framed-ip",
-  "d-netstd_binary_framed-ip",
-  "d-netstd_binary_framed-ip-ssl",
-  "d-netstd_binary_buffered-ip",
-  "d-netstd_binary_buffered-ip-ssl",
-  "go-netstd_binary_framed-ip-ssl",
-  "go-netstd_binary_buffered-ip",
-  "go-netstd_binary_buffered-ip-ssl",
-  "go-netstd_binary_framed-ip",
-  "java-netstd_binary_framed-ip",
-  "java-netstd_binary_fastframed-framed-ip",
-  "java-netstd_binary_buffered-ip",
-  "java-netstd_multi-binary_framed-ip",
-  "java-netstd_multi-binary_buffered-ip",
-  "java-netstd_multi-binary_fastframed-framed-ip",
-  "nodejs-netstd_binary_framed-ip",
-  "nodejs-netstd_binary_buffered-ip",
-  "py-netstd_binary_framed-ip",
-  "py-netstd_binary_buffered-ip",
-  "py-netstd_accel-binary_framed-ip",
-  "py-netstd_accel-binary_buffered-ip",
-  "py-netstd_accel-binary_buffered-ip-ssl",
-  "py3-netstd_binary_framed-ip",
-  "py3-netstd_binary_buffered-ip",
-  "py3-netstd_accel-binary_framed-ip",
-  "py3-netstd_accel-binary_buffered-ip",
-  "py3-netstd_accel-binary_buffered-ip-ssl",
-  "cpp-netstd_binary_framed-ip-ssl",
-  "cpp-netstd_binary_framed-ip",
-  "cpp-netstd_binary_buffered-ip",
-  "cpp-netstd_binary_buffered-ip-ssl",
-  "cpp-netstd_multi-binary_buffered-ip",
-  "cpp-netstd_multi-binary_framed-ip",
-  "cpp-netstd_multi-binary_framed-ip-ssl",
-  "cpp-netstd_multi-binary_buffered-ip-ssl",
-  "rb-netstd_accel-binary_framed-ip",
-  "rb-netstd_accel-binary_buffered-ip-ssl",
-  "rb-netstd_accel-binary_buffered-ip",
-  "rb-netstd_accel-binary_framed-ip-ssl",
-  "rb-netstd_binary_buffered-ip-ssl",
-  "rb-netstd_binary_framed-ip",
-  "rb-netstd_binary_framed-ip-ssl",
-  "rb-netstd_binary_buffered-ip",
-  "netstd-c_glib_binary_buffered-ip",
-  "netstd-c_glib_binary_framed-ip",
-  "netstd-c_glib_binary_framed-ip-ssl",
-  "netstd-c_glib_binary_buffered-ip-ssl",
-  "netstd-cl_binary_buffered-ip",
-  "netstd-cl_binary_framed-ip",
-  "netstd-d_binary_framed-ip",
-  "netstd-d_binary_framed-ip-ssl",
-  "netstd-d_binary_buffered-ip",
-  "netstd-go_binary_framed-ip",
-  "netstd-d_binary_buffered-ip-ssl",
-  "netstd-go_binary_framed-ip-ssl",
-  "netstd-go_binary_buffered-ip",
-  "netstd-go_binary_buffered-ip-ssl",
-  "netstd-java_binary_framed-fastframed-ip-ssl",
-  "netstd-java_binary_framed-fastframed-ip",
-  "netstd-java_binary_framed-ip",
-  "netstd-java_binary_framed-ip-ssl",
-  "netstd-java_binary_buffered-ip-ssl",
-  "netstd-java_binary_buffered-ip",
-  "netstd-nodejs_binary_framed-ip",
-  "netstd-nodejs_binary_framed-ip-ssl",
-  "netstd-nodejs_binary_buffered-ip",
-  "netstd-nodejs_binary_buffered-ip-ssl",
-  "netstd-hs_binary_buffered-ip",
-  "netstd-hs_binary_framed-ip",
-  "netstd-py_binary_buffered-ip",
-  "netstd-py_binary_buffered-ip-ssl",
-  "netstd-py_binary-accel_buffered-ip-ssl",
-  "netstd-py_binary-accel_buffered-ip",
-  "netstd-py3_binary_buffered-ip",
-  "netstd-py3_binary_buffered-ip-ssl",
-  "netstd-py3_binary-accel_buffered-ip",
-  "netstd-py3_binary-accel_buffered-ip-ssl",
-  "netstd-cpp_binary_framed-ip",
-  "netstd-cpp_binary_framed-ip-ssl",
-  "netstd-cpp_binary_buffered-ip",
-  "netstd-cpp_binary_buffered-ip-ssl",
-  "netstd-rb_binary-accel_framed-ip",
-  "netstd-rb_binary-accel_buffered-ip",
-  "netstd-rb_binary_buffered-ip",
-  "netstd-rb_binary_framed-ip",
-  "netstd-perl_binary_framed-ip",
-  "netstd-netstd_binary_framed-ip",
-  "netstd-netstd_binary_buffered-ip",
-  "netstd-perl_binary_framed-ip-ssl",
-  "netstd-php_binary_framed-ip",
-  "netstd-perl_binary_buffered-ip-ssl",
-  "netstd-perl_binary_buffered-ip",
-  "netstd-php_binary_buffered-ip",
-  "netstd-erl_binary_framed-ip",
-  "netstd-erl_binary_buffered-ip",
-  "netstd-lua_binary_framed-ip",
-  "netstd-lua_binary_buffered-ip",
-  "netstd-rs_binary_framed-ip",
-  "netstd-rs_binary_buffered-ip",
-  "netstd-dart_binary_buffered-ip",
-  "netstd-dart_binary_framed-ip",
-  "netstd-nodets_binary_buffered-ip",
-  "perl-netstd_multi-binary_framed-ip",
-  "perl-netstd_multi-binary_buffered-ip",
-  "perl-netstd_multi-binary_buffered-ip-ssl",
-  "perl-netstd_multi-binary_framed-ip-ssl",
-  "perl-netstd_binary_buffered-ip",
-  "perl-netstd_binary_framed-ip-ssl",
-  "perl-netstd_binary_framed-ip",
-  "perl-netstd_binary_buffered-ip-ssl",
-  "erl-netstd_binary_framed-ip",
-  "rs-netstd_binary_buffered-ip",
-  "rs-netstd_binary_framed-ip",
-  "rs-netstd_multi-binary_framed-ip",
-  "rs-netstd_multi-binary_buffered-ip",
-  "nodets-netstd_binary_buffered-ip",
+  "py3-rs_multi_buffered-ip",
+  "py3-rs_multi_framed-ip",
   "rb-cpp_json_buffered-domain",
   "rb-cpp_json_buffered-ip",
   "rb-cpp_json_buffered-ip-ssl",
   "rb-cpp_json_framed-domain",
   "rb-cpp_json_framed-ip",
   "rb-cpp_json_framed-ip-ssl",
-  "rs-netstd_compact_buffered-ip",
-  "netstd-netstd_compact_buffered-ip",
-  "netstd-netstd_compact_framed-ip",
-  "netstd-php_compact_framed-ip",
-  "netstd-php_compact_buffered-ip",
-  "netstd-erl_compact_framed-ip",
-  "netstd-erl_compact_buffered-ip",
-  "netstd-lua_compact_framed-ip",
-  "netstd-lua_compact_buffered-ip",
-  "netstd-rs_compact_framed-ip",
-  "netstd-rs_compact_buffered-ip",
-  "netstd-dart_compact_framed-ip",
-  "netstd-dart_compact_buffered-ip",
-  "erl-netstd_compact_framed-ip",
-  "c_glib-netstd_multic-compact_framed-ip",
-  "c_glib-netstd_compact_framed-ip",
-  "c_glib-netstd_compact_buffered-ip",
-  "c_glib-netstd_multic-compact_buffered-ip",
-  "d-netstd_compact_buffered-ip",
-  "d-netstd_compact_framed-ip-ssl",
-  "d-netstd_compact_buffered-ip-ssl",
-  "d-netstd_compact_framed-ip",
-  "go-netstd_compact_framed-ip-ssl",
-  "go-netstd_compact_framed-ip",
-  "go-netstd_compact_buffered-ip-ssl",
-  "go-netstd_compact_buffered-ip",
-  "java-netstd_compact_framed-ip",
-  "java-netstd_compact_fastframed-framed-ip",
-  "java-netstd_compact_buffered-ip",
-  "java-netstd_multic-compact_fastframed-framed-ip",
-  "java-netstd_multic-compact_framed-ip",
-  "java-netstd_multic-compact_buffered-ip",
-  "nodejs-netstd_compact_framed-ip",
-  "nodejs-netstd_compact_buffered-ip",
-  "py-netstd_accelc-compact_buffered-ip",
-  "py-netstd_accelc-compact_framed-ip",
-  "py-netstd_compact_buffered-ip",
-  "py-netstd_compact_framed-ip",
-  "py3-netstd_compact_framed-ip",
-  "py3-netstd_accelc-compact_framed-ip",
-  "py3-netstd_compact_buffered-ip",
-  "py3-netstd_accelc-compact_buffered-ip",
-  "cpp-netstd_compact_buffered-ip",
-  "cpp-netstd_compact_framed-ip",
-  "cpp-netstd_compact_framed-ip-ssl",
-  "cpp-netstd_compact_buffered-ip-ssl",
-  "cpp-netstd_multic-compact_framed-ip",
-  "cpp-netstd_multic-compact_buffered-ip",
-  "cpp-netstd_multic-compact_framed-ip-ssl",
-  "cpp-netstd_multic-compact_buffered-ip-ssl",
+  "rb-netstd_accel-binary_buffered-ip",
+  "rb-netstd_accel-binary_buffered-ip-ssl",
+  "rb-netstd_accel-binary_framed-ip",
+  "rb-netstd_accel-binary_framed-ip-ssl",
+  "rb-netstd_binary_buffered-ip",
+  "rb-netstd_binary_buffered-ip-ssl",
+  "rb-netstd_binary_framed-ip",
+  "rb-netstd_binary_framed-ip-ssl",
+  "rb-netstd_compact_buffered-ip",
+  "rb-netstd_compact_buffered-ip-ssl",
   "rb-netstd_compact_framed-ip",
   "rb-netstd_compact_framed-ip-ssl",
-  "rb-netstd_compact_buffered-ip-ssl",
-  "rb-netstd_compact_buffered-ip",
-  "netstd-c_glib_compact_buffered-ip",
-  "netstd-c_glib_compact_framed-ip",
-  "netstd-c_glib_compact_framed-ip-ssl",
-  "netstd-c_glib_compact_buffered-ip-ssl",
-  "netstd-d_compact_framed-ip",
-  "netstd-d_compact_framed-ip-ssl",
-  "netstd-d_compact_buffered-ip",
-  "netstd-d_compact_buffered-ip-ssl",
-  "netstd-go_compact_framed-ip",
-  "netstd-go_compact_framed-ip-ssl",
-  "netstd-go_compact_buffered-ip-ssl",
-  "netstd-go_compact_buffered-ip",
-  "netstd-java_compact_framed-ip-ssl",
-  "netstd-java_compact_framed-fastframed-ip-ssl",
-  "netstd-java_compact_framed-ip",
-  "netstd-java_compact_framed-fastframed-ip",
-  "netstd-java_compact_buffered-ip-ssl",
-  "netstd-nodejs_compact_framed-ip",
-  "netstd-java_compact_buffered-ip",
-  "netstd-nodejs_compact_framed-ip-ssl",
-  "netstd-hs_compact_framed-ip",
-  "netstd-nodejs_compact_buffered-ip-ssl",
-  "netstd-nodejs_compact_buffered-ip",
-  "netstd-hs_compact_buffered-ip",
-  "netstd-py_compact-accelc_buffered-ip-ssl",
-  "netstd-py_compact-accelc_buffered-ip",
-  "netstd-py_compact_buffered-ip",
-  "netstd-py_compact_buffered-ip-ssl",
-  "netstd-py3_compact-accelc_buffered-ip-ssl",
-  "netstd-py3_compact-accelc_buffered-ip",
-  "netstd-py3_compact_buffered-ip",
-  "netstd-py3_compact_buffered-ip-ssl",
-  "netstd-cpp_compact_framed-ip-ssl",
-  "netstd-cpp_compact_framed-ip",
-  "netstd-cpp_compact_buffered-ip",
-  "netstd-cpp_compact_buffered-ip-ssl",
-  "netstd-rb_compact_framed-ip",
-  "netstd-rb_compact_buffered-ip",
+  "rb-netstd_json_buffered-ip",
+  "rb-netstd_json_buffered-ip-ssl",
+  "rb-netstd_json_framed-ip",
+  "rb-netstd_json_framed-ip-ssl",
+  "rs-netstd_binary_buffered-ip",
+  "rs-netstd_binary_framed-ip",
+  "rs-netstd_compact_buffered-ip",
+  "rs-netstd_compact_buffered-ip",
   "rs-netstd_compact_framed-ip",
-  "rs-netstd_multic-compact_framed-ip",
+  "rs-netstd_multi-binary_buffered-ip",
+  "rs-netstd_multi-binary_framed-ip",
   "rs-netstd_multic-compact_buffered-ip",
-  "rs-netstd_compact_buffered-ip"
+  "rs-netstd_multic-compact_framed-ip"
 ]
diff --git a/test/lua/test_basic_client.lua b/test/lua/test_basic_client.lua
index 77d8d07..11567d9 100644
--- a/test/lua/test_basic_client.lua
+++ b/test/lua/test_basic_client.lua
@@ -172,6 +172,9 @@
   assertEqual(o.i32_thing, r.i32_thing, 'Failed testStruct 3')
   assertEqual(o.i64_thing, r.i64_thing, 'Failed testStruct 4')
 
+  -- oneway
+  client:testOneway(3)
+
   -- TODO add list map set exception etc etc
 end
 
diff --git a/test/lua/test_basic_server.lua b/test/lua/test_basic_server.lua
index acd2d79..20ac407 100644
--- a/test/lua/test_basic_server.lua
+++ b/test/lua/test_basic_server.lua
@@ -66,6 +66,10 @@
   return thing
 end
 
+function TestHandler:testOneway(secondsToSleep)
+  print("testOneway secondsToSleep:", secondsToSleep)
+end
+
 --------------------------------------------------------------------------------
 -- Test
 local server
@@ -132,6 +136,7 @@
     protocolFactory = prot_factory
   }
   assert(server, 'Failed to create server')
+  server:setExceptionHandler(function (err) error(err) end)
 
   -- Serve
   server:serve()
diff --git a/test/rs/Cargo.toml b/test/rs/Cargo.toml
index c1058f9..deffd21 100644
--- a/test/rs/Cargo.toml
+++ b/test/rs/Cargo.toml
@@ -1,6 +1,7 @@
 [package]
 name = "thrift-test"
 version = "0.1.0"
+edition = "2018"
 license = "Apache-2.0"
 authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
 publish = false
diff --git a/test/rs/src/bin/test_client.rs b/test/rs/src/bin/test_client.rs
index 5983c7d..3206deb 100644
--- a/test/rs/src/bin/test_client.rs
+++ b/test/rs/src/bin/test_client.rs
@@ -110,10 +110,10 @@
     transport: &str,
     protocol: &str,
     service_name: &str,
-) -> thrift::Result<(Box<TInputProtocol>, Box<TOutputProtocol>)> {
+) -> thrift::Result<(Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>)> {
     let (i_chan, o_chan) = tcp_channel(host, port)?;
 
-    let (i_tran, o_tran): (Box<TReadTransport>, Box<TWriteTransport>) = match transport {
+    let (i_tran, o_tran): (Box<dyn TReadTransport>, Box<dyn TWriteTransport>) = match transport {
         "buffered" => {
             (Box::new(TBufferedReadTransport::new(i_chan)),
              Box::new(TBufferedWriteTransport::new(o_chan)))
@@ -125,7 +125,7 @@
         unmatched => return Err(format!("unsupported transport {}", unmatched).into()),
     };
 
-    let (i_prot, o_prot): (Box<TInputProtocol>, Box<TOutputProtocol>) = match protocol {
+    let (i_prot, o_prot): (Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>) = match protocol {
         "binary" => {
             (Box::new(TBinaryInputProtocol::new(i_tran, true)),
              Box::new(TBinaryOutputProtocol::new(o_tran, true)))
@@ -164,8 +164,8 @@
     c.split()
 }
 
-type BuildThriftTestClient = ThriftTestSyncClient<Box<TInputProtocol>, Box<TOutputProtocol>>;
-type BuiltSecondServiceClient = SecondServiceSyncClient<Box<TInputProtocol>, Box<TOutputProtocol>>;
+type BuildThriftTestClient = ThriftTestSyncClient<Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>>;
+type BuiltSecondServiceClient = SecondServiceSyncClient<Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>>;
 
 #[cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity))]
 fn make_thrift_calls(
diff --git a/test/rs/src/bin/test_server.rs b/test/rs/src/bin/test_server.rs
index d87ef75..e57cc14 100644
--- a/test/rs/src/bin/test_server.rs
+++ b/test/rs/src/bin/test_server.rs
@@ -80,8 +80,8 @@
 
     info!("binding to {}", listen_address);
 
-    let (i_transport_factory, o_transport_factory): (Box<TReadTransportFactory>,
-                                                     Box<TWriteTransportFactory>) =
+    let (i_transport_factory, o_transport_factory): (Box<dyn TReadTransportFactory>,
+                                                     Box<dyn TWriteTransportFactory>) =
         match &*transport {
             "buffered" => {
                 (Box::new(TBufferedReadTransportFactory::new()),
@@ -96,8 +96,8 @@
             }
         };
 
-    let (i_protocol_factory, o_protocol_factory): (Box<TInputProtocolFactory>,
-                                                   Box<TOutputProtocolFactory>) =
+    let (i_protocol_factory, o_protocol_factory): (Box<dyn TInputProtocolFactory>,
+                                                   Box<dyn TOutputProtocolFactory>) =
         match &*protocol {
             "binary" | "multi" | "multi:binary" => {
                 (Box::new(TBinaryInputProtocolFactory::new()),
diff --git a/test/rs/src/lib.rs b/test/rs/src/lib.rs
index 479bf90..10523f0 100644
--- a/test/rs/src/lib.rs
+++ b/test/rs/src/lib.rs
@@ -20,4 +20,4 @@
 extern crate try_from;
 
 mod thrift_test;
-pub use thrift_test::*;
+pub use crate::thrift_test::*;
diff --git a/tutorial/rs/Cargo.toml b/tutorial/rs/Cargo.toml
index 60f02d7..d8e2a9a 100644
--- a/tutorial/rs/Cargo.toml
+++ b/tutorial/rs/Cargo.toml
@@ -1,6 +1,7 @@
 [package]
 name = "thrift-tutorial"
 version = "0.1.0"
+edition = "2018"
 license = "Apache-2.0"
 authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
 exclude = ["Makefile*", "shared.rs", "tutorial.rs"]
diff --git a/tutorial/rs/src/bin/tutorial_client.rs b/tutorial/rs/src/bin/tutorial_client.rs
index bfd81d4..90a26d8 100644
--- a/tutorial/rs/src/bin/tutorial_client.rs
+++ b/tutorial/rs/src/bin/tutorial_client.rs
@@ -18,9 +18,6 @@
 #[macro_use]
 extern crate clap;
 
-extern crate thrift;
-extern crate thrift_tutorial;
-
 use thrift::protocol::{TCompactInputProtocol, TCompactOutputProtocol};
 use thrift::transport::{
     ReadHalf, TFramedReadTransport, TFramedWriteTransport, TIoChannel, TTcpChannel, WriteHalf,
diff --git a/tutorial/rs/src/bin/tutorial_server.rs b/tutorial/rs/src/bin/tutorial_server.rs
index 95b1a2b..e4d1d2e 100644
--- a/tutorial/rs/src/bin/tutorial_server.rs
+++ b/tutorial/rs/src/bin/tutorial_server.rs
@@ -18,9 +18,6 @@
 #[macro_use]
 extern crate clap;
 
-extern crate thrift;
-extern crate thrift_tutorial;
-
 use std::collections::HashMap;
 use std::convert::{From, Into};
 use std::default::Default;
diff --git a/tutorial/rs/src/lib.rs b/tutorial/rs/src/lib.rs
index 40007e5..ac509cc 100644
--- a/tutorial/rs/src/lib.rs
+++ b/tutorial/rs/src/lib.rs
@@ -15,9 +15,5 @@
 // specific language governing permissions and limitations
 // under the License.
 
-extern crate ordered_float;
-extern crate thrift;
-extern crate try_from;
-
 pub mod shared;
 pub mod tutorial;