Merge branch '0.19.0' into upstream
diff --git a/.gitignore b/.gitignore
index 232ed2c..cb8029c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -210,7 +210,6 @@
 /lib/delphi/**/*.dcu
 /lib/delphi/**/*.2007
 /lib/delphi/**/codegen/*.bat
-/lib/erl/_build/
 /lib/erl/.eunit
 /lib/erl/.generated
 /lib/erl/.rebar/
diff --git a/ApacheThrift.nuspec b/ApacheThrift.nuspec
index 0e6f09e..cd9a29c 100644
--- a/ApacheThrift.nuspec
+++ b/ApacheThrift.nuspec
@@ -19,14 +19,14 @@
      the "Thrift" project.
   2. nuget setApiKey <your-api-key>
   3. nuget pack ApacheThrift.nuspec -Symbols -SymbolPackageFormat snupkg
-  4. nuget push ApacheThrift.0.19.0.nupkg -Source https://api.nuget.org/v3/index.json
+  4. nuget push ApacheThrift.0.20.0.nupkg -Source https://api.nuget.org/v3/index.json
   -->
 
 <package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
   <metadata>
     <id>ApacheThrift</id>
-    <version>0.19.0</version>
-    <title>Apache Thrift 0.19.0</title>
+    <version>0.20.0</version>
+    <title>Apache Thrift 0.20.0</title>
     <authors>Apache Thrift Developers</authors>
     <owners>Apache Software Foundation</owners>
     <license type="expression">Apache-2.0</license>
@@ -36,7 +36,7 @@
     <description>
       Contains runtime libraries from lib/netstd for netstandard2.0 framework development.
     </description>
-    <repository type="GitHub" url="https://github.com/apache/thrift" branch="release/0.19.0" />
+    <repository type="GitHub" url="https://github.com/apache/thrift" branch="release/0.20.0" />
     <tags>Apache Thrift RPC</tags>
   </metadata>
   <files>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f056629..a685e4f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,7 +28,7 @@
 
 # PACKAGE_VERSION is used by cpack scripts currently
 # Both thrift_VERSION and PACKAGE_VERSION should be the same for now
-set(thrift_VERSION "0.19.0")
+set(thrift_VERSION "0.20.0")
 set(PACKAGE_VERSION ${thrift_VERSION})
 
 project("thrift" VERSION ${PACKAGE_VERSION})
diff --git a/Thrift.podspec b/Thrift.podspec
index fe5bcc3..8bf70f6 100644
--- a/Thrift.podspec
+++ b/Thrift.podspec
@@ -1,6 +1,6 @@
 Pod::Spec.new do |s|
   s.name          = 'Thrift'
-  s.version       = '0.19.0'
+  s.version       = '0.20.0'
   s.summary       = "Apache Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC."
   s.description   = <<-DESC
 The Apache Thrift scalable cross-language software framework for networked services development combines a software stack with a code generation engine to build services that work efficiently and seamlessly between many programming languages.
@@ -10,6 +10,6 @@
   s.author        = { 'Apache Thrift Developers' => 'dev@thrift.apache.org' }
   s.ios.deployment_target = '9.0'
   s.osx.deployment_target = '10.10'
-  s.source        = { :git => 'https://github.com/apache/thrift.git', :tag => 'v0.19.0' }
+  s.source        = { :git => 'https://github.com/apache/thrift.git', :tag => 'v0.20.0' }
   s.source_files  = 'lib/swift/Sources/*.swift'
 end
diff --git a/appveyor.yml b/appveyor.yml
index 1f5abeb..5847ea9 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -19,7 +19,7 @@
 
 # build Apache Thrift on AppVeyor - https://ci.appveyor.com
 
-version: '0.19.0.{build}'
+version: '0.20.0.{build}'
 
 shallow_clone: true
 
diff --git a/bower.json b/bower.json
index 51913da..84f3a98 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.19.0",
+  "version": "0.20.0",
   "homepage": "https://github.com/apache/thrift.git",
   "authors": [
     "Apache Thrift <dev@thrift.apache.org>"
diff --git a/build/docker/README.md b/build/docker/README.md
index 9635e6f..abf0823 100644
--- a/build/docker/README.md
+++ b/build/docker/README.md
@@ -177,7 +177,7 @@
 | d         | 2.087.0       | 2.087.0       |       |
 | dart      | 2.0.0         | 2.4.0         |       |
 | delphi    |               |               | Not in CI |
-| erlang    | OTP-18        | OTP-23        |       |
+| erlang    | OTP-20        | OTP-25        |       |
 | go        | 1.15.10       | 1.16.2        |       |
 | haxe      | 3.2.1         | 3.4.4         | THRIFT-4352: avoid 3.4.2 |
 | java      | 1.8.0\_191     | 17           |       |
diff --git a/build/docker/old/ubuntu-xenial/Dockerfile b/build/docker/old/ubuntu-xenial/Dockerfile
index 64d4804..d954e7f 100644
--- a/build/docker/old/ubuntu-xenial/Dockerfile
+++ b/build/docker/old/ubuntu-xenial/Dockerfile
@@ -121,7 +121,7 @@
       dotnet-apphost-pack-7.0
 
 # Erlang dependencies
-ARG ERLANG_OTP_VERSION=18.3.4.11
+ARG ERLANG_OTP_VERSION=20.3.8.9
 ARG ERLANG_REBAR_VERSION=3.13.2
 RUN apt-get update && apt-get install -y --no-install-recommends automake libncurses5-dev && \
       curl https://raw.githubusercontent.com/kerl/kerl/master/kerl -o /usr/local/bin/kerl && chmod +x /usr/local/bin/kerl && \
diff --git a/compiler/cpp/src/thrift/version.h b/compiler/cpp/src/thrift/version.h
index 4f979d9..65e0f43 100644
--- a/compiler/cpp/src/thrift/version.h
+++ b/compiler/cpp/src/thrift/version.h
@@ -24,6 +24,6 @@
 #pragma once
 #endif // _MSC_VER
 
-#define THRIFT_VERSION "0.19.0"
+#define THRIFT_VERSION "0.20.0"
 
 #endif // _THRIFT_VERSION_H_
diff --git a/configure.ac b/configure.ac
index 6331acd..ace48fc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@
 AC_PREREQ(2.65)
 AC_CONFIG_MACRO_DIR([./aclocal])
 
-AC_INIT([thrift], [0.19.0])
+AC_INIT([thrift], [0.20.0])
 
 AC_CONFIG_AUX_DIR([.])
 
diff --git a/contrib/Rebus/Properties/AssemblyInfo.cs b/contrib/Rebus/Properties/AssemblyInfo.cs
index ab40a65..33b0aa8 100644
--- a/contrib/Rebus/Properties/AssemblyInfo.cs
+++ b/contrib/Rebus/Properties/AssemblyInfo.cs
@@ -34,5 +34,5 @@
 
 [assembly: Guid("0af10984-40d3-453d-b1e5-421529e8c7e2")]
 
-[assembly: AssemblyVersion("0.19.0.0")]
-[assembly: AssemblyFileVersion("0.19.0.0")]
+[assembly: AssemblyVersion("0.20.0.0")]
+[assembly: AssemblyFileVersion("0.20.0.0")]
diff --git a/contrib/thrift-maven-plugin/pom.xml b/contrib/thrift-maven-plugin/pom.xml
index 21bd381..e6e4324 100644
--- a/contrib/thrift-maven-plugin/pom.xml
+++ b/contrib/thrift-maven-plugin/pom.xml
@@ -29,7 +29,7 @@
   <artifactId>thrift-maven-plugin</artifactId>
   <packaging>maven-plugin</packaging>
   <name>thrift-maven-plugin</name>
-  <version>0.19.0</version>
+  <version>0.20.0</version>
 
   <properties>
     <maven.compiler.source>1.8</maven.compiler.source>
diff --git a/contrib/thrift.spec b/contrib/thrift.spec
index 5701116..90bf4aa 100644
--- a/contrib/thrift.spec
+++ b/contrib/thrift.spec
@@ -28,7 +28,7 @@
 License:        Apache License v2.0
 Group:          Development
 Summary:        RPC and serialization framework
-Version:        0.19.0
+Version:        0.20.0
 Release:        0
 URL:            http://thrift.apache.org
 Packager:       Thrift Developers <dev@thrift.apache.org>
diff --git a/contrib/zeromq/csharp/AssemblyInfo.cs b/contrib/zeromq/csharp/AssemblyInfo.cs
index e785620..8d7ed39 100644
--- a/contrib/zeromq/csharp/AssemblyInfo.cs
+++ b/contrib/zeromq/csharp/AssemblyInfo.cs
@@ -36,7 +36,7 @@
 // The form "{Major}.{Minor}.*" will automatically update the build and revision,
 // and "{Major}.{Minor}.{Build}.*" will update just the revision.
 
-[assembly: AssemblyVersion("0.19.0.0")]
+[assembly: AssemblyVersion("0.20.0.0")]
 
 // The following attributes are used to specify the signing key for the assembly,
 // if desired. See the Mono documentation for more information about signing.
diff --git a/doc/specs/idl.md b/doc/specs/idl.md
index cf8354f..0980f5b 100644
--- a/doc/specs/idl.md
+++ b/doc/specs/idl.md
@@ -1,6 +1,6 @@
 ## Thrift interface description language
 
-For Thrift version 0.19.0.
+For Thrift version 0.20.0.
 
 The Thrift interface definition language (IDL) allows for the definition of [Thrift Types](/docs/types). A Thrift IDL file is processed by the Thrift code generator to produce code for the various target languages to support the defined structs and services in the IDL file.
 
diff --git a/lib/d/src/thrift/base.d b/lib/d/src/thrift/base.d
index dbf1429..e843a5c 100644
--- a/lib/d/src/thrift/base.d
+++ b/lib/d/src/thrift/base.d
@@ -50,7 +50,7 @@
 /// The Thrift version string, used for informative purposes.
 // Note: This is currently hardcoded, but will likely be filled in by the build
 // system in future versions.
-enum VERSION = "0.19.0";
+enum VERSION = "0.20.0";
 
 /**
  * Functions used for logging inside Thrift.
diff --git a/lib/dart/pubspec.yaml b/lib/dart/pubspec.yaml
index f16c3ea..7e20548 100644
--- a/lib/dart/pubspec.yaml
+++ b/lib/dart/pubspec.yaml
@@ -16,7 +16,7 @@
 # under the License.
 
 name: thrift
-version: 0.19.0
+version: 0.20.0
 description: >
   A Dart library for Apache Thrift
 author: Apache Thrift Developers <dev@thrift.apache.org>
diff --git a/lib/delphi/src/Thrift.pas b/lib/delphi/src/Thrift.pas
index b725ebc..6696a19 100644
--- a/lib/delphi/src/Thrift.pas
+++ b/lib/delphi/src/Thrift.pas
@@ -28,7 +28,7 @@
   Thrift.Protocol;
 
 const
-  Version = '0.19.0';
+  Version = '0.20.0';
 
 type
   TException = Thrift.Exception.TException; // compatibility alias
diff --git a/lib/erl/include/thrift_constants.hrl b/lib/erl/include/thrift_constants.hrl
index 7cb29eb..4096854 100644
--- a/lib/erl/include/thrift_constants.hrl
+++ b/lib/erl/include/thrift_constants.hrl
@@ -41,10 +41,16 @@
 
 % TApplicationException
 -define(TApplicationException_Structure,
-        {struct, [{1, string},
-                  {2, i32}]}).
+    {struct, [
+        {1, string},
+        {2, i32}
+    ]}
+).
 
--record('TApplicationException', {message, type}).
+-record('TApplicationException', {
+    message :: string(),
+    type :: integer()
+}).
 
 -define(TApplicationException_UNKNOWN, 0).
 -define(TApplicationException_UNKNOWN_METHOD, 1).
@@ -58,5 +64,5 @@
 -define(TApplicationException_INVALID_PROTOCOL, 9).
 -define(TApplicationException_UNSUPPORTED_CLIENT_TYPE, 10).
 
--define (MULTIPLEXED_SERVICE_SEPARATOR, ":").
--define (MULTIPLEXED_ERROR_HANDLER_KEY, "error_handler").
+-define(MULTIPLEXED_SERVICE_SEPARATOR, ":").
+-define(MULTIPLEXED_ERROR_HANDLER_KEY, "error_handler").
diff --git a/lib/erl/include/thrift_protocol.hrl b/lib/erl/include/thrift_protocol.hrl
index bc0acc8..f477423 100644
--- a/lib/erl/include/thrift_protocol.hrl
+++ b/lib/erl/include/thrift_protocol.hrl
@@ -21,46 +21,47 @@
 -define(THRIFT_PROTOCOL_INCLUDED, true).
 
 -record(protocol_message_begin, {name :: string(), type :: integer(), seqid :: integer()}).
--record(protocol_struct_begin, {name :: string()}).
--record(protocol_field_begin, {name :: string(), type :: integer(), id :: integer()}).
+-record(protocol_struct_begin, {name :: undefined | string()}).
+-record(protocol_field_begin, {
+    name :: undefined | string(), type :: integer(), id :: undefined | integer()
+}).
 -record(protocol_map_begin, {ktype :: integer(), vtype :: integer(), size :: integer()}).
 -record(protocol_list_begin, {etype :: integer(), size :: integer()}).
 -record(protocol_set_begin, {etype :: integer(), size :: integer()}).
 
--type tprot_header_val() :: #protocol_message_begin{}
-                          | #protocol_struct_begin{}
-                          | #protocol_field_begin{}
-                          | #protocol_map_begin{}
-                          | #protocol_list_begin{}
-                          | #protocol_set_begin{}
-                          .
--type tprot_empty_tag() :: message_end
-                         | struct_begin
-                         | struct_end
-                         | field_end
-                         | map_end
-                         | list_end
-                         | set_end
-                         .
--type tprot_header_tag() :: message_begin
-                          | field_begin
-                          | map_begin
-                          | list_begin
-                          | set_begin
-                          .
--type tprot_data_tag() :: ui32
-                        | bool
-                        | byte
-                        | i16
-                        | i32
-                        | i64
-                        | double
-                        | string
-                        .
--type tprot_cont_tag() :: {list, _Type}
-                        | {map, _KType, _VType}
-                        | {set, _Type}
-                        .
-
+-type tprot_header_val() ::
+    #protocol_message_begin{}
+    | #protocol_struct_begin{}
+    | #protocol_field_begin{}
+    | #protocol_map_begin{}
+    | #protocol_list_begin{}
+    | #protocol_set_begin{}.
+-type tprot_empty_tag() ::
+    message_end
+    | struct_begin
+    | struct_end
+    | field_end
+    | map_end
+    | list_end
+    | set_end.
+-type tprot_header_tag() ::
+    message_begin
+    | field_begin
+    | map_begin
+    | list_begin
+    | set_begin.
+-type tprot_data_tag() ::
+    ui32
+    | bool
+    | byte
+    | i16
+    | i32
+    | i64
+    | double
+    | string.
+-type tprot_cont_tag() ::
+    {list, _Type}
+    | {map, _KType, _VType}
+    | {set, _Type}.
 
 -endif.
diff --git a/lib/erl/include/thrift_protocol_behaviour.hrl b/lib/erl/include/thrift_protocol_behaviour.hrl
deleted file mode 100644
index abe300b..0000000
--- a/lib/erl/include/thrift_protocol_behaviour.hrl
+++ /dev/null
@@ -1,37 +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.
-%%
-
-%% Signature specifications for protocol implementations.
-
--ifndef(THRIFT_PROTOCOL_BEHAVIOUR_INCLUDED).
--define(THRIFT_PROTOCOL_BEHAVIOUR_INCLUDED, true).
-
--spec flush_transport(state()) -> {state(), ok | {error, _Reason}}.
--spec close_transport(state()) -> {state(), ok | {error, _Reason}}.
-
--spec write(state(), any()) -> {state(), ok | {error, _Reason}}.
-
-%% NOTE: Keep this in sync with thrift_protocol:read and read_specific.
--spec read
-        (state(), tprot_empty_tag()) ->  {state(),  ok                | {error, _Reason}};
-        (state(), tprot_header_tag()) -> {state(), tprot_header_val() | {error, _Reason}};
-        (state(), tprot_data_tag()) ->   {state(), {ok, any()}        | {error, _Reason}}.
-
-
--endif.
diff --git a/lib/erl/include/thrift_transport_behaviour.hrl b/lib/erl/include/thrift_transport_behaviour.hrl
deleted file mode 100644
index dbc05aa..0000000
--- a/lib/erl/include/thrift_transport_behaviour.hrl
+++ /dev/null
@@ -1,31 +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.
-%%
-
-%% Signature specifications for transport implementations.
-
--ifndef(THRIFT_TRANSPORT_BEHAVIOUR_INCLUDED).
--define(THRIFT_TRANSPORT_BEHAVIOUR_INCLUDED, true).
-
--spec write(state(), iolist() | binary()) -> {state(), ok | {error, _Reason}}.
--spec read(state(), non_neg_integer()) -> {state(), {ok, binary()} | {error, _Reason}}.
--spec flush(state()) -> {state(), ok | {error, _Reason}}.
--spec close(state()) -> {state(), ok | {error, _Reason}}.
-
-
--endif.
diff --git a/lib/erl/rebar.config b/lib/erl/rebar.config
index b5258a2..c3149b4 100644
--- a/lib/erl/rebar.config
+++ b/lib/erl/rebar.config
@@ -1,8 +1,55 @@
-{erl_opts, [debug_info]}.
+%% Common project erlang options.
+{erl_opts, [
+
+    % mandatory
+    debug_info,
+    warn_export_all,
+    warn_untyped_record,
+    warn_export_vars,
+
+    % by default
+    warn_unused_record,
+    warn_bif_clash,
+    warn_obsolete_guard,
+    warn_unused_vars,
+    warn_shadow_vars,
+    warn_unused_import,
+    warn_unused_function,
+    warn_deprecated_function
+]}.
+
+%% XRef checks
+{xref_checks, [
+    deprecated_functions_calls,
+    deprecated_functions
+]}.
+
+%% Dialyzer static analyzing
+{dialyzer, [
+    {warnings, [
+        % mandatory
+        unmatched_returns,
+        error_handling,
+        unknown
+        % hardcore mode
+        % overspecs,
+        % underspecs
+    ]},
+    {plt_extra_apps, [ssl, inets, public_key]}
+]}.
+
+{plugins, [
+    {erlfmt, "1.1.0"}
+]}.
+
+{erlfmt, [
+    {print_width, 100},
+    {files, "{src,include,test}/*.{hrl,erl,app.src}"}
+]}.
 
 {profiles, [
     {test, [
-        {deps, [meck]},
+        {deps, [{meck, "0.9.2"}]},
         {eunit_tests, [
             {dir, "test"},
             {dir, "test/gen-erl"}
diff --git a/lib/erl/src/thrift.app.src b/lib/erl/src/thrift.app.src
index c681a2f..0e25b67 100644
--- a/lib/erl/src/thrift.app.src
+++ b/lib/erl/src/thrift.app.src
@@ -18,57 +18,34 @@
 %%
 %%% -*- mode:erlang -*-
 {application, thrift, [
-  % A quick description of the application.
-  {description, "Thrift bindings"},
+    % A quick description of the application.
+    {description, "Thrift bindings"},
 
   % The version of the applicaton
-  {vsn, "0.19.0"},
+  {vsn, "0.20.0"},
 
-  % All modules used by the application.
-  {modules, [
-    thrift_base64_transport,
-    thrift_binary_protocol,
-    thrift_buffered_transport,
-    thrift_client_util,
-    thrift_client,
-    thrift_disk_log_transport,
-    thrift_file_transport,
-    thrift_framed_transport,
-    thrift_http_transport,
-    thrift_json_parser,
-    thrift_json_protocol,
-    thrift_membuffer_transport,
-    thrift_memory_buffer,
-    thrift_processor,
-    thrift_protocol,
-    thrift_reconnecting_client,
-    thrift_server,
-    thrift_service,
-    thrift_socket_server,
-    thrift_socket_transport,
-    thrift_transport_state_test,
-    thrift_transport
-  ]},
+    % All modules used by the application.
+    {modules, []},
 
-  % All of the registered names the application uses. This can be ignored.
-  {registered, []},
+    % All of the registered names the application uses. This can be ignored.
+    {registered, []},
 
-  % Applications that are to be started prior to this one. This can be ignored
-  % leave it alone unless you understand it well and let the .rel files in
-  % your release handle this.
-  {applications, [kernel, stdlib]},
+    % Applications that are to be started prior to this one. This can be ignored
+    % leave it alone unless you understand it well and let the .rel files in
+    % your release handle this.
+    {applications, [kernel, stdlib]},
 
-  % OTP application loader will load, but not start, included apps. Again
-  % this can be ignored as well.  To load but not start an application it
-  % is easier to include it in the .rel file followed by the atom 'none'
-  {included_applications, []},
+    % OTP application loader will load, but not start, included apps. Again
+    % this can be ignored as well.  To load but not start an application it
+    % is easier to include it in the .rel file followed by the atom 'none'
+    {included_applications, []},
 
-  % configuration parameters similar to those in the config file specified
-  % on the command line. can be fetched with gas:get_env
-  {env, [
-    % If an error/crash occurs during processing of a function,
-    % should the TApplicationException serialized back to the client
-    % include the erlang backtrace?
-    {exceptions_include_traces, true}
-  ]}
+    % configuration parameters similar to those in the config file specified
+    % on the command line. can be fetched with gas:get_env
+    {env, [
+        % If an error/crash occurs during processing of a function,
+        % should the TApplicationException serialized back to the client
+        % include the erlang backtrace?
+        {exceptions_include_traces, true}
+    ]}
 ]}.
diff --git a/lib/erl/src/thrift_base64_transport.erl b/lib/erl/src/thrift_base64_transport.erl
index d31f2ba..9aa629f 100644
--- a/lib/erl/src/thrift_base64_transport.erl
+++ b/lib/erl/src/thrift_base64_transport.erl
@@ -28,42 +28,37 @@
 -export([write/2, read/2, flush/1, close/1]).
 
 %% State
--record(b64_transport, {wrapped}).
--type state() :: #b64_transport{}.
--include("thrift_transport_behaviour.hrl").
+-record(b64_transport, {
+    wrapped :: thrift_transport:t_transport()
+}).
 
 new(Wrapped) ->
     State = #b64_transport{wrapped = Wrapped},
     thrift_transport:new(?MODULE, State).
 
-
 write(This = #b64_transport{wrapped = Wrapped}, Data) ->
     {NewWrapped, Result} = thrift_transport:write(Wrapped, base64:encode(iolist_to_binary(Data))),
     {This#b64_transport{wrapped = NewWrapped}, Result}.
 
-
 %% base64 doesn't support reading quite yet since it would involve
 %% nasty buffering and such
 read(This = #b64_transport{}, _Data) ->
     {This, {error, no_reads_allowed}}.
 
-
 flush(This = #b64_transport{wrapped = Wrapped0}) ->
     {Wrapped1, ok} = thrift_transport:write(Wrapped0, <<"\n">>),
     {Wrapped2, ok} = thrift_transport:flush(Wrapped1),
     {This#b64_transport{wrapped = Wrapped2}, ok}.
 
-
 close(This0) ->
     {This1 = #b64_transport{wrapped = Wrapped}, ok} = flush(This0),
     {NewWrapped, ok} = thrift_transport:close(Wrapped),
     {This1#b64_transport{wrapped = NewWrapped}, ok}.
 
-
 %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 new_transport_factory(WrapFactory) ->
     F = fun() ->
-                {ok, Wrapped} = WrapFactory(),
-                new(Wrapped)
-        end,
+        {ok, Wrapped} = WrapFactory(),
+        new(Wrapped)
+    end,
     {ok, F}.
diff --git a/lib/erl/src/thrift_binary_protocol.erl b/lib/erl/src/thrift_binary_protocol.erl
index 85abb62..d2c89d3 100644
--- a/lib/erl/src/thrift_binary_protocol.erl
+++ b/lib/erl/src/thrift_binary_protocol.erl
@@ -24,21 +24,21 @@
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
--export([new/1, new/2,
-         read/2,
-         write/2,
-         flush_transport/1,
-         close_transport/1,
+-export([
+    new/1, new/2,
+    read/2,
+    write/2,
+    flush_transport/1,
+    close_transport/1,
 
-         new_protocol_factory/2
-        ]).
+    new_protocol_factory/2
+]).
 
--record(binary_protocol, {transport,
-                          strict_read=true,
-                          strict_write=true
-                         }).
--type state() :: #binary_protocol{}.
--include("thrift_protocol_behaviour.hrl").
+-record(binary_protocol, {
+    transport :: term(),
+    strict_read = true :: boolean(),
+    strict_write = true :: boolean()
+}).
 
 -define(VERSION_MASK, 16#FFFF0000).
 -define(VERSION_1, 16#80010000).
@@ -48,17 +48,16 @@
     new(Transport, _Options = []).
 
 new(Transport, Options) ->
-    State  = #binary_protocol{transport = Transport},
+    State = #binary_protocol{transport = Transport},
     State1 = parse_options(Options, State),
     thrift_protocol:new(?MODULE, State1).
 
 parse_options([], State) ->
     State;
 parse_options([{strict_read, Bool} | Rest], State) when is_boolean(Bool) ->
-    parse_options(Rest, State#binary_protocol{strict_read=Bool});
+    parse_options(Rest, State#binary_protocol{strict_read = Bool});
 parse_options([{strict_write, Bool} | Rest], State) when is_boolean(Bool) ->
-    parse_options(Rest, State#binary_protocol{strict_write=Bool}).
-
+    parse_options(Rest, State#binary_protocol{strict_write = Bool}).
 
 flush_transport(This = #binary_protocol{transport = Transport}) ->
     {NewTransport, Result} = thrift_transport:flush(Transport),
@@ -73,9 +72,10 @@
 %%%
 
 write(This0, #protocol_message_begin{
-        name = Name,
-        type = Type,
-        seqid = Seqid}) ->
+    name = Name,
+    type = Type,
+    seqid = Seqid
+}) ->
     case This0#binary_protocol.strict_write of
         true ->
             {This1, ok} = write(This0, {i32, ?VERSION_1 bor Type}),
@@ -88,82 +88,75 @@
             {This3, ok} = write(This2, {i32, Seqid}),
             {This3, ok}
     end;
-
-write(This, message_end) -> {This, ok};
-
+write(This, message_end) ->
+    {This, ok};
 write(This0, #protocol_field_begin{
-       name = _Name,
-       type = Type,
-       id = Id}) ->
+    name = _Name,
+    type = Type,
+    id = Id
+}) ->
     {This1, ok} = write(This0, {byte, Type}),
     {This2, ok} = write(This1, {i16, Id}),
     {This2, ok};
-
 write(This, field_stop) ->
     write(This, {byte, ?tType_STOP});
-
-write(This, field_end) -> {This, ok};
-
+write(This, field_end) ->
+    {This, ok};
 write(This0, #protocol_map_begin{
-       ktype = Ktype,
-       vtype = Vtype,
-       size = Size}) ->
+    ktype = Ktype,
+    vtype = Vtype,
+    size = Size
+}) ->
     {This1, ok} = write(This0, {byte, Ktype}),
     {This2, ok} = write(This1, {byte, Vtype}),
     {This3, ok} = write(This2, {i32, Size}),
     {This3, ok};
-
-write(This, map_end) -> {This, ok};
-
+write(This, map_end) ->
+    {This, ok};
 write(This0, #protocol_list_begin{
-        etype = Etype,
-        size = Size}) ->
+    etype = Etype,
+    size = Size
+}) ->
     {This1, ok} = write(This0, {byte, Etype}),
     {This2, ok} = write(This1, {i32, Size}),
     {This2, ok};
-
-write(This, list_end) -> {This, ok};
-
+write(This, list_end) ->
+    {This, ok};
 write(This0, #protocol_set_begin{
-        etype = Etype,
-        size = Size}) ->
+    etype = Etype,
+    size = Size
+}) ->
     {This1, ok} = write(This0, {byte, Etype}),
     {This2, ok} = write(This1, {i32, Size}),
     {This2, ok};
-
-write(This, set_end) -> {This, ok};
-
-write(This, #protocol_struct_begin{}) -> {This, ok};
-write(This, struct_end) -> {This, ok};
-
-write(This, {bool, true})  -> write(This, {byte, 1});
-write(This, {bool, false}) -> write(This, {byte, 0});
-
+write(This, set_end) ->
+    {This, ok};
+write(This, #protocol_struct_begin{}) ->
+    {This, ok};
+write(This, struct_end) ->
+    {This, ok};
+write(This, {bool, true}) ->
+    write(This, {byte, 1});
+write(This, {bool, false}) ->
+    write(This, {byte, 0});
 write(This, {byte, Byte}) ->
     write(This, <<Byte:8/big-signed>>);
-
 write(This, {i16, I16}) ->
     write(This, <<I16:16/big-signed>>);
-
 write(This, {i32, I32}) ->
     write(This, <<I32:32/big-signed>>);
-
 write(This, {i64, I64}) ->
     write(This, <<I64:64/big-signed>>);
-
 write(This, {double, Double}) ->
     write(This, <<Double:64/big-signed-float>>);
-
 write(This0, {string, Str}) when is_list(Str) ->
     {This1, ok} = write(This0, {i32, length(Str)}),
     {This2, ok} = write(This1, list_to_binary(Str)),
     {This2, ok};
-
 write(This0, {string, Bin}) when is_binary(Bin) ->
     {This1, ok} = write(This0, {i32, size(Bin)}),
     {This2, ok} = write(This1, Bin),
     {This2, ok};
-
 %% Data :: iolist()
 write(This = #binary_protocol{transport = Trans}, Data) ->
     {NewTransport, Result} = thrift_transport:write(Trans, Data),
@@ -176,39 +169,39 @@
     case Initial of
         {ok, Sz} when Sz band ?VERSION_MASK =:= ?VERSION_1 ->
             %% we're at version 1
-            {This2, {ok, Name}}  = read(This1, string),
+            {This2, {ok, Name}} = read(This1, string),
             {This3, {ok, SeqId}} = read(This2, i32),
-            Type                 = Sz band ?TYPE_MASK,
-            {This3, #protocol_message_begin{name  = binary_to_list(Name),
-                                            type  = Type,
-                                            seqid = SeqId}};
-
+            Type = Sz band ?TYPE_MASK,
+            {This3, #protocol_message_begin{
+                name = binary_to_list(Name),
+                type = Type,
+                seqid = SeqId
+            }};
         {ok, Sz} when Sz < 0 ->
             %% there's a version number but it's unexpected
             {This1, {error, {bad_binary_protocol_version, Sz}}};
-
         {ok, _Sz} when This1#binary_protocol.strict_read =:= true ->
             %% strict_read is true and there's no version header; that's an error
             {This1, {error, no_binary_protocol_version}};
-
         {ok, Sz} when This1#binary_protocol.strict_read =:= false ->
             %% strict_read is false, so just read the old way
-            {This2, {ok, Name}}  = read_data(This1, Sz),
-            {This3, {ok, Type}}  = read(This2, byte),
+            {This2, {ok, Name}} = read_data(This1, Sz),
+            {This3, {ok, Type}} = read(This2, byte),
             {This4, {ok, SeqId}} = read(This3, i32),
-            {This4, #protocol_message_begin{name  = binary_to_list(Name),
-                                            type  = Type,
-                                            seqid = SeqId}};
-
+            {This4, #protocol_message_begin{
+                name = binary_to_list(Name),
+                type = Type,
+                seqid = SeqId
+            }};
         Else ->
             {This1, Else}
     end;
-
-read(This, message_end) -> {This, ok};
-
-read(This, struct_begin) -> {This, ok};
-read(This, struct_end) -> {This, ok};
-
+read(This, message_end) ->
+    {This, ok};
+read(This, struct_begin) ->
+    {This, ok};
+read(This, struct_end) ->
+    {This, ok};
 read(This0, field_begin) ->
     {This1, Result} = read(This0, byte),
     case Result of
@@ -216,39 +209,45 @@
             {This1, #protocol_field_begin{type = Type}};
         {ok, Type} ->
             {This2, {ok, Id}} = read(This1, i16),
-            {This2, #protocol_field_begin{type = Type,
-                                          id = Id}}
+            {This2, #protocol_field_begin{
+                type = Type,
+                id = Id
+            }}
     end;
-
-read(This, field_end) -> {This, ok};
-
+read(This, field_end) ->
+    {This, ok};
 read(This0, map_begin) ->
     {This1, {ok, Ktype}} = read(This0, byte),
     {This2, {ok, Vtype}} = read(This1, byte),
-    {This3, {ok, Size}}  = read(This2, i32),
-    {This3, #protocol_map_begin{ktype = Ktype,
-                                vtype = Vtype,
-                                size = Size}};
-read(This, map_end) -> {This, ok};
-
+    {This3, {ok, Size}} = read(This2, i32),
+    {This3, #protocol_map_begin{
+        ktype = Ktype,
+        vtype = Vtype,
+        size = Size
+    }};
+read(This, map_end) ->
+    {This, ok};
 read(This0, list_begin) ->
     {This1, {ok, Etype}} = read(This0, byte),
-    {This2, {ok, Size}}  = read(This1, i32),
-    {This2, #protocol_list_begin{etype = Etype,
-                                 size = Size}};
-read(This, list_end) -> {This, ok};
-
+    {This2, {ok, Size}} = read(This1, i32),
+    {This2, #protocol_list_begin{
+        etype = Etype,
+        size = Size
+    }};
+read(This, list_end) ->
+    {This, ok};
 read(This0, set_begin) ->
     {This1, {ok, Etype}} = read(This0, byte),
-    {This2, {ok, Size}}  = read(This1, i32),
-    {This2, #protocol_set_begin{etype = Etype,
-                                 size = Size}};
-read(This, set_end) -> {This, ok};
-
+    {This2, {ok, Size}} = read(This1, i32),
+    {This2, #protocol_set_begin{
+        etype = Etype,
+        size = Size
+    }};
+read(This, set_end) ->
+    {This, ok};
 read(This0, field_stop) ->
     {This1, {ok, ?tType_STOP}} = read(This0, byte),
     {This1, ok};
-
 %%
 
 read(This0, bool) ->
@@ -257,28 +256,24 @@
         {ok, Byte} -> {This1, {ok, Byte /= 0}};
         Else -> {This1, Else}
     end;
-
 read(This0, byte) ->
     {This1, Bytes} = read_data(This0, 1),
     case Bytes of
         {ok, <<Val:8/integer-signed-big, _/binary>>} -> {This1, {ok, Val}};
         Else -> {This1, Else}
     end;
-
 read(This0, i16) ->
     {This1, Bytes} = read_data(This0, 2),
     case Bytes of
         {ok, <<Val:16/integer-signed-big, _/binary>>} -> {This1, {ok, Val}};
         Else -> {This1, Else}
     end;
-
 read(This0, i32) ->
     {This1, Bytes} = read_data(This0, 4),
     case Bytes of
         {ok, <<Val:32/integer-signed-big, _/binary>>} -> {This1, {ok, Val}};
         Else -> {This1, Else}
     end;
-
 %% unsigned ints aren't used by thrift itself, but it's used for the parsing
 %% of the packet version header. Without this special function BEAM works fine
 %% but hipe thinks it received a bad version header.
@@ -288,60 +283,60 @@
         {ok, <<Val:32/integer-unsigned-big, _/binary>>} -> {This1, {ok, Val}};
         Else -> {This1, Else}
     end;
-
 read(This0, i64) ->
     {This1, Bytes} = read_data(This0, 8),
     case Bytes of
         {ok, <<Val:64/integer-signed-big, _/binary>>} -> {This1, {ok, Val}};
         Else -> {This1, Else}
     end;
-
 read(This0, double) ->
     {This1, Bytes} = read_data(This0, 8),
     case Bytes of
         {ok, <<Val:64/float-signed-big, _/binary>>} -> {This1, {ok, Val}};
         Else -> {This1, Else}
     end;
-
 % returns a binary directly, call binary_to_list if necessary
 read(This0, string) ->
-    {This1, {ok, Sz}}  = read(This0, i32),
+    {This1, {ok, Sz}} = read(This0, i32),
     read_data(This1, Sz).
 
 -spec read_data(#binary_protocol{}, non_neg_integer()) ->
     {#binary_protocol{}, {ok, binary()} | {error, _Reason}}.
-read_data(This, 0) -> {This, {ok, <<>>}};
+read_data(This, 0) ->
+    {This, {ok, <<>>}};
 read_data(This = #binary_protocol{transport = Trans}, Len) when is_integer(Len) andalso Len > 0 ->
     {NewTransport, Result} = thrift_transport:read(Trans, Len),
     {This#binary_protocol{transport = NewTransport}, Result}.
 
-
 %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
--record(tbp_opts, {strict_read = true,
-                   strict_write = true}).
+-record(tbp_opts, {
+    strict_read = true :: boolean(),
+    strict_write = true :: boolean()
+}).
 
 parse_factory_options([], Opts) ->
     Opts;
 parse_factory_options([{strict_read, Bool} | Rest], Opts) when is_boolean(Bool) ->
-    parse_factory_options(Rest, Opts#tbp_opts{strict_read=Bool});
+    parse_factory_options(Rest, Opts#tbp_opts{strict_read = Bool});
 parse_factory_options([{strict_write, Bool} | Rest], Opts) when is_boolean(Bool) ->
-    parse_factory_options(Rest, Opts#tbp_opts{strict_write=Bool}).
-
+    parse_factory_options(Rest, Opts#tbp_opts{strict_write = Bool}).
 
 %% returns a (fun() -> thrift_protocol())
 new_protocol_factory(TransportFactory, Options) ->
     ParsedOpts = parse_factory_options(Options, #tbp_opts{}),
     F = fun() ->
-               case TransportFactory() of
-                    {ok, Transport} ->
-                        thrift_binary_protocol:new(
-                            Transport,
-                            [{strict_read,  ParsedOpts#tbp_opts.strict_read},
-                             {strict_write, ParsedOpts#tbp_opts.strict_write}]);
-                    {error, Error} ->
-                        {error, Error}
-                end
-        end,
+        case TransportFactory() of
+            {ok, Transport} ->
+                thrift_binary_protocol:new(
+                    Transport,
+                    [
+                        {strict_read, ParsedOpts#tbp_opts.strict_read},
+                        {strict_write, ParsedOpts#tbp_opts.strict_write}
+                    ]
+                );
+            {error, Error} ->
+                {error, Error}
+        end
+    end,
     {ok, F}.
-
diff --git a/lib/erl/src/thrift_buffered_transport.erl b/lib/erl/src/thrift_buffered_transport.erl
index e9d3fff..423e89a 100644
--- a/lib/erl/src/thrift_buffered_transport.erl
+++ b/lib/erl/src/thrift_buffered_transport.erl
@@ -28,71 +28,59 @@
 %% legacy api
 -export([new_transport_factory/1]).
 
-
 -record(t_buffered, {
-  wrapped,
-  write_buffer
+    wrapped :: thrift_transport:t_transport(),
+    write_buffer :: iodata()
 }).
 
--type state() :: #t_buffered{}.
-
-
--spec new(Transport::thrift_transport:t_transport()) ->
-  thrift_transport:t_transport().
+-spec new(Transport :: thrift_transport:t_transport()) -> {ok, thrift_transport:t_transport()}.
 
 new(Wrapped) ->
-  State = #t_buffered{
-    wrapped = Wrapped,
-    write_buffer = []
-  },
-  thrift_transport:new(?MODULE, State).
-
-
--include("thrift_transport_behaviour.hrl").
-
+    State = #t_buffered{
+        wrapped = Wrapped,
+        write_buffer = []
+    },
+    thrift_transport:new(?MODULE, State).
 
 %% reads data through from the wrapped transport
-read(State = #t_buffered{wrapped = Wrapped}, Len)
-when is_integer(Len), Len >= 0 ->
-  {NewState, Response} = thrift_transport:read(Wrapped, Len),
-  {State#t_buffered{wrapped = NewState}, Response}.
-
+read(State = #t_buffered{wrapped = Wrapped}, Len) when
+    is_integer(Len), Len >= 0
+->
+    {NewState, Response} = thrift_transport:read(Wrapped, Len),
+    {State#t_buffered{wrapped = NewState}, Response}.
 
 %% reads data through from the wrapped transport
-read_exact(State = #t_buffered{wrapped = Wrapped}, Len)
-when is_integer(Len), Len >= 0 ->
-  {NewState, Response} = thrift_transport:read_exact(Wrapped, Len),
-  {State#t_buffered{wrapped = NewState}, Response}.
-
+read_exact(State = #t_buffered{wrapped = Wrapped}, Len) when
+    is_integer(Len), Len >= 0
+->
+    {NewState, Response} = thrift_transport:read_exact(Wrapped, Len),
+    {State#t_buffered{wrapped = NewState}, Response}.
 
 write(State = #t_buffered{write_buffer = Buffer}, Data) ->
-  {State#t_buffered{write_buffer = [Buffer, Data]}, ok}.
-
+    {State#t_buffered{write_buffer = [Buffer, Data]}, ok}.
 
 flush(State = #t_buffered{wrapped = Wrapped, write_buffer = Buffer}) ->
-  case iolist_size(Buffer) of
-    %% if write buffer is empty, do nothing
-    0 -> {State, ok};
-    _ ->
-      {Written, Response} = thrift_transport:write(Wrapped, Buffer),
-      {Flushed, ok} = thrift_transport:flush(Written),
-      {State#t_buffered{wrapped = Flushed, write_buffer = []}, Response}
-  end.
-
+    case iolist_size(Buffer) of
+        %% if write buffer is empty, do nothing
+        0 ->
+            {State, ok};
+        _ ->
+            {Written, Response} = thrift_transport:write(Wrapped, Buffer),
+            {Flushed, ok} = thrift_transport:flush(Written),
+            {State#t_buffered{wrapped = Flushed, write_buffer = []}, Response}
+    end.
 
 close(State = #t_buffered{wrapped = Wrapped}) ->
-  {Closed, Result} = thrift_transport:close(Wrapped),
-  {State#t_buffered{wrapped = Closed}, Result}.
-
+    {Closed, Result} = thrift_transport:close(Wrapped),
+    {State#t_buffered{wrapped = Closed}, Result}.
 
 %%--------------------------------------------------------------------
 %%% Internal functions
 %%--------------------------------------------------------------------
 %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 new_transport_factory(WrapFactory) ->
-  F = fun() ->
-    {ok, Wrapped} = WrapFactory(),
-    new(Wrapped)
-  end,
-  {ok, F}.
-
+    F = fun() ->
+        {ok, Wrapped} = WrapFactory(),
+        new(Wrapped)
+    end,
+    {ok, F}.
diff --git a/lib/erl/src/thrift_client.erl b/lib/erl/src/thrift_client.erl
index 1a9cb50..1c27405 100644
--- a/lib/erl/src/thrift_client.erl
+++ b/lib/erl/src/thrift_client.erl
@@ -25,78 +25,91 @@
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
--record(tclient, {service, protocol, seqid}).
+-record(tclient, {
+    service :: module(),
+    protocol :: thrift_protocol:state(),
+    seqid :: non_neg_integer()
+}).
+-type tclient() :: #tclient{}.
 
-
-new(Protocol, Service)
-  when is_atom(Service) ->
-    {ok, #tclient{protocol = Protocol,
-                  service = Service,
-                  seqid = 0}}.
+new(Protocol, Service) when
+    is_atom(Service)
+->
+    {ok, #tclient{
+        protocol = Protocol,
+        service = Service,
+        seqid = 0
+    }}.
 
 -spec call(#tclient{}, atom(), list()) -> {#tclient{}, {ok, any()} | {error, any()}}.
-call(Client = #tclient{}, Function, Args)
-when is_atom(Function), is_list(Args) ->
-  case send_function_call(Client, Function, Args) of
-    {ok, Client1} -> receive_function_result(Client1, Function);
-    {{error, X}, Client1} -> {Client1, {error, X}};
-    Else -> Else
-  end.
-
+call(Client = #tclient{}, Function, Args) when
+    is_atom(Function), is_list(Args)
+->
+    case send_function_call(Client, Function, Args) of
+        {ok, Client1} -> receive_function_result(Client1, Function);
+        {{error, X}, Client1} -> {Client1, {error, X}}
+    end.
 
 %% Sends a function call but does not read the result. This is useful
 %% if you're trying to log non-oneway function calls to write-only
 %% transports like thrift_disk_log_transport.
 -spec send_call(#tclient{}, atom(), list()) -> {#tclient{}, ok}.
-send_call(Client = #tclient{}, Function, Args)
-  when is_atom(Function), is_list(Args) ->
+send_call(Client = #tclient{}, Function, Args) when
+    is_atom(Function), is_list(Args)
+->
     case send_function_call(Client, Function, Args) of
-      {ok, Client1} -> {Client1, ok};
-      Else -> Else
+        {ok, Client1} -> {Client1, ok};
+        Else -> Else
     end.
 
 -spec close(#tclient{}) -> ok.
-close(#tclient{protocol=Protocol}) ->
+close(#tclient{protocol = Protocol}) ->
     thrift_protocol:close_transport(Protocol).
 
-
 %%--------------------------------------------------------------------
 %%% Internal functions
 %%--------------------------------------------------------------------
 -spec send_function_call(#tclient{}, atom(), list()) -> {ok | {error, any()}, #tclient{}}.
 send_function_call(Client = #tclient{service = Service}, Function, Args) ->
-  {Params, Reply} = try
-    {Service:function_info(Function, params_type), Service:function_info(Function, reply_type)}
-  catch error:function_clause -> {no_function, 0}
-  end,
-  MsgType = case Reply of
-    oneway_void -> ?tMessageType_ONEWAY;
-    _ -> ?tMessageType_CALL
-  end,
-  case Params of
-    no_function ->
-      {{error, {no_function, Function}}, Client};
-    {struct, PList} when length(PList) =/= length(Args) ->
-      {{error, {bad_args, Function, Args}}, Client};
-    {struct, _PList} -> write_message(Client, Function, Args, Params, MsgType)
-  end.
+    {Params, Reply} =
+        try
+            {
+                Service:function_info(Function, params_type),
+                Service:function_info(Function, reply_type)
+            }
+        catch
+            error:function_clause -> {no_function, 0}
+        end,
+    MsgType =
+        case Reply of
+            oneway_void -> ?tMessageType_ONEWAY;
+            _ -> ?tMessageType_CALL
+        end,
+    case Params of
+        no_function ->
+            {{error, {no_function, Function}}, Client};
+        {struct, PList} when length(PList) =/= length(Args) ->
+            {{error, {bad_args, Function, Args}}, Client};
+        {struct, _PList} ->
+            write_message(Client, Function, Args, Params, MsgType)
+    end.
 
 -spec write_message(#tclient{}, atom(), list(), {struct, list()}, integer()) ->
-  {ok | {error, any()}, #tclient{}}.
+    {ok | {error, any()}, #tclient{}}.
 write_message(Client = #tclient{protocol = P0, seqid = Seq}, Function, Args, Params, MsgType) ->
-  try
-    {P1, ok} = thrift_protocol:write(P0, #protocol_message_begin{
-      name = atom_to_list(Function),
-      type = MsgType,
-      seqid = Seq
-    }),
-    {P2, ok} = thrift_protocol:write(P1, {Params, list_to_tuple([Function|Args])}),
-    {P3, ok} = thrift_protocol:write(P2, message_end),
-    {P4, ok} = thrift_protocol:flush_transport(P3),
-    {ok, Client#tclient{protocol = P4}}
-  catch
-    error:{badmatch, {_, {error, _} = Error}} -> {Error, Client}
-  end.
+    try
+        {P1, ok} = thrift_protocol:write(P0, #protocol_message_begin{
+            name = atom_to_list(Function),
+            type = MsgType,
+            seqid = Seq
+        }),
+        {P2, ok} = thrift_protocol:write(P1, {Params, list_to_tuple([Function | Args])}),
+        {P3, ok} = thrift_protocol:write(P2, message_end),
+        {P4, ok} = thrift_protocol:flush_transport(P3),
+        {ok, Client#tclient{protocol = P4}}
+    catch
+        error:{badmatch, {_, {error, _} = Error}} -> {Error, Client}
+    end.
 
 -spec receive_function_result(#tclient{}, atom()) -> {#tclient{}, {ok, any()} | {error, any()}}.
 receive_function_result(Client = #tclient{service = Service}, Function) ->
@@ -105,32 +118,38 @@
 
 read_result(Client, _Function, oneway_void) ->
     {Client, {ok, ok}};
-
-read_result(Client = #tclient{protocol = Proto0,
-                              seqid    = SeqId},
-            Function,
-            ReplyType) ->
+read_result(
+    Client = #tclient{
+        protocol = Proto0,
+        seqid = SeqId
+    },
+    Function,
+    ReplyType
+) ->
     case thrift_protocol:read(Proto0, message_begin) of
-         {Proto1, {error, Reason}} ->
-             NewClient = Client#tclient{protocol = Proto1},
-             {NewClient, {error, Reason}};
-         {Proto1, MessageBegin} ->
-             NewClient = Client#tclient{protocol = Proto1},
-             case MessageBegin of
-                 #protocol_message_begin{seqid = RetSeqId} when RetSeqId =/= SeqId ->
-                     {NewClient, {error, {bad_seq_id, SeqId}}};
-                 #protocol_message_begin{type = ?tMessageType_EXCEPTION} ->
-                     handle_application_exception(NewClient);
-                 #protocol_message_begin{type = ?tMessageType_REPLY} ->
-                     handle_reply(NewClient, Function, ReplyType)
-             end
+        {Proto1, {error, Reason}} ->
+            NewClient = Client#tclient{protocol = Proto1},
+            {NewClient, {error, Reason}};
+        {Proto1, MessageBegin} ->
+            NewClient = Client#tclient{protocol = Proto1},
+            case MessageBegin of
+                #protocol_message_begin{seqid = RetSeqId} when RetSeqId =/= SeqId ->
+                    {NewClient, {error, {bad_seq_id, SeqId}}};
+                #protocol_message_begin{type = ?tMessageType_EXCEPTION} ->
+                    handle_application_exception(NewClient);
+                #protocol_message_begin{type = ?tMessageType_REPLY} ->
+                    handle_reply(NewClient, Function, ReplyType)
+            end
     end.
 
-
-handle_reply(Client = #tclient{protocol = Proto0,
-                               service = Service},
-             Function,
-             ReplyType) ->
+handle_reply(
+    Client = #tclient{
+        protocol = Proto0,
+        service = Service
+    },
+    Function,
+    ReplyType
+) ->
     {struct, ExceptionFields} = Service:function_info(Function, exceptions),
     ReplyStructDef = {struct, [{0, ReplyType}] ++ ExceptionFields},
     {Proto1, {ok, Reply}} = thrift_protocol:read(Proto0, ReplyStructDef),
@@ -139,8 +158,11 @@
     ReplyList = tuple_to_list(Reply),
     true = length(ReplyList) == length(ExceptionFields) + 1,
     ExceptionVals = tl(ReplyList),
-    Thrown = [X || X <- ExceptionVals,
-                   X =/= undefined],
+    Thrown = [
+        X
+     || X <- ExceptionVals,
+        X =/= undefined
+    ],
     case Thrown of
         [] when ReplyType == {struct, []} ->
             {NewClient, {ok, ok}};
@@ -150,12 +172,14 @@
             throw({NewClient, {exception, Exception}})
     end.
 
+-spec handle_application_exception(tclient()) -> no_return().
 handle_application_exception(Client = #tclient{protocol = Proto0}) ->
     {Proto1, {ok, Exception}} =
         thrift_protocol:read(Proto0, ?TApplicationException_Structure),
     {Proto2, ok} = thrift_protocol:read(Proto1, message_end),
     XRecord = list_to_tuple(
-                ['TApplicationException' | tuple_to_list(Exception)]),
+        ['TApplicationException' | tuple_to_list(Exception)]
+    ),
     error_logger:error_msg("X: ~p~n", [XRecord]),
     true = is_record(XRecord, 'TApplicationException'),
     NewClient = Client#tclient{protocol = Proto2},
diff --git a/lib/erl/src/thrift_client_util.erl b/lib/erl/src/thrift_client_util.erl
index 1dbe51e..7c5f094 100644
--- a/lib/erl/src/thrift_client_util.erl
+++ b/lib/erl/src/thrift_client_util.erl
@@ -22,9 +22,11 @@
 -export([new/4]).
 -export([new_multiplexed/3, new_multiplexed/4]).
 
--type service_name()            :: nonempty_string().
--type service_module()          :: atom().
--type multiplexed_service_map() :: [{ServiceName::service_name(), ServiceModule::service_module()}].
+-type service_name() :: nonempty_string().
+-type service_module() :: atom().
+-type multiplexed_service_map() :: [
+    {ServiceName :: service_name(), ServiceModule :: service_module()}
+].
 
 %%
 %% Splits client options into client, protocol, and transport options
@@ -36,44 +38,47 @@
 
 split_options([], ProtoIn, TransIn) ->
     {ProtoIn, TransIn};
-
-split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn)
-  when OptKey =:= strict_read;
-       OptKey =:= strict_write;
-       OptKey =:= protocol ->
+split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn) when
+    OptKey =:= strict_read;
+    OptKey =:= strict_write;
+    OptKey =:= protocol
+->
     split_options(Rest, [Opt | ProtoIn], TransIn);
-
-split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn)
-  when OptKey =:= framed;
-       OptKey =:= connect_timeout;
-       OptKey =:= recv_timeout;
-       OptKey =:= sockopts;
-       OptKey =:= ssltransport;
-       OptKey =:= ssloptions->
+split_options([Opt = {OptKey, _} | Rest], ProtoIn, TransIn) when
+    OptKey =:= framed;
+    OptKey =:= connect_timeout;
+    OptKey =:= recv_timeout;
+    OptKey =:= sockopts;
+    OptKey =:= ssltransport;
+    OptKey =:= ssloptions
+->
     split_options(Rest, ProtoIn, [Opt | TransIn]).
 
-
 %% Client constructor for the common-case of socket transports
-new(Host, Port, Service, Options)
-  when is_integer(Port), is_atom(Service), is_list(Options) ->
+new(Host, Port, Service, Options) when
+    is_integer(Port), is_atom(Service), is_list(Options)
+->
     {ProtoOpts, TransOpts0} = split_options(Options),
 
-    {TransportModule, TransOpts2} = case lists:keytake(ssltransport, 1, TransOpts0) of
-                                        {value, {_, true}, TransOpts1} -> {thrift_sslsocket_transport, TransOpts1};
-                                        false -> {thrift_socket_transport, TransOpts0}
-                                    end,
+    {TransportModule, TransOpts2} =
+        case lists:keytake(ssltransport, 1, TransOpts0) of
+            {value, {_, true}, TransOpts1} -> {thrift_sslsocket_transport, TransOpts1};
+            false -> {thrift_socket_transport, TransOpts0}
+        end,
 
-    {ProtocolModule, ProtoOpts1} = case lists:keytake(protocol, 1, ProtoOpts) of
-                                     {value, {_, compact}, Opts} -> {thrift_compact_protocol, Opts};
-                                     {value, {_, json}, Opts} -> {thrift_json_protocol, Opts};
-                                     {value, {_, binary}, Opts} -> {thrift_binary_protocol, Opts};
-                                     false -> {thrift_binary_protocol, ProtoOpts}
-                                   end,
+    {ProtocolModule, ProtoOpts1} =
+        case lists:keytake(protocol, 1, ProtoOpts) of
+            {value, {_, compact}, Opts} -> {thrift_compact_protocol, Opts};
+            {value, {_, json}, Opts} -> {thrift_json_protocol, Opts};
+            {value, {_, binary}, Opts} -> {thrift_binary_protocol, Opts};
+            false -> {thrift_binary_protocol, ProtoOpts}
+        end,
     {ok, TransportFactory} =
         TransportModule:new_transport_factory(Host, Port, TransOpts2),
 
     {ok, ProtocolFactory} = ProtocolModule:new_protocol_factory(
-                              TransportFactory, ProtoOpts1),
+        TransportFactory, ProtoOpts1
+    ),
 
     case ProtocolFactory() of
         {ok, Protocol} ->
@@ -83,30 +88,49 @@
     end.
 
 -spec new_multiplexed(Host, Port, Services, Options) -> {ok, ServiceThriftClientList} when
-    Host        :: nonempty_string(),
-    Port        :: non_neg_integer(),
-    Services    :: multiplexed_service_map(),
-    Options     :: list(),
-    ServiceThriftClientList :: [{ServiceName::list(), ThriftClient::term()}].
-new_multiplexed(Host, Port, Services, Options) when is_integer(Port),
-                                                    is_list(Services),
-                                                    is_list(Options) ->
-    new_multiplexed(thrift_socket_transport:new_transport_factory(Host, Port, Options), Services, Options).
+    Host :: nonempty_string(),
+    Port :: non_neg_integer(),
+    Services :: multiplexed_service_map(),
+    Options :: list(),
+    ServiceThriftClientList :: [{ServiceName :: list(), ThriftClient :: term()}].
+new_multiplexed(Host, Port, Services, Options) when
+    is_integer(Port),
+    is_list(Services),
+    is_list(Options)
+->
+    new_multiplexed(
+        thrift_socket_transport:new_transport_factory(Host, Port, Options), Services, Options
+    ).
 
--spec new_multiplexed(TransportFactoryTuple, Services, Options) -> {ok, ServiceThriftClientList} when
-    TransportFactoryTuple   :: {ok, TransportFactory::term()},
-    Services                :: multiplexed_service_map(),
-    Options                 :: list(),
-    ServiceThriftClientList :: [{ServiceName::service_name(), ThriftClient::term()}].
-new_multiplexed(TransportFactoryTuple, Services, Options) when is_list(Services),
-                                                               is_list(Options),
-                                                               is_tuple(TransportFactoryTuple) ->
+-spec new_multiplexed(TransportFactoryTuple, Services, Options) ->
+    {ok, ServiceThriftClientList}
+when
+    TransportFactoryTuple :: {ok, TransportFactory :: term()},
+    Services :: multiplexed_service_map(),
+    Options :: list(),
+    ServiceThriftClientList :: [{ServiceName :: service_name(), ThriftClient :: term()}].
+new_multiplexed(TransportFactoryTuple, Services, Options) when
+    is_list(Services),
+    is_list(Options),
+    is_tuple(TransportFactoryTuple)
+->
     {ProtoOpts, _} = split_options(Options),
 
     {ok, TransportFactory} = TransportFactoryTuple,
 
-    {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(TransportFactory, ProtoOpts),
+    {ok, ProtocolFactory} = thrift_binary_protocol:new_protocol_factory(
+        TransportFactory, ProtoOpts
+    ),
 
     {ok, Protocol} = ProtocolFactory(),
 
-    {ok, [{ServiceName, element(2, thrift_client:new(element(2, thrift_multiplexed_protocol:new(Protocol, ServiceName)), Service))} || {ServiceName, Service} <- Services]}.
+    {ok, [
+        {ServiceName,
+            element(
+                2,
+                thrift_client:new(
+                    element(2, thrift_multiplexed_protocol:new(Protocol, ServiceName)), Service
+                )
+            )}
+     || {ServiceName, Service} <- Services
+    ]}.
diff --git a/lib/erl/src/thrift_compact_protocol.erl b/lib/erl/src/thrift_compact_protocol.erl
index 0f14221..f852fcb 100644
--- a/lib/erl/src/thrift_compact_protocol.erl
+++ b/lib/erl/src/thrift_compact_protocol.erl
@@ -24,28 +24,32 @@
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
--export([new/1, new/2,
-         read/2,
-         write/2,
-         flush_transport/1,
-         close_transport/1,
-         new_protocol_factory/2
-        ]).
+-export([
+    new/1, new/2,
+    read/2,
+    write/2,
+    flush_transport/1,
+    close_transport/1,
+    new_protocol_factory/2
+]).
 
 -define(ID_NONE, 16#10000).
 -define(CBOOL_NONE, 0).
 -define(CBOOL_TRUE, 1).
 -define(CBOOL_FALSE, 2).
 
--record(t_compact, {transport,
-                           % state for pending boolean fields
-                           read_stack=[],
-                           read_value=?CBOOL_NONE,
-                           write_stack=[],
-                           write_id=?ID_NONE
-                          }).
--type state() :: #t_compact{}.
--include("thrift_protocol_behaviour.hrl").
+-type cbool() :: ?CBOOL_NONE | ?CBOOL_TRUE | ?CBOOL_FALSE.
+
+-record(t_compact, {
+    transport :: term(),
+    % state for pending boolean fields
+    read_stack = [] :: iodata(),
+    read_value = ?CBOOL_NONE :: cbool(),
+    write_stack = [] :: iodata(),
+    write_id = ?ID_NONE :: non_neg_integer()
+}).
+
+-type t_compact() :: #t_compact{}.
 
 -define(PROTOCOL_ID, 16#82).
 -define(VERSION_MASK, 16#1f).
@@ -67,19 +71,19 @@
 typeid_to_compact(?tType_SET) -> 16#A;
 typeid_to_compact(?tType_LIST) -> 16#9.
 
-compact_to_typeid(16#0) ->  ?tType_STOP;
-compact_to_typeid(?CBOOL_FALSE) ->  ?tType_BOOL;
-compact_to_typeid(?CBOOL_TRUE) ->  ?tType_BOOL;
-compact_to_typeid(16#7) ->  ?tType_DOUBLE;
-compact_to_typeid(16#3) ->  ?tType_I8;
-compact_to_typeid(16#4) ->  ?tType_I16;
-compact_to_typeid(16#5) ->  ?tType_I32;
-compact_to_typeid(16#6) ->  ?tType_I64;
-compact_to_typeid(16#8) ->  ?tType_STRING;
-compact_to_typeid(16#C) ->  ?tType_STRUCT;
-compact_to_typeid(16#B) ->  ?tType_MAP;
-compact_to_typeid(16#A) ->  ?tType_SET;
-compact_to_typeid(16#9) ->  ?tType_LIST.
+compact_to_typeid(16#0) -> ?tType_STOP;
+compact_to_typeid(?CBOOL_FALSE) -> ?tType_BOOL;
+compact_to_typeid(?CBOOL_TRUE) -> ?tType_BOOL;
+compact_to_typeid(16#7) -> ?tType_DOUBLE;
+compact_to_typeid(16#3) -> ?tType_I8;
+compact_to_typeid(16#4) -> ?tType_I16;
+compact_to_typeid(16#5) -> ?tType_I32;
+compact_to_typeid(16#6) -> ?tType_I64;
+compact_to_typeid(16#8) -> ?tType_STRING;
+compact_to_typeid(16#C) -> ?tType_STRUCT;
+compact_to_typeid(16#B) -> ?tType_MAP;
+compact_to_typeid(16#A) -> ?tType_SET;
+compact_to_typeid(16#9) -> ?tType_LIST.
 
 bool_to_cbool(Value) when Value -> ?CBOOL_TRUE;
 bool_to_cbool(_) -> ?CBOOL_FALSE.
@@ -88,30 +92,31 @@
 new(Transport) -> new(Transport, _Options = []).
 
 new(Transport, _Options) ->
-  State  = #t_compact{transport = Transport},
-  thrift_protocol:new(?MODULE, State).
+    State = #t_compact{transport = Transport},
+    thrift_protocol:new(?MODULE, State).
 
 flush_transport(This = #t_compact{transport = Transport}) ->
-  {NewTransport, Result} = thrift_transport:flush(Transport),
-  {This#t_compact{transport = NewTransport}, Result}.
+    {NewTransport, Result} = thrift_transport:flush(Transport),
+    {This#t_compact{transport = NewTransport}, Result}.
 
 close_transport(This = #t_compact{transport = Transport}) ->
-  {NewTransport, Result} = thrift_transport:close(Transport),
-  {This#t_compact{transport = NewTransport}, Result}.
+    {NewTransport, Result} = thrift_transport:close(Transport),
+    {This#t_compact{transport = NewTransport}, Result}.
 
 %%%
 %%% instance methods
 %%%
 
-write_field_begin(This0 = #t_compact{write_stack=[LastId|T]}, CompactType, Id) ->
-  IdDiff = Id - LastId,
-  This1 = This0#t_compact{write_stack=[Id|T]},
-  case (IdDiff > 0) and (IdDiff < 16) of
-    true -> write(This1, {byte, (IdDiff bsl 4) bor CompactType});
-    false ->
-      {This2, ok} = write(This1, {byte, CompactType}),
-      write(This2, {i16, Id})
-  end.
+write_field_begin(This0 = #t_compact{write_stack = [LastId | T]}, CompactType, Id) ->
+    IdDiff = Id - LastId,
+    This1 = This0#t_compact{write_stack = [Id | T]},
+    case (IdDiff > 0) and (IdDiff < 16) of
+        true ->
+            write(This1, {byte, (IdDiff bsl 4) bor CompactType});
+        false ->
+            {This2, ok} = write(This1, {byte, CompactType}),
+            write(This2, {i16, Id})
+    end.
 
 -spec to_zigzag(integer()) -> non_neg_integer().
 to_zigzag(Value) -> 16#FFFFFFFFFFFFFFFF band ((Value bsl 1) bxor (Value bsr 63)).
@@ -121,270 +126,270 @@
 
 -spec to_varint(non_neg_integer(), iolist()) -> iolist().
 to_varint(Value, Acc) when (Value < 16#80) -> [Acc, Value];
-to_varint(Value, Acc) ->
-  to_varint(Value bsr 7, [Acc, ((Value band 16#7F) bor 16#80)]).
+to_varint(Value, Acc) -> to_varint(Value bsr 7, [Acc, ((Value band 16#7F) bor 16#80)]).
 
--spec read_varint(#t_compact{}, non_neg_integer(), non_neg_integer()) -> non_neg_integer().
+-spec read_varint(t_compact(), non_neg_integer(), non_neg_integer()) ->
+    {t_compact(), {'ok', integer()}}.
 read_varint(This0, Acc, Count) ->
-  {This1, {ok, Byte}} = read(This0, byte),
-  case (Byte band 16#80) of
-    0 -> {This1, {ok, (Byte bsl (7 * Count)) + Acc}};
-    _ -> read_varint(This1, ((Byte band 16#7f) bsl (7 * Count)) + Acc, Count + 1)
-  end.
+    {This1, {ok, Byte}} = read(This0, byte),
+    case (Byte band 16#80) of
+        0 -> {This1, {ok, (Byte bsl (7 * Count)) + Acc}};
+        _ -> read_varint(This1, ((Byte band 16#7f) bsl (7 * Count)) + Acc, Count + 1)
+    end.
 
 write(This0, #protocol_message_begin{
-        name = Name,
-        type = Type,
-        seqid = Seqid}) ->
-  {This1, ok} = write(This0, {byte, ?PROTOCOL_ID}),
-  {This2, ok} = write(This1, {byte, (?VERSION_1 band ?VERSION_MASK) bor (Type bsl ?TYPE_SHIFT_AMOUNT)}),
-  {This3, ok} = write(This2, {ui32, Seqid}),
-  {This4, ok} = write(This3, {string, Name}),
-  {This4, ok};
-
-write(This, message_end) -> {This, ok};
-
+    name = Name,
+    type = Type,
+    seqid = Seqid
+}) ->
+    {This1, ok} = write(This0, {byte, ?PROTOCOL_ID}),
+    {This2, ok} = write(
+        This1, {byte, (?VERSION_1 band ?VERSION_MASK) bor (Type bsl ?TYPE_SHIFT_AMOUNT)}
+    ),
+    {This3, ok} = write(This2, {ui32, Seqid}),
+    {This4, ok} = write(This3, {string, Name}),
+    {This4, ok};
+write(This, message_end) ->
+    {This, ok};
 write(This0, #protocol_field_begin{
-       name = _Name,
-       type = Type,
-       id = Id})
-when (Type =:= ?tType_BOOL) -> {This0#t_compact{write_id = Id}, ok};
-
+    name = _Name,
+    type = Type,
+    id = Id
+}) when
+    (Type =:= ?tType_BOOL)
+->
+    {This0#t_compact{write_id = Id}, ok};
 write(This0, #protocol_field_begin{
-       name = _Name,
-       type = Type,
-       id = Id}) ->
-  write_field_begin(This0, typeid_to_compact(Type), Id);
-
-write(This, field_stop) -> write(This, {byte, ?tType_STOP});
-
-write(This, field_end) -> {This, ok};
-
+    name = _Name,
+    type = Type,
+    id = Id
+}) ->
+    write_field_begin(This0, typeid_to_compact(Type), Id);
+write(This, field_stop) ->
+    write(This, {byte, ?tType_STOP});
+write(This, field_end) ->
+    {This, ok};
 write(This0, #protocol_map_begin{
-      ktype = _Ktype,
-      vtype = _Vtype,
-      size = Size})
-when Size =:= 0 ->
-  write(This0, {byte, 0});
-
+    ktype = _Ktype,
+    vtype = _Vtype,
+    size = Size
+}) when
+    Size =:= 0
+->
+    write(This0, {byte, 0});
 write(This0, #protocol_map_begin{
-       ktype = Ktype,
-       vtype = Vtype,
-       size = Size}) ->
-  {This1, ok} = write(This0, {ui32, Size}),
-  write(This1, {byte, (typeid_to_compact(Ktype) bsl 4) bor typeid_to_compact(Vtype)});
-
-write(This, map_end) -> {This, ok};
-
+    ktype = Ktype,
+    vtype = Vtype,
+    size = Size
+}) ->
+    {This1, ok} = write(This0, {ui32, Size}),
+    write(This1, {byte, (typeid_to_compact(Ktype) bsl 4) bor typeid_to_compact(Vtype)});
+write(This, map_end) ->
+    {This, ok};
 write(This0, #protocol_list_begin{
-        etype = Etype,
-        size = Size})
-when Size < 16#f ->
-  write(This0, {byte, (Size bsl 4) bor typeid_to_compact(Etype)});
-
+    etype = Etype,
+    size = Size
+}) when
+    Size < 16#f
+->
+    write(This0, {byte, (Size bsl 4) bor typeid_to_compact(Etype)});
 write(This0, #protocol_list_begin{
-        etype = Etype,
-        size = Size}) ->
-  {This1, ok} = write(This0, {byte, 16#f0 bor typeid_to_compact(Etype)}),
-  write(This1, {ui32, Size});
-
-write(This, list_end) -> {This, ok};
-
+    etype = Etype,
+    size = Size
+}) ->
+    {This1, ok} = write(This0, {byte, 16#f0 bor typeid_to_compact(Etype)}),
+    write(This1, {ui32, Size});
+write(This, list_end) ->
+    {This, ok};
 write(This0, #protocol_set_begin{
-        etype = Etype,
-        size = Size}) ->
-  write(This0, #protocol_list_begin{etype = Etype, size =  Size});
-
-write(This, set_end) -> {This, ok};
-
+    etype = Etype,
+    size = Size
+}) ->
+    write(This0, #protocol_list_begin{etype = Etype, size = Size});
+write(This, set_end) ->
+    {This, ok};
 write(This = #t_compact{write_stack = Stack}, #protocol_struct_begin{}) ->
-  {This#t_compact{write_stack = [0|Stack]}, ok};
-write(This = #t_compact{write_stack = [_|T]}, struct_end) ->
-  {This#t_compact{write_stack = T}, ok};
-
+    {This#t_compact{write_stack = [0 | Stack]}, ok};
+write(This = #t_compact{write_stack = [_ | T]}, struct_end) ->
+    {This#t_compact{write_stack = T}, ok};
 write(This = #t_compact{write_id = ?ID_NONE}, {bool, Value}) ->
-  write(This, {byte, bool_to_cbool(Value)});
-
+    write(This, {byte, bool_to_cbool(Value)});
 write(This0 = #t_compact{write_id = Id}, {bool, Value}) ->
-  {This1, ok} = write_field_begin(This0, bool_to_cbool(Value), Id),
-  {This1#t_compact{write_id = ?ID_NONE}, ok};
-
+    {This1, ok} = write_field_begin(This0, bool_to_cbool(Value), Id),
+    {This1#t_compact{write_id = ?ID_NONE}, ok};
 write(This, {byte, Value}) when is_integer(Value) ->
-  write(This, <<Value:8/big-signed>>);
-
+    write(This, <<Value:8/big-signed>>);
 write(This, {i16, Value}) when is_integer(Value) -> write(This, to_varint(to_zigzag(Value), []));
 write(This, {ui32, Value}) when is_integer(Value) -> write(This, to_varint(Value, []));
 write(This, {i32, Value}) when is_integer(Value) ->
-  write(This, to_varint(to_zigzag(Value), []));
+    write(This, to_varint(to_zigzag(Value), []));
 write(This, {i64, Value}) when is_integer(Value) -> write(This, to_varint(to_zigzag(Value), []));
-
 write(This, {double, Double}) ->
-  write(This, <<Double:64/float-signed-little>>);
-
+    write(This, <<Double:64/float-signed-little>>);
 write(This0, {string, Str}) when is_list(Str) ->
-  % TODO: limit length
-  {This1, ok} = write(This0, {ui32, length(Str)}),
-  {This2, ok} = write(This1, list_to_binary(Str)),
-  {This2, ok};
-
+    % TODO: limit length
+    {This1, ok} = write(This0, {ui32, length(Str)}),
+    {This2, ok} = write(This1, list_to_binary(Str)),
+    {This2, ok};
 write(This0, {string, Bin}) when is_binary(Bin) ->
-  % TODO: limit length
-  {This1, ok} = write(This0, {ui32, size(Bin)}),
-  {This2, ok} = write(This1, Bin),
-  {This2, ok};
-
+    % TODO: limit length
+    {This1, ok} = write(This0, {ui32, size(Bin)}),
+    {This2, ok} = write(This1, Bin),
+    {This2, ok};
 %% Data :: iolist()
 write(This = #t_compact{transport = Trans}, Data) ->
-  {NewTransport, Result} = thrift_transport:write(Trans, Data),
-  {This#t_compact{transport = NewTransport}, Result}.
+    {NewTransport, Result} = thrift_transport:write(Trans, Data),
+    {This#t_compact{transport = NewTransport}, Result}.
 
 %%
 %%
 
 read(This0, message_begin) ->
-  {This1, {ok, ?PROTOCOL_ID}} = read(This0, ubyte),
-  {This2, {ok, VerAndType}} = read(This1, ubyte),
-  ?VERSION_1 = VerAndType band ?VERSION_MASK,
-  {This3, {ok, SeqId}} = read(This2, ui32),
-  {This4, {ok, Name}} = read(This3, string),
-  {This4, #protocol_message_begin{
-             name  = binary_to_list(Name),
-             type  = (VerAndType bsr ?TYPE_SHIFT_AMOUNT) band ?TYPE_BITS,
-             seqid = SeqId}};
-
-read(This, message_end) -> {This, ok};
-
+    {This1, {ok, ?PROTOCOL_ID}} = read(This0, ubyte),
+    {This2, {ok, VerAndType}} = read(This1, ubyte),
+    ?VERSION_1 = VerAndType band ?VERSION_MASK,
+    {This3, {ok, SeqId}} = read(This2, ui32),
+    {This4, {ok, Name}} = read(This3, string),
+    {This4, #protocol_message_begin{
+        name = binary_to_list(Name),
+        type = (VerAndType bsr ?TYPE_SHIFT_AMOUNT) band ?TYPE_BITS,
+        seqid = SeqId
+    }};
+read(This, message_end) ->
+    {This, ok};
 read(This = #t_compact{read_stack = Stack}, struct_begin) ->
-  {This#t_compact{read_stack = [0|Stack]}, ok};
-read(This = #t_compact{read_stack = [_H|T]}, struct_end) ->
-  {This#t_compact{read_stack = T}, ok};
-
-read(This0 = #t_compact{read_stack = [LastId|T]}, field_begin) ->
-  {This1, {ok, Byte}} = read(This0, ubyte),
-  case Byte band 16#f of
-    CompactType = ?tType_STOP ->
-      {This1, #protocol_field_begin{type = CompactType}};
-    CompactType ->
-      {This2, {ok, Id}} = case Byte bsr 4 of
-                            0 -> read(This1, i16);
-                            IdDiff ->
-                              {This1, {ok, LastId + IdDiff}}
-                          end,
-      case compact_to_typeid(CompactType) of
-        ?tType_BOOL ->
-          {This2#t_compact{read_stack = [Id|T], read_value = cbool_to_bool(CompactType)},
-           #protocol_field_begin{type = ?tType_BOOL, id = Id}};
-        Type ->
-          {This2#t_compact{read_stack = [Id|T]},
-           #protocol_field_begin{type = Type, id = Id}}
-      end
-  end;
-
-read(This, field_end) -> {This, ok};
-
+    {This#t_compact{read_stack = [0 | Stack]}, ok};
+read(This = #t_compact{read_stack = [_H | T]}, struct_end) ->
+    {This#t_compact{read_stack = T}, ok};
+read(This0 = #t_compact{read_stack = [LastId | T]}, field_begin) ->
+    {This1, {ok, Byte}} = read(This0, ubyte),
+    case Byte band 16#f of
+        CompactType = ?tType_STOP ->
+            {This1, #protocol_field_begin{type = CompactType}};
+        CompactType ->
+            {This2, {ok, Id}} =
+                case Byte bsr 4 of
+                    0 -> read(This1, i16);
+                    IdDiff -> {This1, {ok, LastId + IdDiff}}
+                end,
+            case compact_to_typeid(CompactType) of
+                ?tType_BOOL ->
+                    {
+                        This2#t_compact{
+                            read_stack = [Id | T], read_value = CompactType
+                        },
+                        #protocol_field_begin{type = ?tType_BOOL, id = Id}
+                    };
+                Type ->
+                    {This2#t_compact{read_stack = [Id | T]}, #protocol_field_begin{
+                        type = Type, id = Id
+                    }}
+            end
+    end;
+read(This, field_end) ->
+    {This, ok};
 read(This0, map_begin) ->
-  {This1, {ok, Size}}  = read(This0, ui32),
-  {This2, {ok, KV}} = case Size of
-                        0 -> {This1, {ok, 0}};
-                        _ -> read(This1, ubyte)
-                      end,
-  {This2, #protocol_map_begin{ktype = compact_to_typeid(KV bsr 4),
-                              vtype = compact_to_typeid(KV band 16#f),
-                              size = Size}};
-read(This, map_end) -> {This, ok};
-
+    {This1, {ok, Size}} = read(This0, ui32),
+    {This2, {ok, KV}} =
+        case Size of
+            0 -> {This1, {ok, 0}};
+            _ -> read(This1, ubyte)
+        end,
+    {This2, #protocol_map_begin{
+        ktype = compact_to_typeid(KV bsr 4),
+        vtype = compact_to_typeid(KV band 16#f),
+        size = Size
+    }};
+read(This, map_end) ->
+    {This, ok};
 read(This0, list_begin) ->
-  {This1, {ok, SizeAndType}} = read(This0, ubyte),
-  {This2, {ok, Size}} = case (SizeAndType bsr 4) band 16#f of
-                          16#f -> read(This1, ui32);
-                          Else -> {This1, {ok, Else}}
-                        end,
-  {This2, #protocol_list_begin{etype = compact_to_typeid(SizeAndType band 16#f),
-                               size = Size}};
-
-read(This, list_end) -> {This, ok};
-
+    {This1, {ok, SizeAndType}} = read(This0, ubyte),
+    {This2, {ok, Size}} =
+        case (SizeAndType bsr 4) band 16#f of
+            16#f -> read(This1, ui32);
+            Else -> {This1, {ok, Else}}
+        end,
+    {This2, #protocol_list_begin{
+        etype = compact_to_typeid(SizeAndType band 16#f),
+        size = Size
+    }};
+read(This, list_end) ->
+    {This, ok};
 read(This0, set_begin) ->
-  {This1, {ok, SizeAndType}} = read(This0, ubyte),
-  {This2, {ok, Size}} = case (SizeAndType bsr 4) band 16#f of
-                          16#f -> read(This1, ui32);
-                          Else -> {This1, {ok, Else}}
-                        end,
-  {This2, #protocol_set_begin{etype = compact_to_typeid(SizeAndType band 16#f),
-                               size = Size}};
-
-read(This, set_end) -> {This, ok};
-
+    {This1, {ok, SizeAndType}} = read(This0, ubyte),
+    {This2, {ok, Size}} =
+        case (SizeAndType bsr 4) band 16#f of
+            16#f -> read(This1, ui32);
+            Else -> {This1, {ok, Else}}
+        end,
+    {This2, #protocol_set_begin{
+        etype = compact_to_typeid(SizeAndType band 16#f),
+        size = Size
+    }};
+read(This, set_end) ->
+    {This, ok};
 read(This0, field_stop) ->
-  {This1, {ok, ?tType_STOP}} = read(This0, ubyte),
-  {This1, ok};
-
+    {This1, {ok, ?tType_STOP}} = read(This0, ubyte),
+    {This1, ok};
 %%
 
 read(This0 = #t_compact{read_value = ?CBOOL_NONE}, bool) ->
-  {This1, {ok, Byte}} = read(This0, ubyte),
-  {This1, {ok, cbool_to_bool(Byte)}};
-
+    {This1, {ok, Byte}} = read(This0, ubyte),
+    {This1, {ok, cbool_to_bool(Byte)}};
 read(This0 = #t_compact{read_value = Bool}, bool) ->
-  {This0#t_compact{read_value = ?CBOOL_NONE}, {ok, Bool}};
-
+    {This0#t_compact{read_value = ?CBOOL_NONE}, {ok, cbool_to_bool(Bool)}};
 read(This0, ubyte) ->
-  {This1, {ok, <<Val:8/integer-unsigned-big, _/binary>>}} = read_data(This0, 1),
-  {This1, {ok, Val}};
-
+    {This1, {ok, <<Val:8/integer-unsigned-big, _/binary>>}} = read_data(This0, 1),
+    {This1, {ok, Val}};
 read(This0, byte) ->
-  {This1, Bytes} = read_data(This0, 1),
-  case Bytes of
-    {ok, <<Val:8/integer-signed-big, _/binary>>} -> {This1, {ok, Val}};
-    Else -> {This1, Else}
-  end;
-
+    {This1, Bytes} = read_data(This0, 1),
+    case Bytes of
+        {ok, <<Val:8/integer-signed-big, _/binary>>} -> {This1, {ok, Val}};
+        Else -> {This1, Else}
+    end;
 read(This0, i16) ->
-  {This1, {ok, Zigzag}} = read_varint(This0, 0, 0),
-  {This1, {ok, from_zigzag(Zigzag)}};
-
-read(This0, ui32) -> read_varint(This0, 0, 0);
-
+    {This1, {ok, Zigzag}} = read_varint(This0, 0, 0),
+    {This1, {ok, from_zigzag(Zigzag)}};
+read(This0, ui32) ->
+    read_varint(This0, 0, 0);
 read(This0, i32) ->
-  {This1, {ok, Zigzag}} = read_varint(This0, 0, 0),
-  {This1, {ok, from_zigzag(Zigzag)}};
-
+    {This1, {ok, Zigzag}} = read_varint(This0, 0, 0),
+    {This1, {ok, from_zigzag(Zigzag)}};
 read(This0, i64) ->
-  {This1, {ok, Zigzag}} = read_varint(This0, 0, 0),
-  {This1, {ok, from_zigzag(Zigzag)}};
-
+    {This1, {ok, Zigzag}} = read_varint(This0, 0, 0),
+    {This1, {ok, from_zigzag(Zigzag)}};
 read(This0, double) ->
-  {This1, Bytes} = read_data(This0, 8),
-  case Bytes of
-    {ok, <<Val:64/float-signed-little, _/binary>>} -> {This1, {ok, Val}};
-    Else -> {This1, Else}
-  end;
-
+    {This1, Bytes} = read_data(This0, 8),
+    case Bytes of
+        {ok, <<Val:64/float-signed-little, _/binary>>} -> {This1, {ok, Val}};
+        Else -> {This1, Else}
+    end;
 % returns a binary directly, call binary_to_list if necessary
 read(This0, string) ->
-  {This1, {ok, Sz}}  = read(This0, ui32),
-  read_data(This1, Sz).
+    {This1, {ok, Sz}} = read(This0, ui32),
+    read_data(This1, Sz).
 
 -spec read_data(#t_compact{}, non_neg_integer()) ->
     {#t_compact{}, {ok, binary()} | {error, _Reason}}.
-read_data(This, 0) -> {This, {ok, <<>>}};
+read_data(This, 0) ->
+    {This, {ok, <<>>}};
 read_data(This = #t_compact{transport = Trans}, Len) when is_integer(Len) andalso Len > 0 ->
     {NewTransport, Result} = thrift_transport:read(Trans, Len),
     {This#t_compact{transport = NewTransport}, Result}.
 
-
 %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %% returns a (fun() -> thrift_protocol())
 new_protocol_factory(TransportFactory, _Options) ->
-  F = fun() ->
-          case TransportFactory() of
+    F = fun() ->
+        case TransportFactory() of
             {ok, Transport} ->
-              thrift_compact_protocol:new(
-                Transport,
-                []);
+                thrift_compact_protocol:new(
+                    Transport,
+                    []
+                );
             {error, Error} ->
-              {error, Error}
-          end
-      end,
-  {ok, F}.
+                {error, Error}
+        end
+    end,
+    {ok, F}.
diff --git a/lib/erl/src/thrift_disk_log_transport.erl b/lib/erl/src/thrift_disk_log_transport.erl
index de8ee41..733d88f 100644
--- a/lib/erl/src/thrift_disk_log_transport.erl
+++ b/lib/erl/src/thrift_disk_log_transport.erl
@@ -31,13 +31,13 @@
 -export([read/2, write/2, force_flush/1, flush/1, close/1]).
 
 %% state
--record(dl_transport, {log,
-                       close_on_close = false,
-                       sync_every = infinity,
-                       sync_tref}).
--type state() :: #dl_transport{}.
--include("thrift_transport_behaviour.hrl").
-
+-record(dl_transport, {
+    %% Keep in sync with disk_log:log/0 type
+    log :: term(),
+    close_on_close = false :: boolean(),
+    sync_every = infinity :: undefined | timeout(),
+    sync_tref :: undefined | timer:tref()
+}).
 
 %% Create a transport attached to an already open log.
 %% If you'd like this transport to close the disk_log using disk_log:lclose()
@@ -51,12 +51,12 @@
             N when is_integer(N), N > 0 ->
                 {ok, TRef} = timer:apply_interval(N, ?MODULE, force_flush, [State]),
                 State#dl_transport{sync_tref = TRef};
-            _ -> State
+            _ ->
+                State
         end,
 
     thrift_transport:new(?MODULE, State2).
 
-
 parse_opts([], State) ->
     State;
 parse_opts([{close_on_close, Bool} | Rest], State) when is_boolean(Bool) ->
@@ -64,7 +64,6 @@
 parse_opts([{sync_every, Int} | Rest], State) when is_integer(Int), Int > 0 ->
     parse_opts(Rest, State#dl_transport{sync_every = Int}).
 
-
 %%%% TRANSPORT IMPLENTATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 %% disk_log_transport is write-only
@@ -80,38 +79,40 @@
 
 flush(This = #dl_transport{log = Log, sync_every = SE}) ->
     case SE of
-        undefined -> % no time-based sync
-            disk_log:sync(Log);
-        _Else ->     % sync will happen automagically
+        % no time-based sync
+        undefined ->
+            ok = disk_log:sync(Log);
+        % sync will happen automagically
+        _Else ->
             ok
     end,
     {This, ok}.
 
-
-
-
 %% On close, close the underlying log if we're configured to do so.
 close(This = #dl_transport{close_on_close = false}) ->
     {This, ok};
 close(This = #dl_transport{log = Log}) ->
-    {This, disk_log:lclose(Log)}.
-
+    {This, disk_log:close(Log)}.
 
 %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 new_transport_factory(Name, ExtraLogOpts) ->
-    new_transport_factory(Name, ExtraLogOpts, [{close_on_close, true},
-                                               {sync_every, 500}]).
+    new_transport_factory(Name, ExtraLogOpts, [
+        {close_on_close, true},
+        {sync_every, 500}
+    ]).
 
 new_transport_factory(Name, ExtraLogOpts, TransportOpts) ->
     F = fun() -> factory_impl(Name, ExtraLogOpts, TransportOpts) end,
     {ok, F}.
 
 factory_impl(Name, ExtraLogOpts, TransportOpts) ->
-    LogOpts = [{name, Name},
-               {format, external},
-               {type, wrap} |
-               ExtraLogOpts],
+    LogOpts = [
+        {name, Name},
+        {format, external},
+        {type, wrap}
+        | ExtraLogOpts
+    ],
     Log =
         case disk_log:open(LogOpts) of
             {ok, LogS} ->
diff --git a/lib/erl/src/thrift_file_transport.erl b/lib/erl/src/thrift_file_transport.erl
index 071152b..b0bf383 100644
--- a/lib/erl/src/thrift_file_transport.erl
+++ b/lib/erl/src/thrift_file_transport.erl
@@ -28,88 +28,76 @@
 %% legacy api
 -export([new_reader/1]).
 
-
 -record(t_file, {
-  device,
-  should_close = true,
-  mode = write
+    device :: file:io_device(),
+    should_close = true :: boolean(),
+    mode = write :: file:mode()
 }).
 
--type state() :: #t_file{}.
-
-
--spec new(Device::file:io_device()) ->
-  thrift_transport:t_transport().
+-spec new(Device :: file:io_device()) -> {ok, thrift_transport:t_transport()}.
 
 new(Device) -> new(Device, []).
 
--spec new(Device::file:io_device(), Opts::list()) ->
-  thrift_transport:t_transport().
+-spec new(Device :: file:io_device(), Opts :: list()) -> {ok, thrift_transport:t_transport()}.
 
 %% Device should be opened in raw and binary mode.
 new(Device, Opts) when is_list(Opts) ->
-  State = parse_opts(Opts, #t_file{device = Device}),
-  thrift_transport:new(?MODULE, State).
+    State = parse_opts(Opts, #t_file{device = Device}),
+    thrift_transport:new(?MODULE, State).
 
-
-parse_opts([{should_close, Bool}|Rest], State)
-when is_boolean(Bool) ->
-  parse_opts(Rest, State#t_file{should_close = Bool});
-parse_opts([{mode, Mode}|Rest], State)
-when Mode =:= write; Mode =:= read ->
-  parse_opts(Rest, State#t_file{mode = Mode});
+parse_opts([{should_close, Bool} | Rest], State) when
+    is_boolean(Bool)
+->
+    parse_opts(Rest, State#t_file{should_close = Bool});
+parse_opts([{mode, Mode} | Rest], State) when
+    Mode =:= write; Mode =:= read
+->
+    parse_opts(Rest, State#t_file{mode = Mode});
 parse_opts([], State) ->
-  State.
+    State.
 
-
--include("thrift_transport_behaviour.hrl").
-
-
-read(State = #t_file{device = Device, mode = read}, Len)
-when is_integer(Len), Len >= 0 ->
-  case file:read(Device, Len) of
-    eof -> {State, {error, eof}};
-    {ok, Result} -> {State, {ok, iolist_to_binary(Result)}}
-  end;
+read(State = #t_file{device = Device, mode = read}, Len) when
+    is_integer(Len), Len >= 0
+->
+    case file:read(Device, Len) of
+        eof -> {State, {error, eof}};
+        {ok, Result} -> {State, {ok, iolist_to_binary(Result)}}
+    end;
 read(State, _) ->
-  {State, {error, write_mode}}.
+    {State, {error, write_mode}}.
 
-
-read_exact(State = #t_file{device = Device, mode = read}, Len)
-when is_integer(Len), Len >= 0 ->
-  case file:read(Device, Len) of
-    eof -> {State, {error, eof}};
-    {ok, Result} ->
-      case iolist_size(Result) of
-        X when X < Len -> {State, {error, eof}};
-        _ -> {State, {ok, iolist_to_binary(Result)}}
-      end
-  end;
+read_exact(State = #t_file{device = Device, mode = read}, Len) when
+    is_integer(Len), Len >= 0
+->
+    case file:read(Device, Len) of
+        eof ->
+            {State, {error, eof}};
+        {ok, Result} ->
+            case iolist_size(Result) of
+                X when X < Len -> {State, {error, eof}};
+                _ -> {State, {ok, iolist_to_binary(Result)}}
+            end
+    end;
 read_exact(State, _) ->
-  {State, {error, write_mode}}.
-
+    {State, {error, write_mode}}.
 
 write(State = #t_file{device = Device, mode = write}, Data) ->
-  {State, file:write(Device, Data)};
+    {State, file:write(Device, Data)};
 write(State, _) ->
-  {State, {error, read_mode}}.
-
+    {State, {error, read_mode}}.
 
 flush(State = #t_file{device = Device, mode = write}) ->
-  {State, file:sync(Device)}.
-
+    {State, file:sync(Device)}.
 
 close(State = #t_file{device = Device, should_close = SC}) ->
-  case SC of
-    true -> {State, file:close(Device)};
-    false -> {State, ok}
-  end.
-
+    case SC of
+        true -> {State, file:close(Device)};
+        false -> {State, ok}
+    end.
 
 %% legacy api. left for compatibility
 new_reader(Filename) ->
-  case file:open(Filename, [read, binary, {read_ahead, 1024*1024}]) of
-    {ok, IODevice} -> new(IODevice, [{should_close, true}, {mode, read}]);
-    Error -> Error
-  end.
-
+    case file:open(Filename, [read, binary, {read_ahead, 1024 * 1024}]) of
+        {ok, IODevice} -> new(IODevice, [{should_close, true}, {mode, read}]);
+        Error -> Error
+    end.
diff --git a/lib/erl/src/thrift_framed_transport.erl b/lib/erl/src/thrift_framed_transport.erl
index 9a5d6af..0d93baa 100644
--- a/lib/erl/src/thrift_framed_transport.erl
+++ b/lib/erl/src/thrift_framed_transport.erl
@@ -26,101 +26,92 @@
 %% protocol callbacks
 -export([read/2, read_exact/2, write/2, flush/1, close/1]).
 
-
 -record(t_framed, {
-  wrapped,
-  read_buffer,
-  write_buffer
+    wrapped :: thrift_transport:t_transport(),
+    read_buffer :: iodata(),
+    write_buffer :: iodata()
 }).
 
--type state() :: #t_framed{}.
-
-
--spec new(Transport::thrift_transport:t_transport()) ->
-  thrift_transport:t_transport().
+-spec new(Transport :: thrift_transport:t_transport()) -> {ok, thrift_transport:t_transport()}.
 
 new(Wrapped) ->
-  State = #t_framed{
-    wrapped = Wrapped,
-    read_buffer = [],
-    write_buffer = []
-  },
-  thrift_transport:new(?MODULE, State).
+    State = #t_framed{
+        wrapped = Wrapped,
+        read_buffer = [],
+        write_buffer = []
+    },
+    thrift_transport:new(?MODULE, State).
 
+read(State = #t_framed{wrapped = Wrapped, read_buffer = Buffer}, Len) when
+    is_integer(Len), Len >= 0
+->
+    Binary = iolist_to_binary(Buffer),
+    case Binary of
+        <<>> when Len > 0 ->
+            case next_frame(Wrapped) of
+                {NewState, {ok, Frame}} ->
+                    NewBinary = iolist_to_binary([Binary, Frame]),
+                    Give = min(iolist_size(NewBinary), Len),
+                    {Result, Remaining} = split_binary(NewBinary, Give),
+                    {State#t_framed{wrapped = NewState, read_buffer = Remaining}, {ok, Result}};
+                {NewState, Error} ->
+                    {State#t_framed{wrapped = NewState}, Error}
+            end;
+        %% read of zero bytes
+        <<>> ->
+            {State, {ok, <<>>}};
+        %% read buffer is nonempty
+        _ ->
+            Give = min(iolist_size(Binary), Len),
+            {Result, Remaining} = split_binary(Binary, Give),
+            {State#t_framed{read_buffer = Remaining}, {ok, Result}}
+    end.
 
--include("thrift_transport_behaviour.hrl").
-
-
-read(State = #t_framed{wrapped = Wrapped, read_buffer = Buffer}, Len)
-when is_integer(Len), Len >= 0 ->
-  Binary = iolist_to_binary(Buffer),
-  case Binary of
-    <<>> when Len > 0 ->
-      case next_frame(Wrapped) of
-        {NewState, {ok, Frame}} ->
-          NewBinary = iolist_to_binary([Binary, Frame]),
-          Give = min(iolist_size(NewBinary), Len),
-          {Result, Remaining} = split_binary(NewBinary, Give),
-          {State#t_framed{wrapped = NewState, read_buffer = Remaining}, {ok, Result}};
-        {NewState, Error} ->
-          {State#t_framed{wrapped = NewState}, Error}
-      end;
-    %% read of zero bytes
-    <<>> -> {State, {ok, <<>>}};
-    %% read buffer is nonempty
-    _ ->
-      Give = min(iolist_size(Binary), Len),
-      {Result, Remaining} = split_binary(Binary, Give),
-      {State#t_framed{read_buffer = Remaining}, {ok, Result}}
-  end.
-
-
-read_exact(State = #t_framed{wrapped = Wrapped, read_buffer = Buffer}, Len)
-when is_integer(Len), Len >= 0 ->
-  Binary = iolist_to_binary(Buffer),
-  case iolist_size(Binary) of
-    %% read buffer is larger than requested read size
-    X when X >= Len ->
-      {Result, Remaining} = split_binary(Binary, Len),
-      {State#t_framed{read_buffer = Remaining}, {ok, Result}};
-    %% read buffer is insufficient for requested read size
-    _ ->
-      case next_frame(Wrapped) of
-        {NewState, {ok, Frame}} ->
-          read_exact(
-            State#t_framed{wrapped = NewState, read_buffer = [Buffer, Frame]},
-            Len
-          );
-        {NewState, Error} ->
-          {State#t_framed{wrapped = NewState}, Error}
-      end
-  end.
+read_exact(State = #t_framed{wrapped = Wrapped, read_buffer = Buffer}, Len) when
+    is_integer(Len), Len >= 0
+->
+    Binary = iolist_to_binary(Buffer),
+    case iolist_size(Binary) of
+        %% read buffer is larger than requested read size
+        X when X >= Len ->
+            {Result, Remaining} = split_binary(Binary, Len),
+            {State#t_framed{read_buffer = Remaining}, {ok, Result}};
+        %% read buffer is insufficient for requested read size
+        _ ->
+            case next_frame(Wrapped) of
+                {NewState, {ok, Frame}} ->
+                    read_exact(
+                        State#t_framed{wrapped = NewState, read_buffer = [Buffer, Frame]},
+                        Len
+                    );
+                {NewState, Error} ->
+                    {State#t_framed{wrapped = NewState}, Error}
+            end
+    end.
 
 next_frame(Transport) ->
-  case thrift_transport:read_exact(Transport, 4) of
-    {NewState, {ok, <<FrameLength:32/integer-signed-big>>}} ->
-      thrift_transport:read_exact(NewState, FrameLength);
-    Error -> Error
-  end.
-
+    case thrift_transport:read_exact(Transport, 4) of
+        {NewState, {ok, <<FrameLength:32/integer-signed-big>>}} ->
+            thrift_transport:read_exact(NewState, FrameLength);
+        Error ->
+            Error
+    end.
 
 write(State = #t_framed{write_buffer = Buffer}, Data) ->
-  {State#t_framed{write_buffer = [Buffer, Data]}, ok}.
-
+    {State#t_framed{write_buffer = [Buffer, Data]}, ok}.
 
 flush(State = #t_framed{write_buffer = Buffer, wrapped = Wrapped}) ->
-  case iolist_size(Buffer) of
-    %% if write buffer is empty, do nothing
-    0 -> {State, ok};
-    FrameLen ->
-      Data = [<<FrameLen:32/integer-signed-big>>, Buffer],
-      {Written, Response} = thrift_transport:write(Wrapped, Data),
-      {Flushed, ok} = thrift_transport:flush(Written),
-      {State#t_framed{wrapped = Flushed, write_buffer = []}, Response}
-  end.
-
+    case iolist_size(Buffer) of
+        %% if write buffer is empty, do nothing
+        0 ->
+            {State, ok};
+        FrameLen ->
+            Data = [<<FrameLen:32/integer-signed-big>>, Buffer],
+            {Written, Response} = thrift_transport:write(Wrapped, Data),
+            {Flushed, ok} = thrift_transport:flush(Written),
+            {State#t_framed{wrapped = Flushed, write_buffer = []}, Response}
+    end.
 
 close(State = #t_framed{wrapped = Wrapped}) ->
-  {Closed, Result} = thrift_transport:close(Wrapped),
-  {State#t_framed{wrapped = Closed}, Result}.
-
+    {Closed, Result} = thrift_transport:close(Wrapped),
+    {State#t_framed{wrapped = Closed}, Result}.
diff --git a/lib/erl/src/thrift_http_transport.erl b/lib/erl/src/thrift_http_transport.erl
index 46bcede..b422b3f 100644
--- a/lib/erl/src/thrift_http_transport.erl
+++ b/lib/erl/src/thrift_http_transport.erl
@@ -27,15 +27,16 @@
 %% thrift_transport callbacks
 -export([write/2, read/2, flush/1, close/1]).
 
--record(http_transport, {host, % string()
-                         path, % string()
-                         read_buffer, % iolist()
-                         write_buffer, % iolist()
-                         http_options, % see http(3)
-                         extra_headers % [{str(), str()}, ...]
-                        }).
--type state() :: #http_transport{}.
--include("thrift_transport_behaviour.hrl").
+% string()
+-record(http_transport, {
+    host :: string(),
+    path :: string(),
+    read_buffer :: iodata(),
+    write_buffer :: iodata(),
+    % see httpc(3)
+    http_options :: [{atom(), term()}],
+    extra_headers :: [{string(), string()}]
+}).
 
 new(Host, Path) ->
     new(Host, Path, _Options = []).
@@ -46,12 +47,14 @@
 %%   {extra_headers, ExtraHeaders}  = List of extra HTTP headers
 %%--------------------------------------------------------------------
 new(Host, Path, Options) ->
-    State1 = #http_transport{host = Host,
-                             path = Path,
-                             read_buffer = [],
-                             write_buffer = [],
-                             http_options = [],
-                             extra_headers = []},
+    State1 = #http_transport{
+        host = Host,
+        path = Path,
+        read_buffer = [],
+        write_buffer = [],
+        http_options = [],
+        extra_headers = []
+    },
     ApplyOption =
         fun
             ({http_options, HttpOpts}, State = #http_transport{}) ->
@@ -75,28 +78,38 @@
     {State#http_transport{write_buffer = [WBuf, Data]}, ok}.
 
 %% Flushes the buffer, making a request
-flush(State = #http_transport{host = Host,
-                                 path = Path,
-                                 read_buffer = Rbuf,
-                                 write_buffer = Wbuf,
-                                 http_options = HttpOptions,
-                                 extra_headers = ExtraHeaders}) ->
+flush(
+    State = #http_transport{
+        host = Host,
+        path = Path,
+        read_buffer = Rbuf,
+        write_buffer = Wbuf,
+        http_options = HttpOptions,
+        extra_headers = ExtraHeaders
+    }
+) ->
     case iolist_to_binary(Wbuf) of
         <<>> ->
             %% Don't bother flushing empty buffers.
             {State, ok};
         WBinary ->
             {ok, {{_Version, 200, _ReasonPhrase}, _Headers, Body}} =
-              httpc:request(post,
-                           {"http://" ++ Host ++ Path,
-                            [{"User-Agent", "Erlang/thrift_http_transport"} | ExtraHeaders],
-                            "application/x-thrift",
-                            WBinary},
-                           HttpOptions,
-                           [{body_format, binary}]),
+                httpc:request(
+                    post,
+                    {
+                        "http://" ++ Host ++ Path,
+                        [{"User-Agent", "Erlang/thrift_http_transport"} | ExtraHeaders],
+                        "application/x-thrift",
+                        WBinary
+                    },
+                    HttpOptions,
+                    [{body_format, binary}]
+                ),
 
-            State1 = State#http_transport{read_buffer = [Rbuf, Body],
-                                          write_buffer = []},
+            State1 = State#http_transport{
+                read_buffer = [Rbuf, Body],
+                write_buffer = []
+            },
             {State1, ok}
     end.
 
@@ -109,7 +122,7 @@
     case iolist_to_binary(RBuf) of
         <<Data:Give/binary, RBuf1/binary>> ->
             Response = {ok, Data},
-            State1 = State#http_transport{read_buffer=RBuf1},
+            State1 = State#http_transport{read_buffer = RBuf1},
             {State1, Response};
         _ ->
             {State, {error, 'EOF'}}
diff --git a/lib/erl/src/thrift_json_parser.erl b/lib/erl/src/thrift_json_parser.erl
index 4e47f10..18e0c03 100644
--- a/lib/erl/src/thrift_json_parser.erl
+++ b/lib/erl/src/thrift_json_parser.erl
@@ -22,19 +22,15 @@
 -module(thrift_json_parser).
 -export([parser/0, handle_event/2]).
 
-
 -record(config, {strict_utf8 = false :: boolean()}).
 
-
 parser() -> fun(JSON) -> start(JSON, {?MODULE, []}, [], #config{}) end.
 
-
 handle_event(Event, {Handler, State}, _Config) -> {Handler, Handler:handle_event(Event, State)}.
 
 handle_event(end_json, State) -> lists:reverse([end_json] ++ State);
 handle_event(Event, State) -> [Event] ++ State.
 
-
 %% whitespace
 -define(space, 16#20).
 -define(tab, 16#09).
@@ -68,12 +64,11 @@
 %% comments
 -define(star, 16#2A).
 
-
 %% some useful guards
 -define(is_hex(Symbol),
     (Symbol >= $a andalso Symbol =< $f) orelse
-    (Symbol >= $A andalso Symbol =< $F) orelse
-    (Symbol >= $0 andalso Symbol =< $9)
+        (Symbol >= $A andalso Symbol =< $F) orelse
+        (Symbol >= $0 andalso Symbol =< $9)
 ).
 
 -define(is_nonzero(Symbol),
@@ -84,7 +79,6 @@
     Symbol =:= ?space; Symbol =:= ?tab; Symbol =:= ?cr; Symbol =:= ?newline
 ).
 
-
 %% lists are benchmarked to be faster (tho higher in memory usage) than binaries
 new_seq() -> [].
 new_seq(C) -> [C].
@@ -96,13 +90,11 @@
 
 end_seq(Seq, _) -> end_seq(Seq).
 
-
 start(<<16#ef, 16#bb, 16#bf, Rest/binary>>, Handler, Stack, Config) ->
     value(Rest, Handler, Stack, Config);
 start(Bin, Handler, Stack, Config) ->
     value(Bin, Handler, Stack, Config).
 
-
 value(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
     string(Rest, Handler, new_seq(), Stack, Config);
 value(<<$t, Rest/binary>>, Handler, Stack, Config) ->
@@ -118,41 +110,37 @@
 value(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_nonzero(S) ->
     integer(Rest, Handler, new_seq(S), Stack, Config);
 value(<<?start_object, Rest/binary>>, Handler, Stack, Config) ->
-    object(Rest, handle_event(start_object, Handler, Config), [key|Stack], Config);
+    object(Rest, handle_event(start_object, Handler, Config), [key | Stack], Config);
 value(<<?start_array, Rest/binary>>, Handler, Stack, Config) ->
-    array(Rest, handle_event(start_array, Handler, Config), [array|Stack], Config);
+    array(Rest, handle_event(start_array, Handler, Config), [array | Stack], Config);
 value(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     value(Rest, Handler, Stack, Config);
 value(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 object(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
     string(Rest, Handler, new_seq(), Stack, Config);
-object(<<?end_object, Rest/binary>>, Handler, [key|Stack], Config) ->
+object(<<?end_object, Rest/binary>>, Handler, [key | Stack], Config) ->
     maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config);
 object(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     object(Rest, Handler, Stack, Config);
 object(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
-array(<<?end_array, Rest/binary>>, Handler, [array|Stack], Config) ->
+array(<<?end_array, Rest/binary>>, Handler, [array | Stack], Config) ->
     maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config);
 array(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     array(Rest, Handler, Stack, Config);
 array(Bin, Handler, Stack, Config) ->
     value(Bin, Handler, Stack, Config).
 
-
-colon(<<?colon, Rest/binary>>, Handler, [key|Stack], Config) ->
-    value(Rest, Handler, [object|Stack], Config);
+colon(<<?colon, Rest/binary>>, Handler, [key | Stack], Config) ->
+    value(Rest, Handler, [object | Stack], Config);
 colon(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     colon(Rest, Handler, Stack, Config);
 colon(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 key(<<?doublequote, Rest/binary>>, Handler, Stack, Config) ->
     string(Rest, Handler, new_seq(), Stack, Config);
 key(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
@@ -160,7 +148,6 @@
 key(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 %% note that if you encounter an error from string and you can't find the clause that
 %%  caused it here, it might be in unescape below
 string(<<?doublequote, Rest/binary>>, Handler, Acc, Stack, Config) ->
@@ -212,42 +199,47 @@
 string(<<X/utf8, Rest/binary>>, Handler, Acc, Stack, Config) when X >= 16#100000, X < 16#10fffe ->
     string(Rest, Handler, acc_seq(Acc, X), Stack, Config);
 %% surrogates
-string(<<237, X, _, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X >= 160 ->
+string(<<237, X, _, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when
+    X >= 160
+->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
 %% u+xfffe, u+xffff, control codes and other noncharacters
-string(<<_/utf8, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false}) ->
+string(<<_/utf8, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) ->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
 %% u+fffe and u+ffff for R14BXX (subsequent runtimes will happily match the
 %%  preceding clause
-string(<<239, 191, X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X == 190; X == 191 ->
+string(
+    <<239, 191, X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}
+) when
+    X == 190; X == 191
+->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
 %% overlong encodings and missing continuations of a 2 byte sequence
-string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X >= 192, X =< 223 ->
+string(<<X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when
+    X >= 192, X =< 223
+->
     strip_continuations(Rest, Handler, Acc, Stack, Config, 1);
 %% overlong encodings and missing continuations of a 3 byte sequence
-string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X >= 224, X =< 239 ->
+string(<<X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when
+    X >= 224, X =< 239
+->
     strip_continuations(Rest, Handler, Acc, Stack, Config, 2);
 %% overlong encodings and missing continuations of a 4 byte sequence
-string(<<X, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false})
-        when X >= 240, X =< 247 ->
+string(<<X, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) when
+    X >= 240, X =< 247
+->
     strip_continuations(Rest, Handler, Acc, Stack, Config, 3);
 %% incompletes and unexpected bytes, including orphan continuations
-string(<<_, Rest/binary>>, Handler, Acc, Stack, Config=#config{strict_utf8=false}) ->
+string(<<_, Rest/binary>>, Handler, Acc, Stack, Config = #config{strict_utf8 = false}) ->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config);
 string(_Bin, _Handler, _Acc, _Stack, _Config) ->
-  erlang:error(badarg).
+    erlang:error(badarg).
 
-
-doublequote(Rest, Handler, Acc, [key|_] = Stack, Config) ->
+doublequote(Rest, Handler, Acc, [key | _] = Stack, Config) ->
     colon(Rest, handle_event({key, end_seq(Acc, Config)}, Handler, Config), Stack, Config);
 doublequote(Rest, Handler, Acc, Stack, Config) ->
     maybe_done(Rest, handle_event({string, end_seq(Acc, Config)}, Handler, Config), Stack, Config).
 
-
 %% strips continuation bytes after bad utf bytes, guards against both too short
 %%  and overlong sequences. N is the maximum number of bytes to strip
 strip_continuations(<<Rest/binary>>, Handler, Acc, Stack, Config, 0) ->
@@ -259,7 +251,6 @@
 strip_continuations(<<Rest/binary>>, Handler, Acc, Stack, Config, _) ->
     string(Rest, Handler, acc_seq(Acc, 16#fffd), Stack, Config).
 
-
 %% this all gets really gross and should probably eventually be folded into
 %%  but for now it fakes being part of string on incompletes and errors
 unescape(<<$b, Rest/binary>>, Handler, Acc, Stack, Config) ->
@@ -278,22 +269,35 @@
     string(Rest, Handler, acc_seq(Acc, $\\), Stack, Config);
 unescape(<<?solidus, Rest/binary>>, Handler, Acc, Stack, Config) ->
     string(Rest, Handler, acc_seq(Acc, $/), Stack, Config);
-unescape(<<$u, $d, A, B, C, ?rsolidus, $u, $d, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config)
-        when (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
-             (X == $c orelse X == $d orelse X == $e orelse X == $f),
-             ?is_hex(B), ?is_hex(C), ?is_hex(Y), ?is_hex(Z)
-        ->
+unescape(
+    <<$u, $d, A, B, C, ?rsolidus, $u, $d, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config
+) when
+    (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
+    (X == $c orelse X == $d orelse X == $e orelse X == $f),
+    ?is_hex(B),
+    ?is_hex(C),
+    ?is_hex(Y),
+    ?is_hex(Z)
+->
     High = erlang:list_to_integer([$d, A, B, C], 16),
     Low = erlang:list_to_integer([$d, X, Y, Z], 16),
     Codepoint = (High - 16#d800) * 16#400 + (Low - 16#dc00) + 16#10000,
     string(Rest, Handler, acc_seq(Acc, Codepoint), Stack, Config);
-unescape(<<$u, $d, A, B, C, ?rsolidus, $u, W, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config)
-        when (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
-             ?is_hex(B), ?is_hex(C), ?is_hex(W), ?is_hex(X), ?is_hex(Y), ?is_hex(Z)
-        ->
+unescape(
+    <<$u, $d, A, B, C, ?rsolidus, $u, W, X, Y, Z, Rest/binary>>, Handler, Acc, Stack, Config
+) when
+    (A == $8 orelse A == $9 orelse A == $a orelse A == $b),
+    ?is_hex(B),
+    ?is_hex(C),
+    ?is_hex(W),
+    ?is_hex(X),
+    ?is_hex(Y),
+    ?is_hex(Z)
+->
     string(Rest, Handler, acc_seq(Acc, [16#fffd, 16#fffd]), Stack, Config);
-unescape(<<$u, A, B, C, D, Rest/binary>>, Handler, Acc, Stack, Config)
-        when ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D) ->
+unescape(<<$u, A, B, C, D, Rest/binary>>, Handler, Acc, Stack, Config) when
+    ?is_hex(A), ?is_hex(B), ?is_hex(C), ?is_hex(D)
+->
     case erlang:list_to_integer([A, B, C, D], 16) of
         Codepoint when Codepoint < 16#d800; Codepoint > 16#dfff ->
             string(Rest, Handler, acc_seq(Acc, Codepoint), Stack, Config);
@@ -303,7 +307,6 @@
 unescape(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 %% like in strings, there's some pseudo states in here that will never
 %%  show up in errors or incompletes. some show up in value, some show
 %%  up in integer, decimal or exp
@@ -314,7 +317,6 @@
 negative(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 zero(<<?decimalpoint, Rest/binary>>, Handler, Acc, Stack, Config) ->
     decimal(Rest, Handler, acc_seq(Acc, ?decimalpoint), Stack, Config);
 zero(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E ->
@@ -322,7 +324,6 @@
 zero(Bin, Handler, Acc, Stack, Config) ->
     finish_number(Bin, Handler, {zero, Acc}, Stack, Config).
 
-
 integer(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     integer(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 integer(<<?decimalpoint, Rest/binary>>, Handler, Acc, Stack, Config) ->
@@ -332,13 +333,11 @@
 integer(Bin, Handler, Acc, Stack, Config) ->
     finish_number(Bin, Handler, {integer, Acc}, Stack, Config).
 
-
 initialdecimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     decimal(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 initialdecimal(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 decimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     decimal(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 decimal(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= $e; S =:= $E ->
@@ -346,7 +345,6 @@
 decimal(Bin, Handler, Acc, Stack, Config) ->
     finish_number(Bin, Handler, {decimal, Acc}, Stack, Config).
 
-
 e(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 e(<<Sign, Rest/binary>>, Handler, Acc, Stack, Config) when Sign =:= ?positive; Sign =:= ?negative ->
@@ -354,66 +352,59 @@
 e(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 ex(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 ex(_Bin, _Handler, _Acc, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 exp(<<S, Rest/binary>>, Handler, Acc, Stack, Config) when S =:= ?zero; ?is_nonzero(S) ->
     exp(Rest, Handler, acc_seq(Acc, S), Stack, Config);
 exp(Bin, Handler, Acc, Stack, Config) ->
     finish_number(Bin, Handler, {exp, Acc}, Stack, Config).
 
-
 finish_number(Rest, Handler, Acc, [], Config) ->
     maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), [], Config);
 finish_number(Rest, Handler, Acc, Stack, Config) ->
     maybe_done(Rest, handle_event(format_number(Acc), Handler, Config), Stack, Config).
 
-
 format_number({zero, Acc}) -> {integer, list_to_integer(lists:reverse(Acc))};
 format_number({integer, Acc}) -> {integer, list_to_integer(lists:reverse(Acc))};
 format_number({decimal, Acc}) -> {float, list_to_float(lists:reverse(Acc))};
 format_number({exp, Acc}) -> {float, list_to_float(lists:reverse(Acc))}.
 
-
 true(<<$r, $u, $e, Rest/binary>>, Handler, Stack, Config) ->
     maybe_done(Rest, handle_event({literal, true}, Handler, Config), Stack, Config);
 true(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 false(<<$a, $l, $s, $e, Rest/binary>>, Handler, Stack, Config) ->
     maybe_done(Rest, handle_event({literal, false}, Handler, Config), Stack, Config);
 false(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 null(<<$u, $l, $l, Rest/binary>>, Handler, Stack, Config) ->
     maybe_done(Rest, handle_event({literal, null}, Handler, Config), Stack, Config);
 null(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 maybe_done(<<Rest/binary>>, Handler, [], Config) ->
     done(Rest, handle_event(end_json, Handler, Config), [], Config);
-maybe_done(<<?end_object, Rest/binary>>, Handler, [object|Stack], Config) ->
+maybe_done(<<?end_object, Rest/binary>>, Handler, [object | Stack], Config) ->
     maybe_done(Rest, handle_event(end_object, Handler, Config), Stack, Config);
-maybe_done(<<?end_array, Rest/binary>>, Handler, [array|Stack], Config) ->
+maybe_done(<<?end_array, Rest/binary>>, Handler, [array | Stack], Config) ->
     maybe_done(Rest, handle_event(end_array, Handler, Config), Stack, Config);
-maybe_done(<<?comma, Rest/binary>>, Handler, [object|Stack], Config) ->
-    key(Rest, Handler, [key|Stack], Config);
-maybe_done(<<?comma, Rest/binary>>, Handler, [array|_] = Stack, Config) ->
+maybe_done(<<?comma, Rest/binary>>, Handler, [object | Stack], Config) ->
+    key(Rest, Handler, [key | Stack], Config);
+maybe_done(<<?comma, Rest/binary>>, Handler, [array | _] = Stack, Config) ->
     value(Rest, Handler, Stack, Config);
 maybe_done(<<S, Rest/binary>>, Handler, Stack, Config) when ?is_whitespace(S) ->
     maybe_done(Rest, Handler, Stack, Config);
 maybe_done(_Bin, _Handler, _Stack, _Config) ->
     erlang:error(badarg).
 
-
 done(<<S, Rest/binary>>, Handler, [], Config) when ?is_whitespace(S) ->
     done(Rest, Handler, [], Config);
-done(<<>>, {_Handler, State}, [], _Config) -> State;
-done(_Bin, _Handler, _Stack, _Config) -> erlang:error(badarg).
+done(<<>>, {_Handler, State}, [], _Config) ->
+    State;
+done(_Bin, _Handler, _Stack, _Config) ->
+    erlang:error(badarg).
diff --git a/lib/erl/src/thrift_json_protocol.erl b/lib/erl/src/thrift_json_protocol.erl
index c5f3da8..b0a3918 100644
--- a/lib/erl/src/thrift_json_protocol.erl
+++ b/lib/erl/src/thrift_json_protocol.erl
@@ -27,35 +27,38 @@
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
--export([new/1, new/2,
-         read/2,
-         write/2,
-         flush_transport/1,
-         close_transport/1,
-         new_protocol_factory/2
-        ]).
+-export([
+    new/1, new/2,
+    read/2,
+    write/2,
+    flush_transport/1,
+    close_transport/1,
+    new_protocol_factory/2
+]).
 
 -record(json_context, {
     % the type of json_context: array or object
-    type,
+    type :: undefined | array | object,
     % fields read or written
-    fields_processed = 0
+    fields_processed = 0 :: non_neg_integer()
 }).
 
+-type json_context() :: #json_context{}.
+-type jsx_type() :: atom() | {atom(), atom() | string()}.
+-type jsx() :: {event, jsx_type(), [jsx_type()]}.
+
 -record(json_protocol, {
-    transport,
-    context_stack = [],
-    jsx
+    transport :: term(),
+    context_stack = [] :: [json_context()],
+    jsx :: undefined | jsx()
 }).
--type state() :: #json_protocol{}.
--include("thrift_protocol_behaviour.hrl").
 
 -define(VERSION_1, 1).
 -define(JSON_DOUBLE_PRECISION, 16).
 
 typeid_to_json(?tType_BOOL) -> "tf";
-typeid_to_json(?tType_BYTE) -> "i8";
 typeid_to_json(?tType_DOUBLE) -> "dbl";
+% NOTE: ?tType_BYTE also match here
 typeid_to_json(?tType_I8) -> "i8";
 typeid_to_json(?tType_I16) -> "i16";
 typeid_to_json(?tType_I32) -> "i32";
@@ -84,28 +87,33 @@
 end_context(object) -> "}";
 end_context(array) -> "]".
 
-
 new(Transport) ->
     new(Transport, _Options = []).
 
 new(Transport, _Options) ->
-    State  = #json_protocol{transport = Transport},
+    State = #json_protocol{transport = Transport},
     thrift_protocol:new(?MODULE, State).
 
 flush_transport(This = #json_protocol{transport = Transport}) ->
     {NewTransport, Result} = thrift_transport:flush(Transport),
-    {This#json_protocol{
+    {
+        This#json_protocol{
             transport = NewTransport,
             context_stack = []
-        }, Result}.
+        },
+        Result
+    }.
 
 close_transport(This = #json_protocol{transport = Transport}) ->
     {NewTransport, Result} = thrift_transport:close(Transport),
-    {This#json_protocol{
+    {
+        This#json_protocol{
             transport = NewTransport,
             context_stack = [],
             jsx = undefined
-        }, Result}.
+        },
+        Result
+    }.
 
 %%%
 %%% instance methods
@@ -113,63 +121,82 @@
 % places a new context on the stack:
 write(#json_protocol{context_stack = Stack} = State0, {enter_context, Type}) ->
     {State1, ok} = write_values(State0, [{context_pre_item, false}]),
-    State2 = State1#json_protocol{context_stack = [
-        #json_context{type=Type}|Stack]},
-    write_values(State2,  [list_to_binary(start_context(Type))]);
-
-% removes the topmost context from stack    
-write(#json_protocol{context_stack = [CurrCtxt|Stack]} = State0, {exit_context}) ->
+    State2 = State1#json_protocol{
+        context_stack = [
+            #json_context{type = Type} | Stack
+        ]
+    },
+    write_values(State2, [list_to_binary(start_context(Type))]);
+% removes the topmost context from stack
+write(#json_protocol{context_stack = [CurrCtxt | Stack]} = State0, {exit_context}) ->
     Type = CurrCtxt#json_context.type,
     State1 = State0#json_protocol{context_stack = Stack},
     write_values(State1, [
-            list_to_binary(end_context(Type)),
-            {context_post_item, false}
-        ]);
-
-% writes necessary prelude to field or container depending on current context   
-write(#json_protocol{context_stack = []} = This0,
-    {context_pre_item, _}) -> {This0, ok};
-write(#json_protocol{context_stack = [Context|_CtxtTail]} = This0,
-    {context_pre_item, MayNeedQuotes}) ->
+        list_to_binary(end_context(Type)),
+        {context_post_item, false}
+    ]);
+% writes necessary prelude to field or container depending on current context
+write(
+    #json_protocol{context_stack = []} = This0,
+    {context_pre_item, _}
+) ->
+    {This0, ok};
+write(
+    #json_protocol{context_stack = [Context | _CtxtTail]} = This0,
+    {context_pre_item, MayNeedQuotes}
+) ->
     FieldNo = Context#json_context.fields_processed,
     CtxtType = Context#json_context.type,
     Rem = FieldNo rem 2,
     case {CtxtType, FieldNo, Rem, MayNeedQuotes} of
-        {array, N, _, _} when N > 0 ->  % array element (not first)
+        % array element (not first)
+        {array, N, _, _} when N > 0 ->
             write(This0, <<",">>);
-        {object, 0, _, true} -> % non-string object key (first)
+        % non-string object key (first)
+        {object, 0, _, true} ->
             write(This0, <<"\"">>);
-        {object, N, 0, true} when N > 0 -> % non-string object key (not first)
+        % non-string object key (not first)
+        {object, N, 0, true} when N > 0 ->
             write(This0, <<",\"">>);
-        {object, N, 0, false} when N > 0-> % string object key (not first)
+        % string object key (not first)
+        {object, N, 0, false} when N > 0 ->
             write(This0, <<",">>);
-        _ -> % no pre-field necessary
+        % no pre-field necessary
+        _ ->
             {This0, ok}
     end;
-
-% writes necessary postlude to field or container depending on current context   
-write(#json_protocol{context_stack = []} = This0,
-    {context_post_item, _}) -> {This0, ok};
-write(#json_protocol{context_stack = [Context|CtxtTail]} = This0,
-    {context_post_item, MayNeedQuotes}) ->
+% writes necessary postlude to field or container depending on current context
+write(
+    #json_protocol{context_stack = []} = This0,
+    {context_post_item, _}
+) ->
+    {This0, ok};
+write(
+    #json_protocol{context_stack = [Context | CtxtTail]} = This0,
+    {context_post_item, MayNeedQuotes}
+) ->
     FieldNo = Context#json_context.fields_processed,
     CtxtType = Context#json_context.type,
     Rem = FieldNo rem 2,
-    {This1, ok} = case {CtxtType, Rem, MayNeedQuotes} of
-        {object, 0, true} -> % non-string object key 
-            write(This0, <<"\":">>);
-        {object, 0, false} -> % string object key 
-            write(This0, <<":">>);
-        _ -> % no pre-field necessary
-            {This0, ok}
-    end,
+    {This1, ok} =
+        case {CtxtType, Rem, MayNeedQuotes} of
+            % non-string object key
+            {object, 0, true} ->
+                write(This0, <<"\":">>);
+            % string object key
+            {object, 0, false} ->
+                write(This0, <<":">>);
+            % no pre-field necessary
+            _ ->
+                {This0, ok}
+        end,
     NewContext = Context#json_context{fields_processed = FieldNo + 1},
-    {This1#json_protocol{context_stack=[NewContext|CtxtTail]}, ok};
-
+    {This1#json_protocol{context_stack = [NewContext | CtxtTail]}, ok};
 write(This0, #protocol_message_begin{
     name = Name,
     type = Type,
-    seqid = Seqid}) ->
+    seqid = Seqid
+}) ->
     write_values(This0, [
         {enter_context, array},
         {i32, ?VERSION_1},
@@ -177,15 +204,14 @@
         {i32, Type},
         {i32, Seqid}
     ]);
-
-write(This, message_end) ->  
+write(This, message_end) ->
     write_values(This, [{exit_context}]);
-
 % Example field expression: "1":{"dbl":3.14}
 write(This0, #protocol_field_begin{
-       name = _Name,
-       type = Type,
-       id = Id}) ->
+    name = _Name,
+    type = Type,
+    id = Id
+}) ->
     write_values(This0, [
         % entering 'outer' object
         {i16, Id},
@@ -193,18 +219,16 @@
         {enter_context, object},
         {string, typeid_to_json(Type)}
     ]);
-
-write(This, field_stop) -> 
+write(This, field_stop) ->
     {This, ok};
-
-write(This, field_end) -> 
-    write_values(This,[{exit_context}]);
-
+write(This, field_end) ->
+    write_values(This, [{exit_context}]);
 % Example message with map: [1,"testMap",1,0,{"1":{"map":["i32","i32",3,{"7":77,"8":88,"9":99}]}}]
 write(This0, #protocol_map_begin{
-       ktype = Ktype,
-       vtype = Vtype,
-       size = Size}) ->
+    ktype = Ktype,
+    vtype = Vtype,
+    size = Size
+}) ->
     write_values(This0, [
         {enter_context, array},
         {string, typeid_to_json(Ktype)},
@@ -212,86 +236,79 @@
         {i32, Size},
         {enter_context, object}
     ]);
-
-write(This, map_end) -> 
-    write_values(This,[
+write(This, map_end) ->
+    write_values(This, [
         {exit_context},
         {exit_context}
     ]);
-
 write(This0, #protocol_list_begin{
-        etype = Etype,
-        size = Size}) ->
+    etype = Etype,
+    size = Size
+}) ->
     write_values(This0, [
         {enter_context, array},
         {string, typeid_to_json(Etype)},
         {i32, Size}
     ]);
-
-write(This, list_end) -> 
-    write_values(This,[
+write(This, list_end) ->
+    write_values(This, [
         {exit_context}
     ]);
-
 % example message with set: [1,"testSet",1,0,{"1":{"set":["i32",3,1,2,3]}}]
 write(This0, #protocol_set_begin{
-        etype = Etype,
-        size = Size}) ->
+    etype = Etype,
+    size = Size
+}) ->
     write_values(This0, [
         {enter_context, array},
         {string, typeid_to_json(Etype)},
         {i32, Size}
     ]);
-
-write(This, set_end) -> 
-    write_values(This,[
+write(This, set_end) ->
+    write_values(This, [
         {exit_context}
     ]);
 % example message with struct: [1,"testStruct",1,0,{"1":{"rec":{"1":{"str":"worked"},"4":{"i8":1},"9":{"i32":1073741824},"11":{"i64":1152921504606847000}}}}]
-write(This, #protocol_struct_begin{}) -> 
+write(This, #protocol_struct_begin{}) ->
     write_values(This, [
         {enter_context, object}
     ]);
-
-write(This, struct_end) -> 
-    write_values(This,[
+write(This, struct_end) ->
+    write_values(This, [
         {exit_context}
     ]);
-
-write(This, {bool, true})  -> write_values(This, [
+write(This, {bool, true}) ->
+    write_values(This, [
         {context_pre_item, true},
         <<"true">>,
         {context_post_item, true}
     ]);
-
-write(This, {bool, false}) -> write_values(This, [
+write(This, {bool, false}) ->
+    write_values(This, [
         {context_pre_item, true},
         <<"false">>,
         {context_post_item, true}
     ]);
-
-write(This, {byte, Byte}) -> write_values(This, [
+write(This, {byte, Byte}) ->
+    write_values(This, [
         {context_pre_item, true},
         list_to_binary(integer_to_list(Byte)),
         {context_post_item, true}
     ]);
-
 write(This, {i16, I16}) ->
     write(This, {byte, I16});
-
 write(This, {i32, I32}) ->
     write(This, {byte, I32});
-
 write(This, {i64, I64}) ->
     write(This, {byte, I64});
-
-write(This, {double, Double}) -> write_values(This, [
+write(This, {double, Double}) ->
+    write_values(This, [
         {context_pre_item, true},
-        list_to_binary(io_lib:format("~.*f", [?JSON_DOUBLE_PRECISION,Double])),
+        list_to_binary(io_lib:format("~.*f", [?JSON_DOUBLE_PRECISION, Double])),
         {context_post_item, true}
     ]);
-
-write(This0, {string, Str}) -> write_values(This0, [
+write(This0, {string, Str}) ->
+    write_values(This0, [
         {context_pre_item, false},
         case is_binary(Str) of
             true -> Str;
@@ -299,7 +316,6 @@
         end,
         {context_post_item, false}
     ]);
-
 %% TODO: binary fields should be base64 encoded?
 
 %% Data :: iolist()
@@ -315,10 +331,11 @@
             ThisOut
         end,
         This0,
-        ValueList),
+        ValueList
+    ),
     {FinalState, ok}.
 
-%% I wish the erlang version of the transport interface included a 
+%% I wish the erlang version of the transport interface included a
 %% read_all function (like eg. the java implementation). Since it doesn't,
 %% here's my version (even though it probably shouldn't be in this file).
 %%
@@ -327,7 +344,7 @@
 read_all(#json_protocol{transport = Transport0} = State) ->
     {Transport1, Bin} = read_all_1(Transport0, []),
     P = thrift_json_parser:parser(),
-    [First|Rest] = P(Bin),
+    [First | Rest] = P(Bin),
     State#json_protocol{
         transport = Transport1,
         jsx = {event, First, Rest}
@@ -336,11 +353,14 @@
 read_all_1(Transport0, IoList) ->
     {Transport1, Result} = thrift_transport:read(Transport0, 1),
     case Result of
-        {ok, <<>>} -> % nothing read: assume we're done
+        % nothing read: assume we're done
+        {ok, <<>>} ->
             {Transport1, iolist_to_binary(lists:reverse(IoList))};
-        {ok, Data} -> % character successfully read; read more
-            read_all_1(Transport1, [Data|IoList]);
-        {error, 'EOF'} -> % we're done
+        % character successfully read; read more
+        {ok, Data} ->
+            read_all_1(Transport1, [Data | IoList]);
+        % we're done
+        {error, 'EOF'} ->
             {Transport1, iolist_to_binary(lists:reverse(IoList))}
     end.
 
@@ -348,17 +368,16 @@
 % type as input. Comparing the read event from the one is was passed, it
 % returns an error if something other than the expected value is encountered.
 % Expect also maintains the context stack in #json_protocol.
-expect(#json_protocol{jsx={event, {Type, Data}=Ev, [Next|Rest]}}=State, ExpectedType) ->
-    NextState = State#json_protocol{jsx={event, Next, Rest}},
+expect(#json_protocol{jsx = {event, {Type, Data} = Ev, [Next | Rest]}} = State, ExpectedType) ->
+    NextState = State#json_protocol{jsx = {event, Next, Rest}},
     case Type == ExpectedType of
-        true -> 
+        true ->
             {NextState, {ok, convert_data(Type, Data)}};
         false ->
             {NextState, {error, {unexpected_json_event, Ev}}}
     end;
-
-expect(#json_protocol{jsx={event, Event, Next}}=State, ExpectedEvent) ->
-     expect(State#json_protocol{jsx={event, {Event, none}, Next}}, ExpectedEvent).
+expect(#json_protocol{jsx = {event, Event, Next}} = State, ExpectedEvent) ->
+    expect(State#json_protocol{jsx = {event, {Event, none}, Next}}, ExpectedEvent).
 
 convert_data(integer, I) -> list_to_integer(I);
 convert_data(float, F) -> list_to_float(F);
@@ -369,9 +388,9 @@
 
 expect_many_1(State, [], ResultList, Status) ->
     {State, {Status, lists:reverse(ResultList)}};
-expect_many_1(State, [Expected|ExpTail], ResultList, _PrevStatus) ->
+expect_many_1(State, [Expected | ExpTail], ResultList, _PrevStatus) ->
     {State1, {Status, Data}} = expect(State, Expected),
-    NewResultList = [Data|ResultList],
+    NewResultList = [Data | ResultList],
     case Status of
         % in case of error, end prematurely
         error -> expect_many_1(State1, [], NewResultList, Status);
@@ -381,178 +400,202 @@
 % wrapper around expect to make life easier for container opening/closing functions
 expect_nodata(This, ExpectedList) ->
     case expect_many(This, ExpectedList) of
-        {State, {ok, _}} -> 
+        {State, {ok, _}} ->
             {State, ok};
-        Error -> 
+        Error ->
             Error
     end.
 
-read_field(#json_protocol{jsx={event, Field, [Next|Rest]}} = State) ->
-    NewState = State#json_protocol{jsx={event, Next, Rest}},
+read_field(#json_protocol{jsx = {event, Field, [Next | Rest]}} = State) ->
+    NewState = State#json_protocol{jsx = {event, Next, Rest}},
     {NewState, Field}.
 
 read(This0, message_begin) ->
     % call read_all to get the contents of the transport buffer into JSX.
     This1 = read_all(This0),
-    case expect_many(This1, 
-            [start_array, integer, string, integer, integer]) of
+    case
+        expect_many(
+            This1,
+            [start_array, integer, string, integer, integer]
+        )
+    of
         {This2, {ok, [_, Version, Name, Type, SeqId]}} ->
             case Version =:= ?VERSION_1 of
                 true ->
-                    {This2, #protocol_message_begin{name  = Name,
-                                                    type  = Type,
-                                                    seqid = SeqId}};
+                    {This2, #protocol_message_begin{
+                        name = Name,
+                        type = Type,
+                        seqid = SeqId
+                    }};
                 false ->
                     {This2, {error, no_json_protocol_version}}
             end;
-        Other -> Other
+        Other ->
+            Other
     end;
-
-read(This, message_end) -> 
+read(This, message_end) ->
     expect_nodata(This, [end_array]);
-
-read(This, struct_begin) -> 
+read(This, struct_begin) ->
     expect_nodata(This, [start_object]);
-
-read(This, struct_end) -> 
+read(This, struct_end) ->
     expect_nodata(This, [end_object]);
-
 read(This0, field_begin) ->
-    {This1, Read} = expect_many(This0, 
-            [%field id
-             key, 
-             % {} surrounding field
-             start_object, 
-             % type of field
-             key]),
+    {This1, Read} = expect_many(
+        This0,
+        %field id
+        [
+            key,
+            % {} surrounding field
+            start_object,
+            % type of field
+            key
+        ]
+    ),
     case Read of
         {ok, [FieldIdStr, _, FieldType]} ->
             {This1, #protocol_field_begin{
-                type = json_to_typeid(FieldType), 
-                id = list_to_integer(FieldIdStr)}}; % TODO: do we need to wrap this in a try/catch?
-        {error,[{unexpected_json_event, {end_object,none}}]} ->
+                type = json_to_typeid(FieldType),
+                % TODO: do we need to wrap this in a try/catch?
+                id = list_to_integer(FieldIdStr)
+            }};
+        {error, [{unexpected_json_event, {end_object, none}}]} ->
             {This1, #protocol_field_begin{type = ?tType_STOP}};
-        Other -> 
+        Other ->
             io:format("**** OTHER branch selected ****"),
             {This1, Other}
     end;
-
-read(This, field_end) -> 
+read(This, field_end) ->
     expect_nodata(This, [end_object]);
-
 % Example message with map: [1,"testMap",1,0,{"1":{"map":["i32","i32",3,{"7":77,"8":88,"9":99}]}}]
 read(This0, map_begin) ->
-    case expect_many(This0, 
-            [start_array,
-             % key type
-             string, 
-             % value type
-             string, 
-             % size
-             integer,
-             % the following object contains the map
-             start_object]) of
+    case
+        expect_many(
+            This0,
+            [
+                start_array,
+                % key type
+                string,
+                % value type
+                string,
+                % size
+                integer,
+                % the following object contains the map
+                start_object
+            ]
+        )
+    of
         {This1, {ok, [_, Ktype, Vtype, Size, _]}} ->
-            {This1, #protocol_map_begin{ktype = Ktype,
-                                vtype = Vtype,
-                                size = Size}};
-        Other -> Other
+            {This1, #protocol_map_begin{
+                ktype = Ktype,
+                vtype = Vtype,
+                size = Size
+            }};
+        Other ->
+            Other
     end;
-
-read(This, map_end) -> 
+read(This, map_end) ->
     expect_nodata(This, [end_object, end_array]);
-
 read(This0, list_begin) ->
-    case expect_many(This0, 
-            [start_array,
-             % element type
-             string, 
-             % size
-             integer]) of
+    case
+        expect_many(
+            This0,
+            [
+                start_array,
+                % element type
+                string,
+                % size
+                integer
+            ]
+        )
+    of
         {This1, {ok, [_, Etype, Size]}} ->
             {This1, #protocol_list_begin{
                 etype = Etype,
-                size = Size}};
-        Other -> Other
+                size = Size
+            }};
+        Other ->
+            Other
     end;
-
-read(This, list_end) -> 
+read(This, list_end) ->
     expect_nodata(This, [end_array]);
-
 % example message with set: [1,"testSet",1,0,{"1":{"set":["i32",3,1,2,3]}}]
 read(This0, set_begin) ->
-    case expect_many(This0, 
-            [start_array,
-             % element type
-             string, 
-             % size
-             integer]) of
+    case
+        expect_many(
+            This0,
+            [
+                start_array,
+                % element type
+                string,
+                % size
+                integer
+            ]
+        )
+    of
         {This1, {ok, [_, Etype, Size]}} ->
             {This1, #protocol_set_begin{
                 etype = Etype,
-                size = Size}};
-        Other -> Other
+                size = Size
+            }};
+        Other ->
+            Other
     end;
-
-read(This, set_end) -> 
+read(This, set_end) ->
     expect_nodata(This, [end_array]);
-
 read(This0, field_stop) ->
     {This0, ok};
 %%
 
 read(This0, bool) ->
     {This1, Field} = read_field(This0),
-    Value = case Field of
-        {literal, I} -> 
-            {ok, I}; 
-        _Other ->
-            {error, unexpected_event_for_boolean}
-    end,
+    Value =
+        case Field of
+            {literal, I} ->
+                {ok, I};
+            _Other ->
+                {error, unexpected_event_for_boolean}
+        end,
     {This1, Value};
-
 read(This0, byte) ->
     {This1, Field} = read_field(This0),
-    Value = case Field of
-        {key, K} ->
-            {ok, list_to_integer(K)};
-        {integer, I} -> 
-            {ok, list_to_integer(I)}; 
-        _Other ->
-            {error, unexpected_event_for_integer}
-    end,
+    Value =
+        case Field of
+            {key, K} ->
+                {ok, list_to_integer(K)};
+            {integer, I} ->
+                {ok, list_to_integer(I)};
+            _Other ->
+                {error, unexpected_event_for_integer}
+        end,
     {This1, Value};
-
 read(This0, i16) ->
     read(This0, byte);
-
 read(This0, i32) ->
     read(This0, byte);
-
 read(This0, i64) ->
     read(This0, byte);
-
 read(This0, double) ->
     {This1, Field} = read_field(This0),
-    Value = case Field of
-        {float, I} -> 
-            {ok, list_to_float(I)}; 
-        _Other ->
-            {error, unexpected_event_for_double}
-    end,
+    Value =
+        case Field of
+            {float, I} ->
+                {ok, list_to_float(I)};
+            _Other ->
+                {error, unexpected_event_for_double}
+        end,
     {This1, Value};
-
 % returns a binary directly, call binary_to_list if necessary
 read(This0, string) ->
     {This1, Field} = read_field(This0),
-    Value = case Field of
-        {string, I} -> 
-            {ok, I}; 
-        {key, J} -> 
-            {ok, J}; 
-        _Other ->
-            {error, unexpected_event_for_string}
-    end,
+    Value =
+        case Field of
+            {string, I} ->
+                {ok, I};
+            {key, J} ->
+                {ok, J};
+            _Other ->
+                {error, unexpected_event_for_string}
+        end,
     {This1, Value}.
 
 %%%% FACTORY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -561,7 +604,7 @@
 new_protocol_factory(TransportFactory, _Options) ->
     % Only strice read/write are implemented
     F = fun() ->
-                {ok, Transport} = TransportFactory(),
-                thrift_json_protocol:new(Transport, [])
-        end,
+        {ok, Transport} = TransportFactory(),
+        thrift_json_protocol:new(Transport, [])
+    end,
     {ok, F}.
diff --git a/lib/erl/src/thrift_membuffer_transport.erl b/lib/erl/src/thrift_membuffer_transport.erl
index be9acb2..df23b03 100644
--- a/lib/erl/src/thrift_membuffer_transport.erl
+++ b/lib/erl/src/thrift_membuffer_transport.erl
@@ -22,62 +22,55 @@
 -behaviour(thrift_transport).
 
 %% constructors
--export([new/0, new/1]).
+-export([new/0, new/1, new/2]).
 %% protocol callbacks
 -export([read/2, read_exact/2, write/2, flush/1, close/1]).
 
-
 -record(t_membuffer, {
-  buffer = []
+    buffer = [] :: iodata()
 }).
 
--type state() :: #t_membuffer{}.
-
-
--spec new() -> thrift_transport:t_transport().
+-spec new() -> {ok, thrift_transport:t_transport()}.
 
 new() -> new([]).
 
--spec new(Buf::iodata()) -> thrift_transport:t_transport().
+-spec new(Buf :: iodata()) -> {ok, thrift_transport:t_transport()}.
 
-new(Buf) when is_list(Buf) ->
-  State = #t_membuffer{buffer = Buf},
-  thrift_transport:new(?MODULE, State);
-new(Buf) when is_binary(Buf) ->
-  State = #t_membuffer{buffer = [Buf]},
-  thrift_transport:new(?MODULE, State).
+new(Buf) ->
+    new(Buf, []).
 
+new(Buf, _Opts) when is_list(Buf) ->
+    State = #t_membuffer{buffer = Buf},
+    thrift_transport:new(?MODULE, State);
+new(Buf, _Opts) when is_binary(Buf) ->
+    State = #t_membuffer{buffer = [Buf]},
+    thrift_transport:new(?MODULE, State).
 
--include("thrift_transport_behaviour.hrl").
+read(State = #t_membuffer{buffer = Buf}, Len) when
+    is_integer(Len), Len >= 0
+->
+    Binary = iolist_to_binary(Buf),
+    Give = min(iolist_size(Binary), Len),
+    {Result, Remaining} = split_binary(Binary, Give),
+    {State#t_membuffer{buffer = Remaining}, {ok, Result}}.
 
+read_exact(State = #t_membuffer{buffer = Buf}, Len) when
+    is_integer(Len), Len >= 0
+->
+    Binary = iolist_to_binary(Buf),
+    case iolist_size(Binary) of
+        X when X >= Len ->
+            {Result, Remaining} = split_binary(Binary, Len),
+            {State#t_membuffer{buffer = Remaining}, {ok, Result}};
+        _ ->
+            {State, {error, eof}}
+    end.
 
-read(State = #t_membuffer{buffer = Buf}, Len)
-when is_integer(Len), Len >= 0 ->
-  Binary = iolist_to_binary(Buf),
-  Give = min(iolist_size(Binary), Len),
-  {Result, Remaining} = split_binary(Binary, Give),
-  {State#t_membuffer{buffer = Remaining}, {ok, Result}}.
-
-
-read_exact(State = #t_membuffer{buffer = Buf}, Len)
-when is_integer(Len), Len >= 0 ->
-  Binary = iolist_to_binary(Buf),
-  case iolist_size(Binary) of
-    X when X >= Len ->
-      {Result, Remaining} = split_binary(Binary, Len),
-      {State#t_membuffer{buffer = Remaining}, {ok, Result}};
-    _ ->
-      {State, {error, eof}}
-  end.
-
-
-write(State = #t_membuffer{buffer = Buf}, Data)
-when is_list(Data); is_binary(Data) ->
-  {State#t_membuffer{buffer = [Buf, Data]}, ok}.
-
+write(State = #t_membuffer{buffer = Buf}, Data) when
+    is_list(Data); is_binary(Data)
+->
+    {State#t_membuffer{buffer = [Buf, Data]}, ok}.
 
 flush(State) -> {State, ok}.
 
-
 close(State) -> {State, ok}.
-
diff --git a/lib/erl/src/thrift_memory_buffer.erl b/lib/erl/src/thrift_memory_buffer.erl
index 6a59ea5..3007f73 100644
--- a/lib/erl/src/thrift_memory_buffer.erl
+++ b/lib/erl/src/thrift_memory_buffer.erl
@@ -28,7 +28,6 @@
 %% legacy api
 -export([new_transport_factory/0]).
 
-
 %% wrapper around thrift_membuffer_transport for legacy reasons
 
 new() -> thrift_membuffer_transport:new().
@@ -44,4 +43,3 @@
 flush(State) -> thrift_membuffer_transport:flush(State).
 
 close(State) -> thrift_membuffer_transport:close(State).
-
diff --git a/lib/erl/src/thrift_multiplexed_map_wrapper.erl b/lib/erl/src/thrift_multiplexed_map_wrapper.erl
index 34c5e95..706aaf7 100644
--- a/lib/erl/src/thrift_multiplexed_map_wrapper.erl
+++ b/lib/erl/src/thrift_multiplexed_map_wrapper.erl
@@ -20,15 +20,15 @@
 -module(thrift_multiplexed_map_wrapper).
 
 -export([
-          new/0
-         ,store/3
-         ,find/2
-         ,fetch/2
-        ]).
+    new/0,
+    store/3,
+    find/2,
+    fetch/2
+]).
 
--type service_handler()     :: nonempty_string().
--type module_()             :: atom().
--type service_handler_map() :: [{ServiceHandler::service_handler(), Module::module_()}].
+-type service_handler() :: nonempty_string().
+-type service_handler_map() :: orddict:orddict(service_handler(), [module()]).
+-export_type([service_handler_map/0]).
 
 -spec new() -> service_handler_map().
 new() ->
@@ -36,22 +36,22 @@
 
 -spec store(ServiceHandler, Module, Map) -> NewMap when
     ServiceHandler :: service_handler(),
-    Module         :: module_(),
-    Map            :: service_handler_map(),
-    NewMap         :: service_handler_map().
+    Module :: module(),
+    Map :: service_handler_map(),
+    NewMap :: service_handler_map().
 store(ServiceHandler, Module, Map) ->
     orddict:store(ServiceHandler, Module, Map).
 
 -spec find(ServiceHandler, Map) -> {ok, Module} | error when
     ServiceHandler :: service_handler(),
-    Module         :: module_(),
-    Map            :: service_handler_map().
+    Module :: module(),
+    Map :: service_handler_map().
 find(ServiceHandler, Map) ->
     orddict:find(ServiceHandler, Map).
 
 -spec fetch(ServiceHandler, Map) -> Module when
     ServiceHandler :: service_handler(),
-    Module         :: module_(),
-    Map            :: service_handler_map().
+    Module :: module(),
+    Map :: service_handler_map().
 fetch(ServiceHandler, Map) ->
     orddict:fetch(ServiceHandler, Map).
diff --git a/lib/erl/src/thrift_multiplexed_protocol.erl b/lib/erl/src/thrift_multiplexed_protocol.erl
index 5f7b70c..ddc9475 100644
--- a/lib/erl/src/thrift_multiplexed_protocol.erl
+++ b/lib/erl/src/thrift_multiplexed_protocol.erl
@@ -24,60 +24,91 @@
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
--include("thrift_protocol_behaviour.hrl").
+-export([
+    new/2,
+    read/2,
+    write/2,
+    flush_transport/1,
+    close_transport/1
+]).
 
--export([new/2,
-         read/2,
-         write/2,
-         flush_transport/1,
-         close_transport/1
-        ]).
-
--record(protocol, {module, data}).
+-record(protocol, {
+    module :: module(),
+    data :: term()
+}).
 -type protocol() :: #protocol{}.
 
--record (multiplexed_protocol, {protocol_module_to_decorate::atom(),
-								protocol_data_to_decorate::term(),
-								service_name::nonempty_string()}).
+-record(multiplexed_protocol, {
+    protocol_module_to_decorate :: atom(),
+    protocol_data_to_decorate :: term(),
+    service_name :: nonempty_string()
+}).
 
--type state() :: #multiplexed_protocol{}.
-
--spec new(ProtocolToDecorate::protocol(), ServiceName::nonempty_string()) -> {ok, Protocol::protocol()}.
-new(ProtocolToDecorate, ServiceName) when is_record(ProtocolToDecorate, protocol),
-                                          is_list(ServiceName) ->
-    State = #multiplexed_protocol{protocol_module_to_decorate = ProtocolToDecorate#protocol.module,
-                                    protocol_data_to_decorate = ProtocolToDecorate#protocol.data,
-                                                 service_name = ServiceName},
+-spec new(ProtocolToDecorate :: protocol(), ServiceName :: nonempty_string()) ->
+    {ok, Protocol :: protocol()}.
+new(ProtocolToDecorate, ServiceName) when
+    is_record(ProtocolToDecorate, protocol),
+    is_list(ServiceName)
+->
+    State = #multiplexed_protocol{
+        protocol_module_to_decorate = ProtocolToDecorate#protocol.module,
+        protocol_data_to_decorate = ProtocolToDecorate#protocol.data,
+        service_name = ServiceName
+    },
     thrift_protocol:new(?MODULE, State).
 
-flush_transport(State = #multiplexed_protocol{protocol_module_to_decorate = ProtocolModuleToDecorate,
-                                                protocol_data_to_decorate = State0}) ->
+flush_transport(
+    State = #multiplexed_protocol{
+        protocol_module_to_decorate = ProtocolModuleToDecorate,
+        protocol_data_to_decorate = State0
+    }
+) ->
     {State1, ok} = ProtocolModuleToDecorate:flush_transport(State0),
     {State#multiplexed_protocol{protocol_data_to_decorate = State1}, ok}.
 
-close_transport(State = #multiplexed_protocol{protocol_module_to_decorate = ProtocolModuleToDecorate,
-                                                protocol_data_to_decorate = State0}) ->
+close_transport(
+    State = #multiplexed_protocol{
+        protocol_module_to_decorate = ProtocolModuleToDecorate,
+        protocol_data_to_decorate = State0
+    }
+) ->
     {State1, ok} = ProtocolModuleToDecorate:close_transport(State0),
     {State#multiplexed_protocol{protocol_data_to_decorate = State1}, ok}.
 
-write(State = #multiplexed_protocol{protocol_module_to_decorate = ProtocolModuleToDecorate,
-                                      protocol_data_to_decorate = State0,
-                                                   service_name = ServiceName},
-      Message = #protocol_message_begin{name = Name}) ->
-    {State1, ok} = ProtocolModuleToDecorate:write(State0,
-                                                  Message#protocol_message_begin{name=ServiceName ++
-                                                                                      ?MULTIPLEXED_SERVICE_SEPARATOR ++
-                                                                                      Name}),
+write(
+    State = #multiplexed_protocol{
+        protocol_module_to_decorate = ProtocolModuleToDecorate,
+        protocol_data_to_decorate = State0,
+        service_name = ServiceName
+    },
+    Message = #protocol_message_begin{name = Name}
+) ->
+    {State1, ok} = ProtocolModuleToDecorate:write(
+        State0,
+        Message#protocol_message_begin{
+            name =
+                ServiceName ++
+                    ?MULTIPLEXED_SERVICE_SEPARATOR ++
+                    Name
+        }
+    ),
     {State#multiplexed_protocol{protocol_data_to_decorate = State1}, ok};
-
-write(State = #multiplexed_protocol{protocol_module_to_decorate = ProtocolModuleToDecorate,
-                                      protocol_data_to_decorate = State0},
-      Message) ->
+write(
+    State = #multiplexed_protocol{
+        protocol_module_to_decorate = ProtocolModuleToDecorate,
+        protocol_data_to_decorate = State0
+    },
+    Message
+) ->
     {State1, ok} = ProtocolModuleToDecorate:write(State0, Message),
     {State#multiplexed_protocol{protocol_data_to_decorate = State1}, ok}.
 
-read(State = #multiplexed_protocol{protocol_module_to_decorate = ProtocolModuleToDecorate,
-                                     protocol_data_to_decorate = State0},
-     Message) ->
+read(
+    State = #multiplexed_protocol{
+        protocol_module_to_decorate = ProtocolModuleToDecorate,
+        protocol_data_to_decorate = State0
+    },
+    Message
+) ->
     {State1, Result} = ProtocolModuleToDecorate:read(State0, Message),
     {State#multiplexed_protocol{protocol_data_to_decorate = State1}, Result}.
diff --git a/lib/erl/src/thrift_processor.erl b/lib/erl/src/thrift_processor.erl
index 5c9f26f..e17eadb 100644
--- a/lib/erl/src/thrift_processor.erl
+++ b/lib/erl/src/thrift_processor.erl
@@ -24,71 +24,101 @@
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
--record(thrift_processor, {handler, protocol, service}).
+-record(thrift_processor, {
+    handler :: module(),
+    protocol :: term(),
+    service :: atom()
+}).
 
 init({_Server, ProtoGen, Service, Handler}) when is_function(ProtoGen, 0) ->
     {ok, Proto} = ProtoGen(),
-    loop(#thrift_processor{protocol = Proto,
-                           service = Service,
-                           handler = Handler}).
+    loop(#thrift_processor{
+        protocol = Proto,
+        service = Service,
+        handler = Handler
+    }).
 
-loop(State0 = #thrift_processor{protocol  = Proto0,
-                                handler = Handler,
-                                service = Service}) ->
-
+loop(
+    State0 = #thrift_processor{
+        protocol = Proto0,
+        handler = Handler,
+        service = Service
+    }
+) ->
     {Proto1, MessageBegin} = thrift_protocol:read(Proto0, message_begin),
     State1 = State0#thrift_processor{protocol = Proto1},
 
     ErrorHandler = fun
-        (HandlerModules) when is_list(HandlerModules) -> thrift_multiplexed_map_wrapper:fetch(?MULTIPLEXED_ERROR_HANDLER_KEY, HandlerModules);
-        (HandlerModule) -> HandlerModule
+        (HandlerModules) when is_list(HandlerModules) ->
+            thrift_multiplexed_map_wrapper:fetch(?MULTIPLEXED_ERROR_HANDLER_KEY, HandlerModules);
+        (HandlerModule) ->
+            HandlerModule
     end,
 
     case MessageBegin of
-
-        #protocol_message_begin{name = Function,
-                                type = Type,
-                                seqid = Seqid} when Type =:= ?tMessageType_CALL; Type =:= ?tMessageType_ONEWAY ->
+        #protocol_message_begin{
+            name = Function,
+            type = Type,
+            seqid = Seqid
+        } when Type =:= ?tMessageType_CALL; Type =:= ?tMessageType_ONEWAY ->
             case string:tokens(Function, ?MULTIPLEXED_SERVICE_SEPARATOR) of
                 [ServiceName, FunctionName] ->
-                    ServiceModule  = thrift_multiplexed_map_wrapper:fetch(ServiceName, Service),
+                    ServiceModule = thrift_multiplexed_map_wrapper:fetch(ServiceName, Service),
                     ServiceHandler = thrift_multiplexed_map_wrapper:fetch(ServiceName, Handler),
-                    case handle_function(State1#thrift_processor{service=ServiceModule, handler=ServiceHandler}, list_to_atom(FunctionName), Seqid) of
-                        {State2, ok} -> loop(State2#thrift_processor{service=Service, handler=Handler});
+                    case
+                        handle_function(
+                            State1#thrift_processor{
+                                service = ServiceModule, handler = ServiceHandler
+                            },
+                            list_to_existing_atom(FunctionName),
+                            Seqid
+                        )
+                    of
+                        {State2, ok} ->
+                            loop(State2#thrift_processor{service = Service, handler = Handler});
                         {_State2, {error, Reason}} ->
-							apply(ErrorHandler(Handler), handle_error, [list_to_atom(Function), Reason]),
+                            apply(ErrorHandler(Handler), handle_error, [
+                                list_to_existing_atom(Function), Reason
+                            ]),
                             thrift_protocol:close_transport(Proto1),
                             ok
                     end;
                 _ ->
-                    case handle_function(State1, list_to_atom(Function), Seqid) of
-                        {State2, ok} -> loop(State2);
+                    case handle_function(State1, list_to_existing_atom(Function), Seqid) of
+                        {State2, ok} ->
+                            loop(State2);
                         {_State2, {error, Reason}} ->
-							apply(ErrorHandler(Handler), handle_error, [list_to_atom(Function), Reason]),
+                            apply(ErrorHandler(Handler), handle_error, [
+                                list_to_existing_atom(Function), Reason
+                            ]),
                             thrift_protocol:close_transport(Proto1),
                             ok
                     end
             end;
         {error, timeout = Reason} ->
-			apply(ErrorHandler(Handler), handle_error, [undefined, Reason]),
+            apply(ErrorHandler(Handler), handle_error, [undefined, Reason]),
             thrift_protocol:close_transport(Proto1),
             ok;
         {error, closed = Reason} ->
             %% error_logger:info_msg("Client disconnected~n"),
-			apply(ErrorHandler(Handler), handle_error, [undefined, Reason]),
+            apply(ErrorHandler(Handler), handle_error, [undefined, Reason]),
             thrift_protocol:close_transport(Proto1),
             exit(shutdown);
         {error, Reason} ->
-			apply(ErrorHandler(Handler), handle_error, [undefined, Reason]),
+            apply(ErrorHandler(Handler), handle_error, [undefined, Reason]),
             thrift_protocol:close_transport(Proto1),
             exit(shutdown)
     end.
 
-handle_function(State0=#thrift_processor{protocol = Proto0,
-                                         handler = Handler,
-                                         service = Service},
-                Function,
-                Seqid) ->
+handle_function(
+    State0 = #thrift_processor{
+        protocol = Proto0,
+        handler = Handler,
+        service = Service
+    },
+    Function,
+    Seqid
+) ->
     InParams = Service:function_info(Function, params_type),
 
     {Proto1, {ok, Params}} = thrift_protocol:read(Proto0, InParams),
@@ -101,55 +131,63 @@
         %%                       [Function, Params, Micro/1000.0]),
         handle_success(State1, Function, Result, Seqid)
     catch
-        Type:Data when Type =:= throw orelse Type =:= error ->
-            handle_function_catch(State1, Function, Type, Data, Seqid)
+        Type:Data:Stack when Type =:= throw orelse Type =:= error ->
+            handle_function_catch(State1, Function, Type, Data, Seqid, Stack)
     end.
 
-handle_function_catch(State = #thrift_processor{service = Service},
-                      Function, ErrType, ErrData, Seqid) ->
+handle_function_catch(
+    State = #thrift_processor{service = Service},
+    Function,
+    ErrType,
+    ErrData,
+    Seqid,
+    Stack
+) ->
     IsOneway = Service:function_info(Function, reply_type) =:= oneway_void,
 
     case {ErrType, ErrData} of
         _ when IsOneway ->
-            Stack = erlang:get_stacktrace(),
             error_logger:warning_msg(
-              "oneway void ~p threw error which must be ignored: ~p",
-              [Function, {ErrType, ErrData, Stack}]),
+                "oneway void ~p threw error which must be ignored: ~p",
+                [Function, {ErrType, ErrData, Stack}]
+            ),
             {State, ok};
-
         {throw, Exception} when is_tuple(Exception), size(Exception) > 0 ->
             %error_logger:warning_msg("~p threw exception: ~p~n", [Function, Exception]),
-            handle_exception(State, Function, Exception, Seqid);
-            % we still want to accept more requests from this client
+            handle_exception(State, Function, Exception, Seqid, Stack);
+        % we still want to accept more requests from this client
 
         {error, Error} ->
-            handle_error(State, Function, Error, Seqid)
+            handle_error(State, Function, Error, Seqid, Stack)
     end.
 
-handle_success(State = #thrift_processor{service = Service},
-               Function,
-               Result,
-               Seqid) ->
-    ReplyType  = Service:function_info(Function, reply_type),
+handle_success(
+    State = #thrift_processor{service = Service},
+    Function,
+    Result,
+    Seqid
+) ->
+    ReplyType = Service:function_info(Function, reply_type),
     StructName = atom_to_list(Function) ++ "_result",
 
     case Result of
         {reply, ReplyData} ->
             Reply = {{struct, [{0, ReplyType}]}, {StructName, ReplyData}},
             send_reply(State, Function, ?tMessageType_REPLY, Reply, Seqid);
-
         ok when ReplyType == {struct, []} ->
             send_reply(State, Function, ?tMessageType_REPLY, {ReplyType, {StructName}}, Seqid);
-
         ok when ReplyType == oneway_void ->
             %% no reply for oneway void
             {State, ok}
     end.
 
-handle_exception(State = #thrift_processor{service = Service},
-                 Function,
-                 Exception,
-                 Seqid) ->
+handle_exception(
+    State = #thrift_processor{service = Service},
+    Function,
+    Exception,
+    Seqid,
+    Stack
+) ->
     ExceptionType = element(1, Exception),
     %% Fetch a structure like {struct, [{-2, {struct, {Module, Type}}},
     %%                                  {-3, {struct, {Module, Type}}}]}
@@ -161,18 +199,20 @@
 
     %% Assuming we had a type1 exception, we'd get: [undefined, Exception, undefined]
     %% e.g.: [{-1, type0}, {-2, type1}, {-3, type2}]
-    ExceptionList = [case Type of
-                         ExceptionType -> Exception;
-                         _ -> undefined
-                     end
-                     || {_Fid, {struct, {_Module, Type}}} <- XInfo],
+    ExceptionList = [
+        case Type of
+            ExceptionType -> Exception;
+            _ -> undefined
+        end
+     || {_Fid, {struct, {_Module, Type}}} <- XInfo
+    ],
 
     ExceptionTuple = list_to_tuple([Function | ExceptionList]),
 
-                                                % Make sure we got at least one defined
+    % Make sure we got at least one defined
     case lists:all(fun(X) -> X =:= undefined end, ExceptionList) of
         true ->
-            handle_unknown_exception(State, Function, Exception, Seqid);
+            handle_unknown_exception(State, Function, Exception, Seqid, Stack);
         false ->
             send_reply(State, Function, ?tMessageType_REPLY, {ReplySpec, ExceptionTuple}, Seqid)
     end.
@@ -181,34 +221,38 @@
 %% Called when an exception has been explicitly thrown by the service, but it was
 %% not one of the exceptions that was defined for the function.
 %%
-handle_unknown_exception(State, Function, Exception, Seqid) ->
-    handle_error(State, Function, {exception_not_declared_as_thrown,
-                                   Exception}, Seqid).
+handle_unknown_exception(State, Function, Exception, Seqid, Stack) ->
+    handle_error(State, Function, {exception_not_declared_as_thrown, Exception}, Seqid, Stack).
 
-handle_error(State, Function, Error, Seqid) ->
-    Stack = erlang:get_stacktrace(),
+handle_error(State, Function, Error, Seqid, Stack) ->
     error_logger:error_msg("~p had an error: ~p~n", [Function, {Error, Stack}]),
 
     Message =
         case application:get_env(thrift, exceptions_include_traces) of
             {ok, true} ->
-                lists:flatten(io_lib:format("An error occurred: ~p~n",
-                                            [{Error, Stack}]));
+                lists:flatten(
+                    io_lib:format(
+                        "An error occurred: ~p~n",
+                        [{Error, Stack}]
+                    )
+                );
             _ ->
                 "An unknown handler error occurred."
         end,
-    Reply = {?TApplicationException_Structure,
-             #'TApplicationException'{
-                message = Message,
-                type = ?TApplicationException_UNKNOWN}},
+    Reply =
+        {?TApplicationException_Structure, #'TApplicationException'{
+            message = Message,
+            type = ?TApplicationException_UNKNOWN
+        }},
     send_reply(State, Function, ?tMessageType_EXCEPTION, Reply, Seqid).
 
 send_reply(State = #thrift_processor{protocol = Proto0}, Function, ReplyMessageType, Reply, Seqid) ->
     try
         {Proto1, ok} = thrift_protocol:write(Proto0, #protocol_message_begin{
-                                               name = atom_to_list(Function),
-                                               type = ReplyMessageType,
-                                               seqid = Seqid}),
+            name = atom_to_list(Function),
+            type = ReplyMessageType,
+            seqid = Seqid
+        }),
         {Proto2, ok} = thrift_protocol:write(Proto1, Reply),
         {Proto3, ok} = thrift_protocol:write(Proto2, message_end),
         {Proto4, ok} = thrift_protocol:flush_transport(Proto3),
diff --git a/lib/erl/src/thrift_protocol.erl b/lib/erl/src/thrift_protocol.erl
index 2fe10d6..c75712a 100644
--- a/lib/erl/src/thrift_protocol.erl
+++ b/lib/erl/src/thrift_protocol.erl
@@ -19,45 +19,67 @@
 
 -module(thrift_protocol).
 
--export([new/2,
-         write/2,
-         read/2,
-         read/3,
-         skip/2,
-         flush_transport/1,
-         close_transport/1,
-         typeid_to_atom/1
-        ]).
-
--export([behaviour_info/1]).
+-export([
+    new/2,
+    write/2,
+    read/2,
+    read/3,
+    skip/2,
+    flush_transport/1,
+    close_transport/1,
+    typeid_to_atom/1
+]).
 
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
--record(protocol, {module, data}).
+-record(protocol, {
+    module :: module(),
+    data :: term()
+}).
 
-behaviour_info(callbacks) ->
-    [
-     {read, 2},
-     {write, 2},
-     {flush_transport, 1},
-     {close_transport, 1}
-    ];
-behaviour_info(_Else) -> undefined.
+%%%=========================================================================
+%%%  API
+%%%=========================================================================
+-type state() :: term().
+-export_type([state/0]).
+-type reason() :: term().
+-export_type([reason/0]).
+
+%% NOTE: keep this in sync with read/2 spec
+-callback read
+    (state(), {struct, _Info}) -> {state(), {ok, tuple()} | {error, reason()}};
+    (state(), tprot_cont_tag()) -> {state(), {ok, any()} | {error, reason()}};
+    (state(), tprot_empty_tag()) -> {state(), ok | {error, reason()}};
+    (state(), tprot_header_tag()) -> {state(), tprot_header_val() | {error, reason()}};
+    (state(), tprot_data_tag()) -> {state(), {ok, any()} | {error, reason()}}.
+
+-callback write(state(), any()) -> {state(), ok | {error, reason()}}.
+
+-callback flush_transport(state()) -> {state(), ok | {error, reason()}}.
+-callback close_transport(state()) -> {state(), ok | {error, reason()}}.
 
 new(Module, Data) when is_atom(Module) ->
-    {ok, #protocol{module = Module,
-                   data = Data}}.
+    {ok, #protocol{
+        module = Module,
+        data = Data
+    }}.
 
 -spec flush_transport(#protocol{}) -> {#protocol{}, ok}.
-flush_transport(Proto = #protocol{module = Module,
-                                  data = Data}) ->
+flush_transport(
+    Proto = #protocol{
+        module = Module,
+        data = Data
+    }
+) ->
     {NewData, Result} = Module:flush_transport(Data),
     {Proto#protocol{data = NewData}, Result}.
 
 -spec close_transport(#protocol{}) -> ok.
-close_transport(#protocol{module = Module,
-                          data = Data}) ->
+close_transport(#protocol{
+    module = Module,
+    data = Data
+}) ->
     Module:close_transport(Data).
 
 typeid_to_atom(?tType_STOP) -> field_stop;
@@ -91,103 +113,123 @@
 %% Structure is like:
 %%    [{Fid, Type}, ...]
 -spec read(#protocol{}, {struct, _StructDef}, atom()) -> {#protocol{}, {ok, tuple()}}.
-read(IProto0, {struct, Structure}, Tag)
-  when is_list(Structure), is_atom(Tag) ->
-
+read(IProto0, {struct, Structure}, Tag) when
+    is_list(Structure), is_atom(Tag)
+->
     % If we want a tagged tuple, we need to offset all the tuple indices
     % by 1 to avoid overwriting the tag.
-    Offset = if Tag =/= undefined -> 1; true -> 0 end,
-    IndexList = case length(Structure) of
-                    N when N > 0 -> lists:seq(1 + Offset, N + Offset);
-                    _ -> []
-                end,
+    Offset =
+        if
+            Tag =/= undefined -> 1;
+            true -> 0
+        end,
+    IndexList =
+        case length(Structure) of
+            N when N > 0 -> lists:seq(1 + Offset, N + Offset);
+            _ -> []
+        end,
 
-    SWithIndices = [{Fid, {Type, Index}} ||
-                       {{Fid, Type}, Index} <-
-                           lists:zip(Structure, IndexList)],
+    SWithIndices = [
+        {Fid, {Type, Index}}
+     || {{Fid, Type}, Index} <-
+            lists:zip(Structure, IndexList)
+    ],
     % Fid -> {Type, Index}
     SDict = dict:from_list(SWithIndices),
 
     {IProto1, ok} = read(IProto0, struct_begin),
     RTuple0 = erlang:make_tuple(length(Structure) + Offset, undefined),
-    RTuple1 = if Tag =/= undefined -> setelement(1, RTuple0, Tag);
-                 true              -> RTuple0
-              end,
+    RTuple1 =
+        if
+            Tag =/= undefined -> setelement(1, RTuple0, Tag);
+            true -> RTuple0
+        end,
 
     {IProto2, RTuple2} = read_struct_loop(IProto1, SDict, RTuple1),
     {IProto2, {ok, RTuple2}}.
 
-
-%% NOTE: Keep this in sync with thrift_protocol_behaviour:read
+%% NOTE: Keep this in sync with read callback
 -spec read
-        (#protocol{}, {struct, _Info}) ->    {#protocol{}, {ok, tuple()}      | {error, _Reason}};
-        (#protocol{}, tprot_cont_tag()) ->   {#protocol{}, {ok, any()}        | {error, _Reason}};
-        (#protocol{}, tprot_empty_tag()) ->  {#protocol{},  ok                | {error, _Reason}};
-        (#protocol{}, tprot_header_tag()) -> {#protocol{}, tprot_header_val() | {error, _Reason}};
-        (#protocol{}, tprot_data_tag()) ->   {#protocol{}, {ok, any()}        | {error, _Reason}}.
+    (#protocol{}, {struct, _Info}) -> {#protocol{}, {ok, tuple()} | {error, _Reason}};
+    (#protocol{}, tprot_cont_tag()) -> {#protocol{}, {ok, any()} | {error, _Reason}};
+    (#protocol{}, tprot_empty_tag()) -> {#protocol{}, ok | {error, _Reason}};
+    (#protocol{}, tprot_header_tag()) -> {#protocol{}, tprot_header_val() | {error, _Reason}};
+    (#protocol{}, tprot_data_tag()) -> {#protocol{}, {ok, any()} | {error, _Reason}}.
 
-read(IProto, {struct, {Module, StructureName}}) when is_atom(Module),
-                                                     is_atom(StructureName) ->
+read(IProto, {struct, {Module, StructureName}}) when
+    is_atom(Module),
+    is_atom(StructureName)
+->
     read(IProto, Module:struct_info(StructureName), StructureName);
-
-read(IProto, S={struct, Structure}) when is_list(Structure) ->
+read(IProto, S = {struct, Structure}) when is_list(Structure) ->
     read(IProto, S, undefined);
-
 read(IProto0, {list, Type}) ->
     {IProto1, #protocol_list_begin{etype = EType, size = Size}} =
         read(IProto0, list_begin),
     {EType, EType} = {term_to_typeid(Type), EType},
-    {List, IProto2} = lists:mapfoldl(fun(_, ProtoS0) ->
-                                             {ProtoS1, {ok, Item}} = read(ProtoS0, Type),
-                                             {Item, ProtoS1}
-                                     end,
-                                     IProto1,
-                                     lists:duplicate(Size, 0)),
+    {List, IProto2} = lists:mapfoldl(
+        fun(_, ProtoS0) ->
+            {ProtoS1, {ok, Item}} = read(ProtoS0, Type),
+            {Item, ProtoS1}
+        end,
+        IProto1,
+        lists:duplicate(Size, 0)
+    ),
     {IProto3, ok} = read(IProto2, list_end),
     {IProto3, {ok, List}};
-
 read(IProto0, {map, KeyType, ValType}) ->
     {IProto1, #protocol_map_begin{size = Size, ktype = KType, vtype = VType}} =
         read(IProto0, map_begin),
-    _ = case Size of
-      0 -> 0;
-      _ ->
-        {KType, KType} = {term_to_typeid(KeyType), KType},
-        {VType, VType} = {term_to_typeid(ValType), VType}
-    end,
-    {List, IProto2} = lists:mapfoldl(fun(_, ProtoS0) ->
-                                             {ProtoS1, {ok, Key}} = read(ProtoS0, KeyType),
-                                             {ProtoS2, {ok, Val}} = read(ProtoS1, ValType),
-                                             {{Key, Val}, ProtoS2}
-                                     end,
-                                     IProto1,
-                                     lists:duplicate(Size, 0)),
+    _ =
+        case Size of
+            0 ->
+                0;
+            _ ->
+                {KType, KType} = {term_to_typeid(KeyType), KType},
+                {VType, VType} = {term_to_typeid(ValType), VType}
+        end,
+    {List, IProto2} = lists:mapfoldl(
+        fun(_, ProtoS0) ->
+            {ProtoS1, {ok, Key}} = read(ProtoS0, KeyType),
+            {ProtoS2, {ok, Val}} = read(ProtoS1, ValType),
+            {{Key, Val}, ProtoS2}
+        end,
+        IProto1,
+        lists:duplicate(Size, 0)
+    ),
     {IProto3, ok} = read(IProto2, map_end),
     {IProto3, {ok, dict:from_list(List)}};
-
 read(IProto0, {set, Type}) ->
     {IProto1, #protocol_set_begin{etype = EType, size = Size}} =
         read(IProto0, set_begin),
     {EType, EType} = {term_to_typeid(Type), EType},
-    {List, IProto2} = lists:mapfoldl(fun(_, ProtoS0) ->
-                                             {ProtoS1, {ok, Item}} = read(ProtoS0, Type),
-                                             {Item, ProtoS1}
-                                     end,
-                                     IProto1,
-                                     lists:duplicate(Size, 0)),
+    {List, IProto2} = lists:mapfoldl(
+        fun(_, ProtoS0) ->
+            {ProtoS1, {ok, Item}} = read(ProtoS0, Type),
+            {Item, ProtoS1}
+        end,
+        IProto1,
+        lists:duplicate(Size, 0)
+    ),
     {IProto3, ok} = read(IProto2, set_end),
     {IProto3, {ok, sets:from_list(List)}};
-
 read(Protocol, ProtocolType) ->
     read_specific(Protocol, ProtocolType).
 
-%% NOTE: Keep this in sync with thrift_protocol_behaviour:read
+%% NOTE: Keep this in sync with read/2 spec
 -spec read_specific
-        (#protocol{}, tprot_empty_tag()) ->  {#protocol{},  ok                | {error, _Reason}};
-        (#protocol{}, tprot_header_tag()) -> {#protocol{}, tprot_header_val() | {error, _Reason}};
-        (#protocol{}, tprot_data_tag()) ->   {#protocol{}, {ok, any()}        | {error, _Reason}}.
-read_specific(Proto = #protocol{module = Module,
-                                data = ModuleData}, ProtocolType) ->
+    (#protocol{}, {struct, _Info}) -> {#protocol{}, {ok, tuple()} | {error, _Reason}};
+    (#protocol{}, tprot_cont_tag()) -> {#protocol{}, {ok, any()} | {error, _Reason}};
+    (#protocol{}, tprot_empty_tag()) -> {#protocol{}, ok | {error, _Reason}};
+    (#protocol{}, tprot_header_tag()) -> {#protocol{}, tprot_header_val() | {error, _Reason}};
+    (#protocol{}, tprot_data_tag()) -> {#protocol{}, {ok, any()} | {error, _Reason}}.
+read_specific(
+    Proto = #protocol{
+        module = Module,
+        data = ModuleData
+    },
+    ProtocolType
+) ->
     {NewData, Result} = Module:read(ModuleData, ProtocolType),
     {Proto#protocol{data = NewData}, Result}.
 
@@ -209,8 +251,9 @@
                             read_struct_loop(IProto3, SDict, NewRTuple);
                         Expected ->
                             error_logger:info_msg(
-                              "Skipping field ~p with wrong type (~p != ~p)~n",
-                              [Fid, FType, Expected]),
+                                "Skipping field ~p with wrong type (~p != ~p)~n",
+                                [Fid, FType, Expected]
+                            ),
                             skip_field(FType, IProto1, SDict, RTuple)
                     end;
                 _Else2 ->
@@ -230,30 +273,25 @@
     {Proto2, ok} = skip_struct_loop(Proto1),
     {Proto3, ok} = read(Proto2, struct_end),
     {Proto3, ok};
-
 skip(Proto0, map) ->
     {Proto1, Map} = read(Proto0, map_begin),
     {Proto2, ok} = skip_map_loop(Proto1, Map),
     {Proto3, ok} = read(Proto2, map_end),
     {Proto3, ok};
-
 skip(Proto0, set) ->
     {Proto1, Set} = read(Proto0, set_begin),
     {Proto2, ok} = skip_set_loop(Proto1, Set),
     {Proto3, ok} = read(Proto2, set_end),
     {Proto3, ok};
-
 skip(Proto0, list) ->
     {Proto1, List} = read(Proto0, list_begin),
     {Proto2, ok} = skip_list_loop(Proto1, List),
     {Proto3, ok} = read(Proto2, list_end),
     {Proto3, ok};
-
 skip(Proto0, Type) when is_atom(Type) ->
     {Proto1, _Ignore} = read(Proto0, Type),
     {Proto1, ok}.
 
-
 skip_struct_loop(Proto0) ->
     {Proto1, #protocol_field_begin{type = Type}} = read(Proto0, field_begin),
     case Type of
@@ -265,39 +303,62 @@
             skip_struct_loop(Proto3)
     end.
 
-skip_map_loop(Proto0, Map = #protocol_map_begin{ktype = Ktype,
-                                                vtype = Vtype,
-                                                size = Size}) ->
+skip_map_loop(
+    Proto0,
+    Map = #protocol_map_begin{
+        ktype = Ktype,
+        vtype = Vtype,
+        size = Size
+    }
+) ->
     case Size of
         N when N > 0 ->
             {Proto1, ok} = skip(Proto0, typeid_to_atom(Ktype)),
             {Proto2, ok} = skip(Proto1, typeid_to_atom(Vtype)),
-            skip_map_loop(Proto2,
-                          Map#protocol_map_begin{size = Size - 1});
-        0 -> {Proto0, ok}
+            skip_map_loop(
+                Proto2,
+                Map#protocol_map_begin{size = Size - 1}
+            );
+        0 ->
+            {Proto0, ok}
     end.
 
-skip_set_loop(Proto0, Map = #protocol_set_begin{etype = Etype,
-                                                size = Size}) ->
+skip_set_loop(
+    Proto0,
+    Map = #protocol_set_begin{
+        etype = Etype,
+        size = Size
+    }
+) ->
     case Size of
         N when N > 0 ->
             {Proto1, ok} = skip(Proto0, typeid_to_atom(Etype)),
-            skip_set_loop(Proto1,
-                          Map#protocol_set_begin{size = Size - 1});
-        0 -> {Proto0, ok}
+            skip_set_loop(
+                Proto1,
+                Map#protocol_set_begin{size = Size - 1}
+            );
+        0 ->
+            {Proto0, ok}
     end.
 
-skip_list_loop(Proto0, Map = #protocol_list_begin{etype = Etype,
-                                                  size = Size}) ->
+skip_list_loop(
+    Proto0,
+    Map = #protocol_list_begin{
+        etype = Etype,
+        size = Size
+    }
+) ->
     case Size of
         N when N > 0 ->
             {Proto1, ok} = skip(Proto0, typeid_to_atom(Etype)),
-            skip_list_loop(Proto1,
-                           Map#protocol_list_begin{size = Size - 1});
-        0 -> {Proto0, ok}
+            skip_list_loop(
+                Proto1,
+                Map#protocol_list_begin{size = Size - 1}
+            );
+        0 ->
+            {Proto0, ok}
     end.
 
-
 %%--------------------------------------------------------------------
 %% Function: write(OProto, {Type, Data}) -> ok
 %%
@@ -318,95 +379,112 @@
 %%--------------------------------------------------------------------
 -spec write(#protocol{}, any()) -> {#protocol{}, ok | {error, _Reason}}.
 
-write(Proto0, {{struct, StructDef}, Data})
-  when is_list(StructDef), is_tuple(Data), length(StructDef) == size(Data) - 1 ->
-
+write(Proto0, {{struct, StructDef}, Data}) when
+    is_list(StructDef), is_tuple(Data), length(StructDef) == size(Data) - 1
+->
     [StructName | Elems] = tuple_to_list(Data),
     {Proto1, ok} = write(Proto0, #protocol_struct_begin{name = StructName}),
     {Proto2, ok} = struct_write_loop(Proto1, StructDef, Elems),
     {Proto3, ok} = write(Proto2, struct_end),
     {Proto3, ok};
-
-write(Proto, {{struct, {Module, StructureName}}, Data})
-  when is_atom(Module),
-       is_atom(StructureName),
-       element(1, Data) =:= StructureName ->
+write(Proto, {{struct, {Module, StructureName}}, Data}) when
+    is_atom(Module),
+    is_atom(StructureName),
+    element(1, Data) =:= StructureName
+->
     write(Proto, {Module:struct_info(StructureName), Data});
-
-write(_, {{struct, {Module, StructureName}}, Data})
-  when is_atom(Module),
-       is_atom(StructureName) ->
-    erlang:error(struct_unmatched, {{provided, element(1, Data)},
-                             {expected, StructureName}});
-
-write(Proto0, {{list, Type}, Data})
-  when is_list(Data) ->
-    {Proto1, ok} = write(Proto0,
-               #protocol_list_begin{
-                 etype = term_to_typeid(Type),
-                 size = length(Data)
-                }),
-    Proto2 = lists:foldl(fun(Elem, ProtoIn) ->
-                                 {ProtoOut, ok} = write(ProtoIn, {Type, Elem}),
-                                 ProtoOut
-                         end,
-                         Proto1,
-                         Data),
+write(_, {{struct, {Module, StructureName}}, Data}) when
+    is_atom(Module),
+    is_atom(StructureName)
+->
+    erlang:error(struct_unmatched, {{provided, element(1, Data)}, {expected, StructureName}});
+write(Proto0, {{list, Type}, Data}) when
+    is_list(Data)
+->
+    {Proto1, ok} = write(
+        Proto0,
+        #protocol_list_begin{
+            etype = term_to_typeid(Type),
+            size = length(Data)
+        }
+    ),
+    Proto2 = lists:foldl(
+        fun(Elem, ProtoIn) ->
+            {ProtoOut, ok} = write(ProtoIn, {Type, Elem}),
+            ProtoOut
+        end,
+        Proto1,
+        Data
+    ),
     {Proto3, ok} = write(Proto2, list_end),
     {Proto3, ok};
-
 write(Proto0, {{map, KeyType, ValType}, Data}) ->
-    {Proto1, ok} = write(Proto0,
-                         #protocol_map_begin{
-                           ktype = term_to_typeid(KeyType),
-                           vtype = term_to_typeid(ValType),
-                           size  = dict:size(Data)
-                          }),
-    Proto2 = dict:fold(fun(KeyData, ValData, ProtoS0) ->
-                               {ProtoS1, ok} = write(ProtoS0, {KeyType, KeyData}),
-                               {ProtoS2, ok} = write(ProtoS1, {ValType, ValData}),
-                               ProtoS2
-                       end,
-                       Proto1,
-                       Data),
+    {Proto1, ok} = write(
+        Proto0,
+        #protocol_map_begin{
+            ktype = term_to_typeid(KeyType),
+            vtype = term_to_typeid(ValType),
+            size = dict:size(Data)
+        }
+    ),
+    Proto2 = dict:fold(
+        fun(KeyData, ValData, ProtoS0) ->
+            {ProtoS1, ok} = write(ProtoS0, {KeyType, KeyData}),
+            {ProtoS2, ok} = write(ProtoS1, {ValType, ValData}),
+            ProtoS2
+        end,
+        Proto1,
+        Data
+    ),
     {Proto3, ok} = write(Proto2, map_end),
     {Proto3, ok};
-
 write(Proto0, {{set, Type}, Data}) ->
     true = sets:is_set(Data),
-    {Proto1, ok} = write(Proto0,
-                         #protocol_set_begin{
-                           etype = term_to_typeid(Type),
-                           size  = sets:size(Data)
-                          }),
-    Proto2 = sets:fold(fun(Elem, ProtoIn) ->
-                               {ProtoOut, ok} = write(ProtoIn, {Type, Elem}),
-                               ProtoOut
-                       end,
-                       Proto1,
-                       Data),
+    {Proto1, ok} = write(
+        Proto0,
+        #protocol_set_begin{
+            etype = term_to_typeid(Type),
+            size = sets:size(Data)
+        }
+    ),
+    Proto2 = sets:fold(
+        fun(Elem, ProtoIn) ->
+            {ProtoOut, ok} = write(ProtoIn, {Type, Elem}),
+            ProtoOut
+        end,
+        Proto1,
+        Data
+    ),
     {Proto3, ok} = write(Proto2, set_end),
     {Proto3, ok};
-
-write(Proto = #protocol{module = Module,
-                        data = ModuleData}, Data) ->
+write(
+    Proto = #protocol{
+        module = Module,
+        data = ModuleData
+    },
+    Data
+) ->
     {NewData, Result} = Module:write(ModuleData, Data),
     {Proto#protocol{data = NewData}, Result}.
 
 struct_write_loop(Proto0, [{Fid, Type} | RestStructDef], [Data | RestData]) ->
-    NewProto = case Data of
-                   undefined ->
-                       Proto0; % null fields are skipped in response
-                   _ ->
-                       {Proto1, ok} = write(Proto0,
-                                           #protocol_field_begin{
-                                             type = term_to_typeid(Type),
-                                             id = Fid
-                                            }),
-                       {Proto2, ok} = write(Proto1, {Type, Data}),
-                       {Proto3, ok} = write(Proto2, field_end),
-                       Proto3
-               end,
+    NewProto =
+        case Data of
+            undefined ->
+                % null fields are skipped in response
+                Proto0;
+            _ ->
+                {Proto1, ok} = write(
+                    Proto0,
+                    #protocol_field_begin{
+                        type = term_to_typeid(Type),
+                        id = Fid
+                    }
+                ),
+                {Proto2, ok} = write(Proto1, {Type, Data}),
+                {Proto3, ok} = write(Proto2, field_end),
+                Proto3
+        end,
     struct_write_loop(NewProto, RestStructDef, RestData);
 struct_write_loop(Proto, [], []) ->
     write(Proto, field_stop).
diff --git a/lib/erl/src/thrift_reconnecting_client.erl b/lib/erl/src/thrift_reconnecting_client.erl
index 538fd3a..c9fe2aa 100644
--- a/lib/erl/src/thrift_reconnecting_client.erl
+++ b/lib/erl/src/thrift_reconnecting_client.erl
@@ -22,30 +22,36 @@
 -behaviour(gen_server).
 
 %% API
--export([ call/3,
-          get_stats/1,
-          get_and_reset_stats/1 ]).
+-export([
+    call/3,
+    get_stats/1,
+    get_and_reset_stats/1
+]).
 
--export([ start_link/6 ]).
+-export([start_link/6]).
 
 %% gen_server callbacks
--export([ init/1,
-          handle_call/3,
-          handle_cast/2,
-          handle_info/2,
-          terminate/2,
-          code_change/3 ]).
+-export([
+    init/1,
+    handle_call/3,
+    handle_cast/2,
+    handle_info/2,
+    terminate/2,
+    code_change/3
+]).
 
--record( state, { client = nil,
-                  host,
-                  port,
-                  thrift_svc,
-                  thrift_opts,
-                  reconn_min,
-                  reconn_max,
-                  reconn_time = 0,
-                  op_cnt_dict,
-                  op_time_dict } ).
+-record(state, {
+    client = nil,
+    host,
+    port,
+    thrift_svc,
+    thrift_opts,
+    reconn_min,
+    reconn_max,
+    reconn_time = 0,
+    op_cnt_dict,
+    op_time_dict
+}).
 
 %%====================================================================
 %% API
@@ -54,23 +60,35 @@
 %% Function: start_link() -> {ok,Pid} | ignore | {error,Error}
 %% Description: Starts the server
 %%--------------------------------------------------------------------
-start_link( Host, Port,
-            ThriftSvc, ThriftOpts,
-            ReconnMin, ReconnMax ) ->
-  gen_server:start_link( ?MODULE,
-                         [ Host, Port,
-                           ThriftSvc, ThriftOpts,
-                           ReconnMin, ReconnMax ],
-                         [] ).
+start_link(
+    Host,
+    Port,
+    ThriftSvc,
+    ThriftOpts,
+    ReconnMin,
+    ReconnMax
+) ->
+    gen_server:start_link(
+        ?MODULE,
+        [
+            Host,
+            Port,
+            ThriftSvc,
+            ThriftOpts,
+            ReconnMin,
+            ReconnMax
+        ],
+        []
+    ).
 
-call( Pid, Op, Args ) ->
-  gen_server:call( Pid, { call, Op, Args } ).
+call(Pid, Op, Args) ->
+    gen_server:call(Pid, {call, Op, Args}).
 
-get_stats( Pid ) ->
-  gen_server:call( Pid, get_stats ).
+get_stats(Pid) ->
+    gen_server:call(Pid, get_stats).
 
-get_and_reset_stats( Pid ) ->
-  gen_server:call( Pid, get_and_reset_stats ).
+get_and_reset_stats(Pid) ->
+    gen_server:call(Pid, get_and_reset_stats).
 
 %%====================================================================
 %% gen_server callbacks
@@ -83,19 +101,21 @@
 %%                         {stop, Reason}
 %% Description: Start the server.
 %%--------------------------------------------------------------------
-init( [ Host, Port, TSvc, TOpts, ReconnMin, ReconnMax ] ) ->
-  process_flag( trap_exit, true ),
+init([Host, Port, TSvc, TOpts, ReconnMin, ReconnMax]) ->
+    process_flag(trap_exit, true),
 
-  State = #state{ host         = Host,
-                  port         = Port,
-                  thrift_svc   = TSvc,
-                  thrift_opts  = TOpts,
-                  reconn_min   = ReconnMin,
-                  reconn_max   = ReconnMax,
-                  op_cnt_dict  = dict:new(),
-                  op_time_dict = dict:new() },
+    State = #state{
+        host = Host,
+        port = Port,
+        thrift_svc = TSvc,
+        thrift_opts = TOpts,
+        reconn_min = ReconnMin,
+        reconn_max = ReconnMax,
+        op_cnt_dict = dict:new(),
+        op_time_dict = dict:new()
+    },
 
-  { ok, try_connect( State ) }.
+    {ok, try_connect(State)}.
 
 %%--------------------------------------------------------------------
 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -106,40 +126,44 @@
 %%                                                   {stop, Reason, State}
 %% Description: Handling call messages
 %%--------------------------------------------------------------------
-handle_call( { call, Op, _ },
-             _From,
-             State = #state{ client = nil } ) ->
-  { reply, { error, noconn }, incr_stats( Op, "failfast", 1, State ) };
+handle_call(
+    {call, Op, _},
+    _From,
+    State = #state{client = nil}
+) ->
+    {reply, {error, noconn}, incr_stats(Op, "failfast", 1, State)};
+handle_call(
+    {call, Op, Args},
+    _From,
+    State = #state{client = Client}
+) ->
+    Timer = timer_fun(),
+    Result = (catch thrift_client:call(Client, Op, Args)),
+    Time = Timer(),
 
-handle_call( { call, Op, Args },
-             _From,
-             State=#state{ client = Client } ) ->
-
-  Timer = timer_fun(),
-  Result = ( catch thrift_client:call( Client, Op, Args) ),
-  Time = Timer(),
-
-  case Result of
-    { C, { ok, Reply } } ->
-      S = incr_stats( Op, "success", Time, State#state{ client = C } ),
-      { reply, {ok, Reply }, S };
-    { _, { E, Msg } } when E == error; E == exception ->
-      S = incr_stats( Op, "error", Time, try_connect( State ) ),
-      { reply, { E, Msg }, S };
-    Other ->
-      S = incr_stats( Op, "error", Time, try_connect( State ) ),
-      { reply, Other, S }
-  end;
-
-handle_call( get_stats,
-             _From,
-             State = #state{} ) ->
-  { reply, stats( State ), State };
-
-handle_call( get_and_reset_stats,
-             _From,
-             State = #state{} ) ->
-  { reply, stats( State ), reset_stats( State ) }.
+    case Result of
+        {C, {ok, Reply}} ->
+            S = incr_stats(Op, "success", Time, State#state{client = C}),
+            {reply, {ok, Reply}, S};
+        {_, {E, Msg}} when E == error; E == exception ->
+            S = incr_stats(Op, "error", Time, try_connect(State)),
+            {reply, {E, Msg}, S};
+        Other ->
+            S = incr_stats(Op, "error", Time, try_connect(State)),
+            {reply, Other, S}
+    end;
+handle_call(
+    get_stats,
+    _From,
+    State = #state{}
+) ->
+    {reply, stats(State), State};
+handle_call(
+    get_and_reset_stats,
+    _From,
+    State = #state{}
+) ->
+    {reply, stats(State), reset_stats(State)}.
 
 %%--------------------------------------------------------------------
 %% Function: handle_cast(Msg, State) -> {noreply, State} |
@@ -147,8 +171,8 @@
 %%                                      {stop, Reason, State}
 %% Description: Handling cast messages
 %%--------------------------------------------------------------------
-handle_cast( _Msg, State ) ->
-  { noreply, State }.
+handle_cast(_Msg, State) ->
+    {noreply, State}.
 
 %%--------------------------------------------------------------------
 %% Function: handle_info(Info, State) -> {noreply, State} |
@@ -156,11 +180,10 @@
 %%                                       {stop, Reason, State}
 %% Description: Handling all non call/cast messages
 %%--------------------------------------------------------------------
-handle_info( try_connect, State ) ->
-  { noreply, try_connect( State ) };
-
-handle_info( _Info, State ) ->
-  { noreply, State }.
+handle_info(try_connect, State) ->
+    {noreply, try_connect(State)};
+handle_info(_Info, State) ->
+    {noreply, State}.
 
 %%--------------------------------------------------------------------
 %% Function: terminate(Reason, State) -> void()
@@ -169,90 +192,103 @@
 %% cleaning up. When it returns, the gen_server terminates with Reason.
 %% The return value is ignored.
 %%--------------------------------------------------------------------
-terminate( _Reason, #state{ client = Client } ) ->
-  thrift_client:close( Client ),
-  ok.
+terminate(_Reason, #state{client = Client}) ->
+    thrift_client:close(Client),
+    ok.
 
 %%--------------------------------------------------------------------
 %% Func: code_change(OldVsn, State, Extra) -> {ok, NewState}
 %% Description: Convert process state when code is changed
 %%--------------------------------------------------------------------
-code_change( _OldVsn, State, _Extra ) ->
-  { ok, State }.
+code_change(_OldVsn, State, _Extra) ->
+    {ok, State}.
 
 %%--------------------------------------------------------------------
 %%% Internal functions
 %%--------------------------------------------------------------------
-try_connect( State = #state{ client      = OldClient,
-                             host        = Host,
-                             port        = Port,
-                             thrift_svc  = TSvc,
-                             thrift_opts = TOpts } ) ->
+try_connect(
+    State = #state{
+        client = OldClient,
+        host = Host,
+        port = Port,
+        thrift_svc = TSvc,
+        thrift_opts = TOpts
+    }
+) ->
+    case OldClient of
+        nil -> ok;
+        _ -> (catch thrift_client:close(OldClient))
+    end,
 
-  case OldClient of
-    nil -> ok;
-    _   -> ( catch thrift_client:close( OldClient ) )
-  end,
+    case catch thrift_client_util:new(Host, Port, TSvc, TOpts) of
+        {ok, Client} ->
+            State#state{client = Client, reconn_time = 0};
+        {E, Msg} when E == error; E == exception ->
+            ReconnTime = reconn_time(State),
+            error_logger:error_msg(
+                "[~w] ~w connect failed (~w), trying again in ~w ms~n",
+                [self(), TSvc, Msg, ReconnTime]
+            ),
+            erlang:send_after(ReconnTime, self(), try_connect),
+            State#state{client = nil, reconn_time = ReconnTime}
+    end.
 
-  case catch thrift_client_util:new( Host, Port, TSvc, TOpts ) of
-    { ok, Client } ->
-      State#state{ client = Client, reconn_time = 0 };
-    { E, Msg } when E == error; E == exception ->
-      ReconnTime = reconn_time( State ),
-      error_logger:error_msg( "[~w] ~w connect failed (~w), trying again in ~w ms~n",
-                              [ self(), TSvc, Msg, ReconnTime ] ),
-      erlang:send_after( ReconnTime, self(), try_connect ),
-      State#state{ client = nil, reconn_time = ReconnTime }
-  end.
-
-
-reconn_time( #state{ reconn_min = ReconnMin, reconn_time = 0 } ) ->
-  ReconnMin;
-reconn_time( #state{ reconn_max = ReconnMax, reconn_time = ReconnMax } ) ->
-  ReconnMax;
-reconn_time( #state{ reconn_max = ReconnMax, reconn_time = R } ) ->
-  Backoff = 2 * R,
-  case Backoff > ReconnMax of
-    true  -> ReconnMax;
-    false -> Backoff
-  end.
+reconn_time(#state{reconn_min = ReconnMin, reconn_time = 0}) ->
+    ReconnMin;
+reconn_time(#state{reconn_max = ReconnMax, reconn_time = ReconnMax}) ->
+    ReconnMax;
+reconn_time(#state{reconn_max = ReconnMax, reconn_time = R}) ->
+    Backoff = 2 * R,
+    case Backoff > ReconnMax of
+        true -> ReconnMax;
+        false -> Backoff
+    end.
 
 -ifdef(time_correction).
 timer_fun() ->
-  T1 = erlang:monotonic_time(),
-  fun() ->
-    T2 = erlang:monotonic_time(),
-    erlang:convert_time_unit(T2 - T1, native, micro_seconds)
-  end.
+    T1 = erlang:monotonic_time(),
+    fun() ->
+        T2 = erlang:monotonic_time(),
+        erlang:convert_time_unit(T2 - T1, native, micro_seconds)
+    end.
 -else.
 timer_fun() ->
-  T1 = erlang:timestamp(),
-  fun() ->
-    T2 = erlang:timestamp(),
-    timer:now_diff(T2, T1)
-  end.
+    T1 = erlang:timestamp(),
+    fun() ->
+        T2 = erlang:timestamp(),
+        timer:now_diff(T2, T1)
+    end.
 -endif.
 
-incr_stats( Op, Result, Time,
-            State = #state{ op_cnt_dict  = OpCntDict,
-                            op_time_dict = OpTimeDict } ) ->
-  Key = lists:flatten( [ atom_to_list( Op ), [ "_" | Result ] ] ),
-  State#state{ op_cnt_dict  = dict:update_counter( Key, 1, OpCntDict ),
-               op_time_dict = dict:update_counter( Key, Time, OpTimeDict ) }.
+incr_stats(
+    Op,
+    Result,
+    Time,
+    State = #state{
+        op_cnt_dict = OpCntDict,
+        op_time_dict = OpTimeDict
+    }
+) ->
+    Key = lists:flatten([atom_to_list(Op), ["_" | Result]]),
+    State#state{
+        op_cnt_dict = dict:update_counter(Key, 1, OpCntDict),
+        op_time_dict = dict:update_counter(Key, Time, OpTimeDict)
+    }.
 
+stats(#state{
+    thrift_svc = TSvc,
+    op_cnt_dict = OpCntDict,
+    op_time_dict = OpTimeDict
+}) ->
+    Svc = atom_to_list(TSvc),
 
-stats( #state{ thrift_svc   = TSvc,
-               op_cnt_dict  = OpCntDict,
-               op_time_dict = OpTimeDict } ) ->
-  Svc = atom_to_list(TSvc),
+    F = fun(Key, Count, Stats) ->
+        Name = lists:flatten([Svc, ["_" | Key]]),
+        Micros = dict:fetch(Key, OpTimeDict),
+        [{Name, Count, Micros} | Stats]
+    end,
 
-  F = fun( Key, Count, Stats ) ->
-        Name = lists:flatten( [ Svc, [ "_" | Key ] ] ),
-        Micros = dict:fetch( Key, OpTimeDict ),
-        [ { Name, Count, Micros } | Stats ]
-      end,
+    dict:fold(F, [], OpCntDict).
 
-  dict:fold( F, [], OpCntDict ).
-
-reset_stats( State = #state{} ) ->
-  State#state{ op_cnt_dict = dict:new(), op_time_dict = dict:new() }.
+reset_stats(State = #state{}) ->
+    State#state{op_cnt_dict = dict:new(), op_time_dict = dict:new()}.
diff --git a/lib/erl/src/thrift_server.erl b/lib/erl/src/thrift_server.erl
index 5012e16..e97acff 100644
--- a/lib/erl/src/thrift_server.erl
+++ b/lib/erl/src/thrift_server.erl
@@ -25,12 +25,23 @@
 -export([start_link/3, stop/1, take_socket/2]).
 
 %% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
-         terminate/2, code_change/3]).
+-export([
+    init/1,
+    handle_call/3,
+    handle_cast/2,
+    handle_info/2,
+    terminate/2,
+    code_change/3
+]).
 
 -define(SERVER, ?MODULE).
 
--record(state, {listen_socket, acceptor_ref, service, handler}).
+-record(state, {
+    listen_socket :: gen_tcp:socket(),
+    acceptor_ref :: term(),
+    service :: module(),
+    handler :: module()
+}).
 
 %%====================================================================
 %% API
@@ -49,11 +60,9 @@
 stop(Pid) when is_pid(Pid) ->
     gen_server:call(Pid, stop).
 
-
 take_socket(Server, Socket) ->
     gen_server:call(Server, {take_socket, Socket}).
 
-
 %%====================================================================
 %% gen_server callbacks
 %%====================================================================
@@ -66,17 +75,23 @@
 %% Description: Initiates the server
 %%--------------------------------------------------------------------
 init({Port, Service, Handler}) ->
-    {ok, Socket} = gen_tcp:listen(Port,
-                                  [binary,
-                                   {packet, 0},
-                                   {active, false},
-                                   {nodelay, true},
-                                   {reuseaddr, true}]),
+    {ok, Socket} = gen_tcp:listen(
+        Port,
+        [
+            binary,
+            {packet, 0},
+            {active, false},
+            {nodelay, true},
+            {reuseaddr, true}
+        ]
+    ),
     {ok, Ref} = prim_inet:async_accept(Socket, -1),
-    {ok, #state{listen_socket = Socket,
-                acceptor_ref = Ref,
-                service = Service,
-                handler = Handler}}.
+    {ok, #state{
+        listen_socket = Socket,
+        acceptor_ref = Ref,
+        service = Service,
+        handler = Handler
+    }}.
 
 %%--------------------------------------------------------------------
 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
@@ -89,7 +104,6 @@
 %%--------------------------------------------------------------------
 handle_call(stop, _From, State) ->
     {stop, stopped, ok, State};
-
 handle_call({take_socket, Socket}, {FromPid, _Tag}, State) ->
     Result = gen_tcp:controlling_process(Socket, FromPid),
     {reply, Result, State}.
@@ -109,11 +123,15 @@
 %%                                       {stop, Reason, State}
 %% Description: Handling all non call/cast messages
 %%--------------------------------------------------------------------
-handle_info({inet_async, ListenSocket, Ref, {ok, ClientSocket}},
-            State = #state{listen_socket = ListenSocket,
-                           acceptor_ref = Ref,
-                           service = Service,
-                           handler = Handler}) ->
+handle_info(
+    {inet_async, ListenSocket, Ref, {ok, ClientSocket}},
+    State = #state{
+        listen_socket = ListenSocket,
+        acceptor_ref = Ref,
+        service = Service,
+        handler = Handler
+    }
+) ->
     case set_sockopt(ListenSocket, ClientSocket) of
         ok ->
             %% New client connected - start processor
@@ -121,15 +139,15 @@
             {ok, NewRef} = prim_inet:async_accept(ListenSocket, -1),
             {noreply, State#state{acceptor_ref = NewRef}};
         {error, Reason} ->
-            error_logger:error_msg("Couldn't set socket opts: ~p~n",
-                                   [Reason]),
+            error_logger:error_msg(
+                "Couldn't set socket opts: ~p~n",
+                [Reason]
+            ),
             {stop, Reason, State}
     end;
-
 handle_info({inet_async, _ListenSocket, _Ref, Error}, State) ->
     error_logger:error_msg("Error in acceptor: ~p~n", [Error]),
     {stop, Error, State};
-
 handle_info(_Info, State) ->
     {noreply, State}.
 
@@ -155,13 +173,19 @@
 %%--------------------------------------------------------------------
 set_sockopt(ListenSocket, ClientSocket) ->
     true = inet_db:register_socket(ClientSocket, inet_tcp),
-    case prim_inet:getopts(ListenSocket,
-                           [active, nodelay, keepalive, delay_send, priority, tos]) of
+    case
+        prim_inet:getopts(
+            ListenSocket,
+            [active, nodelay, keepalive, delay_send, priority, tos]
+        )
+    of
         {ok, Opts} ->
             case prim_inet:setopts(ClientSocket, Opts) of
-                ok    -> ok;
-                Error -> gen_tcp:close(ClientSocket),
-                         Error
+                ok ->
+                    ok;
+                Error ->
+                    gen_tcp:close(ClientSocket),
+                    Error
             end;
         Error ->
             gen_tcp:close(ClientSocket),
@@ -172,12 +196,12 @@
     Server = self(),
 
     ProtoGen = fun() ->
-                       % Become the controlling process
-                       ok = take_socket(Server, Socket),
-                       {ok, SocketTransport} = thrift_socket_transport:new(Socket),
-                       {ok, BufferedTransport} = thrift_buffered_transport:new(SocketTransport),
-                       {ok, Protocol} = thrift_binary_protocol:new(BufferedTransport),
-                       {ok, Protocol}
-               end,
+        % Become the controlling process
+        ok = take_socket(Server, Socket),
+        {ok, SocketTransport} = thrift_socket_transport:new(Socket),
+        {ok, BufferedTransport} = thrift_buffered_transport:new(SocketTransport),
+        {ok, Protocol} = thrift_binary_protocol:new(BufferedTransport),
+        {ok, Protocol}
+    end,
 
     spawn(thrift_processor, init, [{Server, ProtoGen, Service, Handler}]).
diff --git a/lib/erl/src/thrift_service.erl b/lib/erl/src/thrift_service.erl
index 2ed7b57..5024102 100644
--- a/lib/erl/src/thrift_service.erl
+++ b/lib/erl/src/thrift_service.erl
@@ -19,7 +19,9 @@
 
 -module(thrift_service).
 
--export([behaviour_info/1]).
+%%%=========================================================================
+%%%  API
+%%%=========================================================================
 
-behaviour_info(callbacks) ->
-    [{function_info, 2}].
+%% TODO Replace response with type
+-callback function_info(atom(), atom()) -> {struct, term()}.
diff --git a/lib/erl/src/thrift_socket_server.erl b/lib/erl/src/thrift_socket_server.erl
index 432e65b..abeee81 100644
--- a/lib/erl/src/thrift_socket_server.erl
+++ b/lib/erl/src/thrift_socket_server.erl
@@ -21,40 +21,51 @@
 
 -behaviour(gen_server).
 
--include ("thrift_constants.hrl").
+-include("thrift_constants.hrl").
+
+-export([start/1, stop/1]).
+-export([
+    init/1,
+    handle_call/3,
+    handle_cast/2,
+    terminate/2,
+    code_change/3,
+    handle_info/2
+]).
+-export([acceptor_loop/1]).
 
 -ifdef(TEST).
-    -compile(export_all).
-    -export_records([thrift_socket_server]).
--else.
-    -export([start/1, stop/1]).
-
-    -export([init/1, handle_call/3, handle_cast/2, terminate/2, code_change/3,
-             handle_info/2]).
-
-    -export([acceptor_loop/1]).
+-export([parse_options/1]).
 -endif.
 
--record(thrift_socket_server,
-        {port,
-         service,
-         handler,
-         name,
-         max=2048,
-         ip=any,
-         listen=null,
-         acceptor=null,
-         socket_opts=[{recv_timeout, 500}],
-         protocol=binary,
-         framed=false,
-         ssltransport=false,
-         ssloptions=[]
-        }).
+-type protocol() ::
+    compact
+    | {compact, term()}
+    | json
+    | {json, term()}
+    | binary
+    | {binary | term()}
+    | {custom, module(), term()}.
 
-start(State=#thrift_socket_server{}) ->
-    start_server(State);
+-type socket_opts() :: [inet:inet_backend() | gen_tcp:listen_option()].
+-type ssl_opts() :: [ssl:tls_server_option()].
+
+-record(thrift_socket_server, {
+    port :: inet:port_number(),
+    service :: thrift_multiplexed_map_wrapper:service_handler_map(),
+    handler :: thrift_multiplexed_map_wrapper:service_handler_map(),
+    acceptors_left :: non_neg_integer(),
+    listen :: gen_tcp:socket(),
+    acceptor :: undefined | pid(),
+    socket_opts :: socket_opts(),
+    protocol :: protocol(),
+    framed :: boolean(),
+    ssltransport :: boolean(),
+    ssloptions :: ssl_opts()
+}).
+
 start(Options) ->
-    start(parse_options(Options)).
+    start_server(parse_options(Options)).
 
 stop(Name) when is_atom(Name) ->
     gen_server:cast(Name, stop);
@@ -65,259 +76,300 @@
 stop({global, Name}) ->
     stop(Name);
 stop(Options) ->
-    State = parse_options(Options),
-    stop(State#thrift_socket_server.name).
+    #{name := Name} = parse_options(Options),
+    stop(Name).
 
 %% Internal API
 
 parse_options(Options) ->
-    parse_options(Options, #thrift_socket_server{}).
+    parse_options(Options, #{}).
 
 parse_options([], State) ->
     State;
 parse_options([{name, L} | Rest], State) when is_list(L) ->
     Name = {local, list_to_atom(L)},
-    parse_options(Rest, State#thrift_socket_server{name=Name});
+    parse_options(Rest, State#{name => Name});
 parse_options([{name, A} | Rest], State) when is_atom(A) ->
     Name = {local, A},
-    parse_options(Rest, State#thrift_socket_server{name=Name});
+    parse_options(Rest, State#{name => Name});
 parse_options([{name, Name} | Rest], State) ->
-    parse_options(Rest, State#thrift_socket_server{name=Name});
+    parse_options(Rest, State#{name => Name});
 parse_options([{port, L} | Rest], State) when is_list(L) ->
     Port = list_to_integer(L),
-    parse_options(Rest, State#thrift_socket_server{port=Port});
-parse_options([{port, Port} | Rest], State) ->
-    parse_options(Rest, State#thrift_socket_server{port=Port});
+    parse_options(Rest, State#{port => Port});
+parse_options([{port, Port} | Rest], State) when is_integer(Port), Port >= 0, Port =< 65535 ->
+    parse_options(Rest, State#{port => Port});
 parse_options([{ip, Ip} | Rest], State) ->
-    ParsedIp = case Ip of
-                   any ->
-                       any;
-                   Ip when is_tuple(Ip) ->
-                       Ip;
-                   Ip when is_list(Ip) ->
-                       {ok, IpTuple} = inet_parse:address(Ip),
-                       IpTuple
-               end,
-    parse_options(Rest, State#thrift_socket_server{ip=ParsedIp});
+    case Ip of
+        any ->
+            parse_options(Rest, State);
+        Ip when is_tuple(Ip) ->
+            parse_options(Rest, State#{ip => Ip});
+        Ip when is_list(Ip) ->
+            {ok, IpTuple} = inet_parse:address(Ip),
+            parse_options(Rest, State#{ip => IpTuple})
+    end;
 parse_options([{socket_opts, L} | Rest], State) when is_list(L), length(L) > 0 ->
-    parse_options(Rest, State#thrift_socket_server{socket_opts=L});
-
+    parse_options(Rest, State#{socket_opts => L});
 parse_options([{handler, []} | _Rest], _State) ->
     throw("At least an error handler must be defined.");
-parse_options([{handler, ServiceHandlerPropertyList} | Rest], State) when is_list(ServiceHandlerPropertyList) ->
+parse_options([{handler, ServiceHandlerPropertyList} | Rest], State) when
+    is_list(ServiceHandlerPropertyList)
+->
     ServiceHandlerMap =
-    case State#thrift_socket_server.handler of
-        undefined ->
-            lists:foldl(
-                fun ({ServiceName, ServiceHandler}, Acc) when is_list(ServiceName), is_atom(ServiceHandler) ->
-                        thrift_multiplexed_map_wrapper:store(ServiceName, ServiceHandler, Acc);
-                    (_, _Acc) ->
-                        throw("The handler option is not properly configured for multiplexed services. It should be a kind of [{\"error_handler\", Module::atom()}, {SericeName::list(), Module::atom()}, ...]")
-                end, thrift_multiplexed_map_wrapper:new(), ServiceHandlerPropertyList);
-        _ -> throw("Error while parsing the handler option.")
-    end,
+        case maps:get(handler, State, undefined) of
+            undefined ->
+                lists:foldl(
+                    fun
+                        ({ServiceName, ServiceHandler}, Acc) when
+                            is_list(ServiceName), is_atom(ServiceHandler)
+                        ->
+                            thrift_multiplexed_map_wrapper:store(ServiceName, ServiceHandler, Acc);
+                        (_, _Acc) ->
+                            throw(
+                                "The handler option is not properly configured for multiplexed services. It should be a kind of [{\"error_handler\", Module::atom()}, {SericeName::list(), Module::atom()}, ...]"
+                            )
+                    end,
+                    thrift_multiplexed_map_wrapper:new(),
+                    ServiceHandlerPropertyList
+                );
+            _ ->
+                throw("Error while parsing the handler option.")
+        end,
     case thrift_multiplexed_map_wrapper:find(?MULTIPLEXED_ERROR_HANDLER_KEY, ServiceHandlerMap) of
-        {ok, _ErrorHandler} -> parse_options(Rest, State#thrift_socket_server{handler=ServiceHandlerMap});
-        error -> throw("The handler option is not properly configured for multiplexed services. It should be a kind of [{\"error_handler\", Module::atom()}, {SericeName::list(), Module::atom()}, ...]")
+        {ok, _ErrorHandler} ->
+            parse_options(Rest, State#{handler => ServiceHandlerMap});
+        error ->
+            throw(
+                "The handler option is not properly configured for multiplexed services. It should be a kind of [{\"error_handler\", Module::atom()}, {SericeName::list(), Module::atom()}, ...]"
+            )
     end;
-parse_options([{handler, Handler} | Rest], State) when State#thrift_socket_server.handler == undefined, is_atom(Handler) ->
-    parse_options(Rest, State#thrift_socket_server{handler=Handler});
-
+parse_options([{handler, Handler} | Rest], State) when
+    not is_map_key(handler, State), is_atom(Handler)
+->
+    parse_options(Rest, State#{handler => Handler});
 parse_options([{service, []} | _Rest], _State) ->
     throw("At least one service module must be defined.");
-parse_options([{service, ServiceModulePropertyList} | Rest], State) when is_list(ServiceModulePropertyList) ->
+parse_options([{service, ServiceModulePropertyList} | Rest], State) when
+    is_list(ServiceModulePropertyList)
+->
     ServiceModuleMap =
-    case State#thrift_socket_server.service of
-        undefined ->
-            lists:foldl(
-                fun ({ServiceName, ServiceModule}, Acc) when is_list(ServiceName), is_atom(ServiceModule) ->
-                        thrift_multiplexed_map_wrapper:store(ServiceName, ServiceModule, Acc);
-                    (_, _Acc) ->
-                        throw("The service option is not properly configured for multiplexed services. It should be a kind of [{SericeName::list(), ServiceModule::atom()}, ...]")
-                end, thrift_multiplexed_map_wrapper:new(), ServiceModulePropertyList);
-        _ -> throw("Error while parsing the service option.")
-    end,
-    parse_options(Rest, State#thrift_socket_server{service=ServiceModuleMap});
-parse_options([{service, Service} | Rest], State) when State#thrift_socket_server.service == undefined, is_atom(Service) ->
-    parse_options(Rest, State#thrift_socket_server{service=Service});
-
-parse_options([{max, Max} | Rest], State) ->
-    MaxInt = case Max of
-                 Max when is_list(Max) ->
-                     list_to_integer(Max);
-                 Max when is_integer(Max) ->
-                     Max
-             end,
-    parse_options(Rest, State#thrift_socket_server{max=MaxInt});
-
+        case maps:get(service, State, undefined) of
+            undefined ->
+                lists:foldl(
+                    fun
+                        ({ServiceName, ServiceModule}, Acc) when
+                            is_list(ServiceName), is_atom(ServiceModule)
+                        ->
+                            thrift_multiplexed_map_wrapper:store(ServiceName, ServiceModule, Acc);
+                        (_, _Acc) ->
+                            throw(
+                                "The service option is not properly configured for multiplexed services. It should be a kind of [{SericeName::list(), ServiceModule::atom()}, ...]"
+                            )
+                    end,
+                    thrift_multiplexed_map_wrapper:new(),
+                    ServiceModulePropertyList
+                );
+            _ ->
+                throw("Error while parsing the service option.")
+        end,
+    parse_options(Rest, State#{service => ServiceModuleMap});
+parse_options([{service, Service} | Rest], State) when
+    not is_map_key(service, State), is_atom(Service)
+->
+    parse_options(Rest, State#{service => Service});
+parse_options([{max, Max} | Rest], State) when is_integer(Max), Max > 0 ->
+    parse_options(Rest, State#{max => Max});
 parse_options([{protocol, Proto} | Rest], State) when is_atom(Proto) ->
-    parse_options(Rest, State#thrift_socket_server{protocol=Proto});
-
+    parse_options(Rest, State#{protocol => Proto});
 parse_options([{framed, Framed} | Rest], State) when is_boolean(Framed) ->
-    parse_options(Rest, State#thrift_socket_server{framed=Framed});
-
+    parse_options(Rest, State#{framed => Framed});
 parse_options([{ssltransport, SSLTransport} | Rest], State) when is_boolean(SSLTransport) ->
-    parse_options(Rest, State#thrift_socket_server{ssltransport=SSLTransport});
+    parse_options(Rest, State#{ssltransport => SSLTransport});
 parse_options([{ssloptions, SSLOptions} | Rest], State) when is_list(SSLOptions) ->
-    parse_options(Rest, State#thrift_socket_server{ssloptions=SSLOptions}).
+    parse_options(Rest, State#{ssloptions => SSLOptions}).
 
-start_server(State=#thrift_socket_server{name=Name}) ->
+start_server(Options = #{name := Name}) ->
     case Name of
         undefined ->
-            gen_server:start_link(?MODULE, State, []);
+            gen_server:start_link(?MODULE, Options, []);
         _ ->
-            gen_server:start_link(Name, ?MODULE, State, [])
+            gen_server:start_link(Name, ?MODULE, Options, [])
     end.
 
-init(State=#thrift_socket_server{ip=Ip, port=Port}) ->
+init(State = #{port := Port}) ->
     process_flag(trap_exit, true),
-    BaseOpts = [binary,
-                {reuseaddr, true},
-                {packet, 0},
-                {backlog, 4096},
-                {recbuf, 8192},
-                {active, false}],
-    Opts = case Ip of
-               any ->
-                   BaseOpts;
-               Ip ->
-                   [{ip, Ip} | BaseOpts]
-           end,
-    case gen_tcp_listen(Port, Opts, State) of
-        {stop, eacces} ->
-            %% fdsrv module allows another shot to bind
-            %% ports which require root access
-            case Port < 1024 of
-                true ->
-                    case fdsrv:start() of
-                        {ok, _} ->
-                            case fdsrv:bind_socket(tcp, Port) of
-                                {ok, Fd} ->
-                                    gen_tcp_listen(Port, [{fd, Fd} | Opts], State);
-                                _ ->
-                                    {stop, fdsrv_bind_failed}
-                            end;
-                        _ ->
-                            {stop, fdsrv_start_failed}
-                    end;
-                false ->
-                    {stop, eacces}
-            end;
-        Other ->
-            error_logger:info_msg("thrift service listening on port ~p", [Port]),
-            Other
-    end.
-
-gen_tcp_listen(Port, Opts, State) ->
+    BaseOpts = [
+        binary,
+        {reuseaddr, true},
+        {packet, 0},
+        {backlog, 4096},
+        {recbuf, 8192},
+        {active, false}
+    ],
+    Opts =
+        case maps:get(ip, State, undefined) of
+            undefined ->
+                BaseOpts;
+            Ip ->
+                [{ip, Ip} | BaseOpts]
+        end,
     case gen_tcp:listen(Port, Opts) of
         {ok, Listen} ->
             {ok, ListenPort} = inet:port(Listen),
-            {ok, new_acceptor(State#thrift_socket_server{listen=Listen,
-                                                         port=ListenPort})};
+            {ok,
+                new_acceptor(#thrift_socket_server{
+                    acceptors_left = maps:get(max, State, 2048),
+                    listen = Listen,
+                    port = ListenPort,
+                    service = maps:get(service, State),
+                    handler = maps:get(handler, State),
+                    socket_opts = maps:get(socket_opts, State, [{recv_timeout, 500}]),
+                    framed = maps:get(framed, State, false),
+                    protocol = maps:get(protocol, State, binary),
+                    ssltransport = maps:get(ssltransport, State, false),
+                    ssloptions = maps:get(ssloptions, State, [])
+                })};
         {error, Reason} ->
             {stop, Reason}
     end.
 
-new_acceptor(State=#thrift_socket_server{max=0}) ->
+new_acceptor(State = #thrift_socket_server{acceptors_left = 0}) ->
     error_logger:error_msg("Not accepting new connections"),
-    State#thrift_socket_server{acceptor=null};
-new_acceptor(State=#thrift_socket_server{listen=Listen,
-                                         service=Service, handler=Handler,
-                                         socket_opts=Opts, framed=Framed, protocol=Proto,
-                                         ssltransport=SslTransport, ssloptions=SslOptions
-                                        }) ->
-    Pid = proc_lib:spawn_link(?MODULE, acceptor_loop,
-                              [{self(), Listen, Service, Handler, Opts, Framed, SslTransport, SslOptions, Proto}]),
-    State#thrift_socket_server{acceptor=Pid}.
+    State#thrift_socket_server{acceptor = undefined};
+new_acceptor(
+    State = #thrift_socket_server{
+        listen = Listen,
+        service = Service,
+        handler = Handler,
+        socket_opts = Opts,
+        framed = Framed,
+        protocol = Proto,
+        ssltransport = SslTransport,
+        ssloptions = SslOptions
+    }
+) ->
+    Pid = proc_lib:spawn_link(
+        ?MODULE,
+        acceptor_loop,
+        [{self(), Listen, Service, Handler, Opts, Framed, SslTransport, SslOptions, Proto}]
+    ),
+    State#thrift_socket_server{acceptor = Pid}.
 
-acceptor_loop({Server, Listen, Service, Handler, SocketOpts, Framed, SslTransport, SslOptions, Proto})
-  when is_pid(Server), is_list(SocketOpts) ->
-    case catch gen_tcp:accept(Listen) of % infinite timeout
+acceptor_loop(
+    {Server, Listen, Service, Handler, SocketOpts, Framed, SslTransport, SslOptions, Proto}
+) when
+    is_pid(Server), is_list(SocketOpts)
+->
+    % infinite timeout
+    case catch gen_tcp:accept(Listen) of
         {ok, Socket} ->
             gen_server:cast(Server, {accepted, self()}),
             ProtoGen = fun() ->
-                               {ok, SocketTransport} = case SslTransport of
-                                                           true  -> thrift_sslsocket_transport:new(Socket, SocketOpts, SslOptions);
-                                                           false -> thrift_socket_transport:new(Socket, SocketOpts)
-                                                       end,
-                               {ok, Transport}       = case Framed of
-                                                           true  -> thrift_framed_transport:new(SocketTransport);
-                                                           false -> thrift_buffered_transport:new(SocketTransport)
-                                                       end,
-                               {ok, Protocol}        = case Proto of
-                                                         compact -> thrift_compact_protocol:new(Transport);
-                                                         json -> thrift_json_protocol:new(Transport);
-                                                         _ -> thrift_binary_protocol:new(Transport)
-                                                       end,
-                               {ok, Protocol}
-                       end,
+                {ok, SocketTransport} =
+                    case SslTransport of
+                        true -> thrift_sslsocket_transport:new(Socket, SocketOpts, SslOptions);
+                        false -> thrift_socket_transport:new(Socket, SocketOpts)
+                    end,
+                {ok, Transport} =
+                    case Framed of
+                        true -> thrift_framed_transport:new(SocketTransport);
+                        false -> thrift_buffered_transport:new(SocketTransport)
+                    end,
+                {ok, Protocol} =
+                    case Proto of
+                        compact ->
+                            thrift_compact_protocol:new(Transport);
+                        {compact, Options} ->
+                            thrift_compact_protocol:new(Transport, Options);
+                        json ->
+                            thrift_json_protocol:new(Transport);
+                        {json, Options} ->
+                            thrift_json_protocol:new(Transport, Options);
+                        binary ->
+                            thrift_binary_protocol:new(Transport);
+                        {binary, Options} ->
+                            thrift_binary_protocol:new(Transport, Options);
+                        {custom, Module, Options} ->
+                            case erlang:function_exported(Module, new, 2) of
+                                true -> Module:new(Transport, Options);
+                                false -> throw("Could not instantiate custom protocol")
+                            end
+                    end,
+                {ok, Protocol}
+            end,
             thrift_processor:init({Server, ProtoGen, Service, Handler});
         {error, closed} ->
             exit({error, closed});
         Other ->
             error_logger:error_report(
-              [{application, thrift},
-               "Accept failed error",
-               lists:flatten(io_lib:format("~p", [Other]))]),
+                [
+                    {application, thrift},
+                    "Accept failed error",
+                    lists:flatten(io_lib:format("~p", [Other]))
+                ]
+            ),
             exit({error, accept_failed})
     end.
 
-handle_call({get, port}, _From, State=#thrift_socket_server{port=Port}) ->
+handle_call({get, port}, _From, State = #thrift_socket_server{port = Port}) ->
     {reply, Port, State};
 handle_call(_Message, _From, State) ->
     Res = error,
     {reply, Res, State}.
 
-handle_cast({accepted, Pid},
-            State=#thrift_socket_server{acceptor=Pid, max=Max}) ->
+handle_cast(
+    {accepted, Pid},
+    State = #thrift_socket_server{acceptor = Pid, acceptors_left = Max}
+) ->
     % io:format("accepted ~p~n", [Pid]),
-    State1 = State#thrift_socket_server{max=Max - 1},
+    State1 = State#thrift_socket_server{acceptors_left = Max - 1},
     {noreply, new_acceptor(State1)};
 handle_cast(stop, State) ->
     {stop, normal, State}.
 
-terminate(Reason, #thrift_socket_server{listen=Listen, port=Port}) ->
+terminate(Reason, #thrift_socket_server{listen = Listen}) ->
     gen_tcp:close(Listen),
     case Reason of
-        normal -> ok;
-        shutdown -> ok;
-        _ -> {backtrace, Bt} = erlang:process_info(self(), backtrace),
-             error_logger:error_report({?MODULE, ?LINE,
-                                       {child_error, Reason, Bt}})
-    end,
-    case Port < 1024 of
-        true ->
-            catch fdsrv:stop(),
+        normal ->
             ok;
-        false ->
-            ok
+        shutdown ->
+            ok;
+        _ ->
+            {backtrace, Bt} = erlang:process_info(self(), backtrace),
+            error_logger:error_report({?MODULE, ?LINE, {child_error, Reason, Bt}})
     end.
 
 code_change(_OldVsn, State, _Extra) ->
     State.
 
-handle_info({'EXIT', Pid, normal},
-            State=#thrift_socket_server{acceptor=Pid}) ->
+handle_info(
+    {'EXIT', Pid, normal},
+    State = #thrift_socket_server{acceptor = Pid}
+) ->
     {noreply, new_acceptor(State)};
-handle_info({'EXIT', Pid, Reason},
-            State=#thrift_socket_server{acceptor=Pid}) ->
-    error_logger:error_report({?MODULE, ?LINE,
-                               {acceptor_error, Reason}}),
+handle_info(
+    {'EXIT', Pid, Reason},
+    State = #thrift_socket_server{acceptor = Pid}
+) ->
+    error_logger:error_report({?MODULE, ?LINE, {acceptor_error, Reason}}),
     timer:sleep(100),
     {noreply, new_acceptor(State)};
-handle_info({'EXIT', _LoopPid, Reason},
-            State=#thrift_socket_server{acceptor=Pid, max=Max}) ->
+handle_info(
+    {'EXIT', _LoopPid, Reason},
+    State = #thrift_socket_server{acceptor = Pid, acceptors_left = AcceptorsLeft}
+) ->
     case Reason of
         normal -> ok;
         shutdown -> ok;
-        _ -> error_logger:error_report({?MODULE, ?LINE,
-                                        {child_error, Reason, erlang:get_stacktrace()}})
+        _ -> error_logger:error_report({?MODULE, ?LINE, {child_error, Reason}})
     end,
-    State1 = State#thrift_socket_server{max=Max + 1},
-    State2 = case Pid of
-                 null -> new_acceptor(State1);
-                 _ -> State1
-             end,
+    State1 = State#thrift_socket_server{acceptors_left = AcceptorsLeft + 1},
+    State2 =
+        case Pid of
+            undefined -> new_acceptor(State1);
+            _ -> State1
+        end,
     {noreply, State2};
 handle_info(Info, State) ->
     error_logger:info_report([{'INFO', Info}, {'State', State}]),
diff --git a/lib/erl/src/thrift_socket_transport.erl b/lib/erl/src/thrift_socket_transport.erl
index fe210da..a5b68e1 100644
--- a/lib/erl/src/thrift_socket_transport.erl
+++ b/lib/erl/src/thrift_socket_transport.erl
@@ -28,113 +28,89 @@
 %% legacy api
 -export([new_transport_factory/3]).
 
-
 -record(t_socket, {
-  socket,
-  recv_timeout=60000,
-  buffer = []
+    socket :: gen_tcp:socket(),
+    recv_timeout = 60000 :: timeout(),
+    buffer = [] :: iodata()
 }).
 
--type state() :: #t_socket{}.
-
-
--spec new(Socket::any()) ->
-  thrift_transport:t_transport().
+-spec new(Socket :: any()) -> {ok, thrift_transport:t_transport()}.
 
 new(Socket) -> new(Socket, []).
 
--spec new(Socket::any(), Opts::list()) ->
-  thrift_transport:t_transport().
+-spec new(Socket :: any(), Opts :: list()) -> {ok, thrift_transport:t_transport()}.
 
 new(Socket, Opts) when is_list(Opts) ->
-  State = parse_opts(Opts, #t_socket{socket = Socket}),
-  thrift_transport:new(?MODULE, State).
+    State = parse_opts(Opts, #t_socket{socket = Socket}),
+    thrift_transport:new(?MODULE, State).
 
-
-parse_opts([{recv_timeout, Timeout}|Rest], State)
-when is_integer(Timeout), Timeout > 0 ->
-  parse_opts(Rest, State#t_socket{recv_timeout = Timeout});
-parse_opts([{recv_timeout, infinity}|Rest], State) ->
-  parse_opts(Rest, State#t_socket{recv_timeout = infinity});
+parse_opts([{recv_timeout, Timeout} | Rest], State) when
+    is_integer(Timeout), Timeout > 0
+->
+    parse_opts(Rest, State#t_socket{recv_timeout = Timeout});
+parse_opts([{recv_timeout, infinity} | Rest], State) ->
+    parse_opts(Rest, State#t_socket{recv_timeout = infinity});
 parse_opts([], State) ->
-  State.
+    State.
 
+read(State = #t_socket{buffer = Buf}, Len) when
+    is_integer(Len), Len >= 0
+->
+    Binary = iolist_to_binary(Buf),
+    case iolist_size(Binary) of
+        X when X >= Len ->
+            {Result, Remaining} = split_binary(Binary, Len),
+            {State#t_socket{buffer = Remaining}, {ok, Result}};
+        _ ->
+            loop_recv(State, Len, Len)
+    end.
 
--include("thrift_transport_behaviour.hrl").
-
-
-read(State = #t_socket{buffer = Buf}, Len)
-when is_integer(Len), Len >= 0 ->
-  Binary = iolist_to_binary(Buf),
-  case iolist_size(Binary) of
-    X when X >= Len ->
-      {Result, Remaining} = split_binary(Binary, Len),
-      {State#t_socket{buffer = Remaining}, {ok, Result}};
-    _ ->
-     %%recv(State, Len)
-     loop_recv(State,Len,Len)
-  end.
-
-loop_recv(State=#t_socket{buffer = Buf},ReadLen,NextReadLen) when NextReadLen =< 0->
-  {Result,Remaining}=split_binary(Buf,ReadLen),
-  {State#t_socket{buffer = Remaining},{ok,Result}};
-
-loop_recv(State=#t_socket{socket = Socket,buffer = Buf},ReadLen,NextReadLen) when NextReadLen >0 ->
-  case gen_tcp:recv(Socket,0,State#t_socket.recv_timeout) of
-    {error,Error}->
-      gen_tcp:close(Socket),
-      {State,{error,Error}};
-    {ok,Data}->
-      Binary=iolist_to_binary([Buf,Data]),
-      Give=min(iolist_size(Binary),ReadLen),
-      loop_recv(State#t_socket{buffer = Binary},ReadLen,ReadLen-Give)
-  end.
-
-recv(State = #t_socket{socket = Socket, buffer = Buf}, Len) ->
-  case gen_tcp:recv(Socket, 0, State#t_socket.recv_timeout) of
-    {error, Error} ->
-      gen_tcp:close(Socket),
-      {State, {error, Error}};
-    {ok, Data} ->
-      Binary = iolist_to_binary([Buf, Data]),
-      Give = min(iolist_size(Binary), Len),
-      {Result, Remaining} = split_binary(Binary, Give),
-      {State#t_socket{buffer = Remaining}, {ok, Result}}
-  end.
-
-
-read_exact(State = #t_socket{buffer = Buf}, Len)
-when is_integer(Len), Len >= 0 ->
-  Binary = iolist_to_binary(Buf),
-  case iolist_size(Binary) of
-    X when X >= Len -> read(State, Len);
-    X ->
-      case gen_tcp:recv(State#t_socket.socket, Len - X, State#t_socket.recv_timeout) of
+loop_recv(State = #t_socket{buffer = Buf}, ReadLen, NextReadLen) when NextReadLen =< 0 ->
+    {Result, Remaining} = split_binary(Buf, ReadLen),
+    {State#t_socket{buffer = Remaining}, {ok, Result}};
+loop_recv(State = #t_socket{socket = Socket, buffer = Buf}, ReadLen, NextReadLen) when
+    NextReadLen > 0
+->
+    case gen_tcp:recv(Socket, 0, State#t_socket.recv_timeout) of
         {error, Error} ->
-          gen_tcp:close(State#t_socket.socket),
-          {State, {error, Error}};
+            gen_tcp:close(Socket),
+            {State, {error, Error}};
         {ok, Data} ->
-          {State#t_socket{buffer = []}, {ok, <<Binary/binary, Data/binary>>}}
-      end
-  end.
+            Binary = iolist_to_binary([Buf, Data]),
+            Give = min(iolist_size(Binary), ReadLen),
+            loop_recv(State#t_socket{buffer = Binary}, ReadLen, ReadLen - Give)
+    end.
 
+read_exact(State = #t_socket{buffer = Buf}, Len) when
+    is_integer(Len), Len >= 0
+->
+    Binary = iolist_to_binary(Buf),
+    case iolist_size(Binary) of
+        X when X >= Len -> read(State, Len);
+        X ->
+            case gen_tcp:recv(State#t_socket.socket, Len - X, State#t_socket.recv_timeout) of
+                {error, Error} ->
+                    gen_tcp:close(State#t_socket.socket),
+                    {State, {error, Error}};
+                {ok, Data} ->
+                    {State#t_socket{buffer = []}, {ok, <<Binary/binary, Data/binary>>}}
+            end
+    end.
 
 write(State = #t_socket{socket = Socket}, Data) ->
-  case gen_tcp:send(Socket, Data) of
-    {error, Error} ->
-      gen_tcp:close(Socket),
-      {State, {error, Error}};
-    ok -> {State, ok}
-  end.
-
+    case gen_tcp:send(Socket, Data) of
+        {error, Error} ->
+            gen_tcp:close(Socket),
+            {State, {error, Error}};
+        ok ->
+            {State, ok}
+    end.
 
 flush(State) ->
-  {State#t_socket{buffer = []}, ok}.
-
+    {State#t_socket{buffer = []}, ok}.
 
 close(State = #t_socket{socket = Socket}) ->
-  {State, gen_tcp:close(Socket)}.
-
+    {State, gen_tcp:close(Socket)}.
 
 %% legacy api. left for compatibility
 
@@ -143,51 +119,61 @@
 %% proplists-style option list. They're parsed like this so it is an O(n)
 %% operation instead of O(n^2)
 -record(factory_opts, {
-  connect_timeout = infinity,
-  sockopts = [],
-  framed = false
+    connect_timeout = infinity :: timeout(),
+    sockopts = [] :: [inet:inet_backend() | gen_tcp:connect_option()],
+    framed = false :: boolean()
 }).
 
-parse_factory_options([], FactoryOpts, TransOpts) -> {FactoryOpts, TransOpts};
-parse_factory_options([{framed, Bool}|Rest], FactoryOpts, TransOpts)
-when is_boolean(Bool) ->
-  parse_factory_options(Rest, FactoryOpts#factory_opts{framed = Bool}, TransOpts);
-parse_factory_options([{sockopts, OptList}|Rest], FactoryOpts, TransOpts)
-when is_list(OptList) ->
-  parse_factory_options(Rest, FactoryOpts#factory_opts{sockopts = OptList}, TransOpts);
-parse_factory_options([{connect_timeout, TO}|Rest], FactoryOpts, TransOpts)
-when TO =:= infinity; is_integer(TO) ->
-  parse_factory_options(Rest, FactoryOpts#factory_opts{connect_timeout = TO}, TransOpts);
-parse_factory_options([{recv_timeout, TO}|Rest], FactoryOpts, TransOpts)
-when TO =:= infinity; is_integer(TO) ->
-  parse_factory_options(Rest, FactoryOpts, [{recv_timeout, TO}] ++ TransOpts).
-
+parse_factory_options([], FactoryOpts, TransOpts) ->
+    {FactoryOpts, TransOpts};
+parse_factory_options([{framed, Bool} | Rest], FactoryOpts, TransOpts) when
+    is_boolean(Bool)
+->
+    parse_factory_options(Rest, FactoryOpts#factory_opts{framed = Bool}, TransOpts);
+parse_factory_options([{sockopts, OptList} | Rest], FactoryOpts, TransOpts) when
+    is_list(OptList)
+->
+    parse_factory_options(Rest, FactoryOpts#factory_opts{sockopts = OptList}, TransOpts);
+parse_factory_options([{connect_timeout, TO} | Rest], FactoryOpts, TransOpts) when
+    TO =:= infinity; is_integer(TO)
+->
+    parse_factory_options(Rest, FactoryOpts#factory_opts{connect_timeout = TO}, TransOpts);
+parse_factory_options([{recv_timeout, TO} | Rest], FactoryOpts, TransOpts) when
+    TO =:= infinity; is_integer(TO)
+->
+    parse_factory_options(Rest, FactoryOpts, [{recv_timeout, TO}] ++ TransOpts).
 
 %% Generates a "transport factory" function - a fun which returns a thrift_transport()
 %% instance.
 %% State can be passed into a protocol factory to generate a connection to a
 %% thrift server over a socket.
 new_transport_factory(Host, Port, Options) ->
-  {FactoryOpts, TransOpts} = parse_factory_options(Options, #factory_opts{}, []),
-  {ok, fun() -> SockOpts = [binary,
-      {packet, 0},
-      {active, false},
-      {nodelay, true}|FactoryOpts#factory_opts.sockopts
-    ],
-    case catch gen_tcp:connect(
-      Host,
-      Port,
-      SockOpts,
-      FactoryOpts#factory_opts.connect_timeout
-    ) of
-      {ok, Sock} ->
-        {ok, Transport} = thrift_socket_transport:new(Sock, TransOpts),
-        {ok, BufTransport} = case FactoryOpts#factory_opts.framed of
-          true  -> thrift_framed_transport:new(Transport);
-          false -> thrift_buffered_transport:new(Transport)
-        end,
-        {ok, BufTransport};
-      Error  -> Error
-    end
-  end}.
-
+    {FactoryOpts, TransOpts} = parse_factory_options(Options, #factory_opts{}, []),
+    {ok, fun() ->
+        SockOpts = [
+            binary,
+            {packet, 0},
+            {active, false},
+            {nodelay, true}
+            | FactoryOpts#factory_opts.sockopts
+        ],
+        case
+            catch gen_tcp:connect(
+                Host,
+                Port,
+                SockOpts,
+                FactoryOpts#factory_opts.connect_timeout
+            )
+        of
+            {ok, Sock} ->
+                {ok, Transport} = thrift_socket_transport:new(Sock, TransOpts),
+                {ok, BufTransport} =
+                    case FactoryOpts#factory_opts.framed of
+                        true -> thrift_framed_transport:new(Transport);
+                        false -> thrift_buffered_transport:new(Transport)
+                    end,
+                {ok, BufTransport};
+            Error ->
+                Error
+        end
+    end}.
diff --git a/lib/erl/src/thrift_sslsocket_transport.erl b/lib/erl/src/thrift_sslsocket_transport.erl
index 211153f..43e64b1 100644
--- a/lib/erl/src/thrift_sslsocket_transport.erl
+++ b/lib/erl/src/thrift_sslsocket_transport.erl
@@ -18,80 +18,97 @@
 %%
 -module(thrift_sslsocket_transport).
 
--include("thrift_transport_behaviour.hrl").
-
 -behaviour(thrift_transport).
 
--export([new/3,
-         write/2, read/2, flush/1, close/1,
+-export([
+    new/3,
+    write/2,
+    read/2,
+    flush/1,
+    close/1,
 
-         new_transport_factory/3]).
+    new_transport_factory/3
+]).
 
 %% Export only for the transport factory
 -export([new/2]).
 
--record(data, {socket,
-               recv_timeout=infinity}).
--type state() :: #data{}.
+-record(data, {
+    socket :: ssl:sslsocket(),
+    recv_timeout = infinity :: infinity | timeout()
+}).
+
+-type data() :: #data{}.
+-type reason() :: thrift_transport:reason().
 
 %% The following "local" record is filled in by parse_factory_options/2
 %% below. These options can be passed to new_protocol_factory/3 in a
 %% proplists-style option list. They're parsed like this so it is an O(n)
 %% operation instead of O(n^2)
--record(factory_opts, {connect_timeout = infinity,
-                       sockopts = [],
-                       framed = false,
-                       ssloptions = []}).
+-record(factory_opts, {
+    connect_timeout = infinity :: infinity | timeout(),
+    sockopts = [] :: [inet:inet_backend() | gen_tcp:connect_option()],
+    framed = false :: boolean(),
+    ssloptions = [] :: [ssl:tls_client_option()]
+}).
 
 parse_factory_options([], Opts) ->
     Opts;
 parse_factory_options([{framed, Bool} | Rest], Opts) when is_boolean(Bool) ->
-    parse_factory_options(Rest, Opts#factory_opts{framed=Bool});
+    parse_factory_options(Rest, Opts#factory_opts{framed = Bool});
 parse_factory_options([{sockopts, OptList} | Rest], Opts) when is_list(OptList) ->
-    parse_factory_options(Rest, Opts#factory_opts{sockopts=OptList});
+    parse_factory_options(Rest, Opts#factory_opts{sockopts = OptList});
 parse_factory_options([{connect_timeout, TO} | Rest], Opts) when TO =:= infinity; is_integer(TO) ->
-    parse_factory_options(Rest, Opts#factory_opts{connect_timeout=TO});
+    parse_factory_options(Rest, Opts#factory_opts{connect_timeout = TO});
 parse_factory_options([{ssloptions, SslOptions} | Rest], Opts) when is_list(SslOptions) ->
-    parse_factory_options(Rest, Opts#factory_opts{ssloptions=SslOptions}).
+    parse_factory_options(Rest, Opts#factory_opts{ssloptions = SslOptions}).
 
 new(Socket, SockOpts, SslOptions) when is_list(SockOpts), is_list(SslOptions) ->
-    inet:setopts(Socket, [{active, false}]), %% => prevent the ssl handshake messages get lost
+    %% => prevent the ssl handshake messages get lost
+    ok = inet:setopts(Socket, [{active, false}]),
 
     %% upgrade to an ssl socket
-    case catch ssl:ssl_accept(Socket, SslOptions) of % infinite timeout
+
+    % infinite timeout
+    case catch ssl:handshake(Socket, SslOptions) of
         {ok, SslSocket} ->
             new(SslSocket, SockOpts);
         {error, Reason} ->
             exit({error, Reason});
         Other ->
             error_logger:error_report(
-              [{application, thrift},
-               "SSL accept failed error",
-               lists:flatten(io_lib:format("~p", [Other]))]),
+                [
+                    {application, thrift},
+                    "SSL accept failed error",
+                    lists:flatten(io_lib:format("~p", [Other]))
+                ]
+            ),
             exit({error, ssl_accept_failed})
     end.
 
 new(SslSocket, SockOpts) ->
     State =
         case lists:keysearch(recv_timeout, 1, SockOpts) of
-            {value, {recv_timeout, Timeout}}
-              when is_integer(Timeout), Timeout > 0 ->
-                #data{socket=SslSocket, recv_timeout=Timeout};
+            {value, {recv_timeout, Timeout}} when
+                is_integer(Timeout), Timeout > 0
+            ->
+                #data{socket = SslSocket, recv_timeout = Timeout};
             _ ->
-                #data{socket=SslSocket}
+                #data{socket = SslSocket}
         end,
     thrift_transport:new(?MODULE, State).
 
 %% Data :: iolist()
+-spec write(data(), iolist()) -> {data(), ok | {error, reason()}}.
 write(This = #data{socket = Socket}, Data) ->
     {This, ssl:send(Socket, Data)}.
 
-read(This = #data{socket=Socket, recv_timeout=Timeout}, Len)
-  when is_integer(Len), Len >= 0 ->
+read(This = #data{socket = Socket, recv_timeout = Timeout}, Len) when
+    is_integer(Len), Len >= 0
+->
     case ssl:recv(Socket, Len, Timeout) of
         Err = {error, timeout} ->
-            error_logger:info_msg("read timeout: peer conn ~p", [inet:peername(Socket)]),
-            ssl:close(Socket),
+            ok = ssl:close(Socket),
             {This, Err};
         Data ->
             {This, Data}
@@ -116,32 +133,48 @@
     ParsedOpts = parse_factory_options(Options, #factory_opts{}),
 
     F = fun() ->
-                SockOpts = [binary,
-                            {packet, 0},
-                            {active, false},
-                            {nodelay, true} |
-                            ParsedOpts#factory_opts.sockopts],
-                case catch gen_tcp:connect(Host, Port, SockOpts,
-                                           ParsedOpts#factory_opts.connect_timeout) of
-                    {ok, Sock} ->
-                        SslSock = case catch ssl:connect(Sock, ParsedOpts#factory_opts.ssloptions,
-                                                         ParsedOpts#factory_opts.connect_timeout) of
-                                      {ok, SslSocket} ->
-                                          SslSocket;
-                                      Other ->
-                                          error_logger:info_msg("error while connecting over ssl - reason: ~p~n", [Other]),
-                                          catch gen_tcp:close(Sock),
-                                          exit(error)
-                                  end,
-                        {ok, Transport} = thrift_sslsocket_transport:new(SslSock, SockOpts),
-                        {ok, BufTransport} =
-                            case ParsedOpts#factory_opts.framed of
-                                true  -> thrift_framed_transport:new(Transport);
-                                false -> thrift_buffered_transport:new(Transport)
-                            end,
-                        {ok, BufTransport};
-                    Error  ->
-                        Error
-                end
-        end,
-    {ok, F}.
\ No newline at end of file
+        SockOpts = [
+            binary,
+            {packet, 0},
+            {active, false},
+            {nodelay, true}
+            | ParsedOpts#factory_opts.sockopts
+        ],
+        case
+            catch gen_tcp:connect(
+                Host,
+                Port,
+                SockOpts,
+                ParsedOpts#factory_opts.connect_timeout
+            )
+        of
+            {ok, Sock} ->
+                SslSock =
+                    case
+                        catch ssl:connect(
+                            Sock,
+                            ParsedOpts#factory_opts.ssloptions,
+                            ParsedOpts#factory_opts.connect_timeout
+                        )
+                    of
+                        {ok, SslSocket} ->
+                            SslSocket;
+                        Other ->
+                            error_logger:info_msg(
+                                "error while connecting over ssl - reason: ~p~n", [Other]
+                            ),
+                            catch gen_tcp:close(Sock),
+                            exit(error)
+                    end,
+                {ok, Transport} = thrift_sslsocket_transport:new(SslSock, SockOpts),
+                {ok, BufTransport} =
+                    case ParsedOpts#factory_opts.framed of
+                        true -> thrift_framed_transport:new(Transport);
+                        false -> thrift_buffered_transport:new(Transport)
+                    end,
+                {ok, BufTransport};
+            Error ->
+                Error
+        end
+    end,
+    {ok, F}.
diff --git a/lib/erl/src/thrift_transport.erl b/lib/erl/src/thrift_transport.erl
index 2414bde..cc9ca1b 100644
--- a/lib/erl/src/thrift_transport.erl
+++ b/lib/erl/src/thrift_transport.erl
@@ -19,108 +19,105 @@
 
 -module(thrift_transport).
 
--export([behaviour_info/1]).
 %% constructors
 -export([new/1, new/2]).
 %% transport callbacks
 -export([read/2, read_exact/2, write/2, flush/1, close/1]).
 
+-record(t_transport, {
+    module :: module(),
+    state :: term()
+}).
+-type t_transport() :: #t_transport{}.
 -export_type([t_transport/0]).
 
+%%%=========================================================================
+%%%  API
+%%%=========================================================================
+-type state() :: term().
+-export_type([state/0]).
+-type reason() :: term().
+-export_type([reason/0]).
 
-behaviour_info(callbacks) ->
-  [{read, 2}, {write, 2}, {flush, 1}, {close, 1}].
-
-
--record(t_transport, {
-  module,
-  state
-}).
-
--type state() :: #t_transport{}.
--type t_transport() :: #t_transport{}.
-
+-callback write(state(), iolist() | binary()) -> {state(), ok | {error, reason()}}.
+-callback read(state(), non_neg_integer()) -> {state(), {ok, binary()} | {error, reason()}}.
+-callback flush(state()) -> {state(), ok | {error, reason()}}.
+-callback close(state()) -> {state(), ok | {error, reason()}}.
 
 -ifdef(transport_wrapper_module).
 -define(debug_wrap(Transport),
-  case Transport#t_transport.module of
-    ?transport_wrapper_module -> Transport;
-    _Else ->
-      {ok, Result} = ?transport_wrapper_module:new(Transport),
-      Result
-  end
+    case Transport#t_transport.module of
+        ?transport_wrapper_module ->
+            Transport;
+        _Else ->
+            {ok, Result} = ?transport_wrapper_module:new(Transport),
+            Result
+    end
 ).
 -else.
 -define(debug_wrap(Transport), Transport).
 -endif.
 
-
 -type wrappable() ::
-  binary() |
-  list() |
-  {membuffer, binary() | list()} |
-  {tcp, port()} |
-  {tcp, port(), list()} |
-  {file, file:io_device()} |
-  {file, file:io_device(), list()} |
-  {file, file:filename()} |
-  {file, file:filename(), list()}.
+    binary()
+    | list()
+    | {membuffer, binary() | list()}
+    | {membuffer, binary() | list(), list()}
+    | {tcp, port()}
+    | {tcp, port(), list()}
+    | {file, file:io_device()}
+    | {file, file:io_device(), list()}
+    | {file, file:filename()}
+    | {file, file:filename(), list()}.
 
 -spec new(wrappable()) -> {ok, #t_transport{}}.
 
-new({membuffer, Membuffer}) when is_binary(Membuffer); is_list(Membuffer) ->
-  thrift_membuffer_transport:new(Membuffer);
-new({membuffer, Membuffer, []}) when is_binary(Membuffer); is_list(Membuffer) ->
-  thrift_membuffer_transport:new(Membuffer);
+new({membuffer, Membuffer}) ->
+    new({membuffer, Membuffer, []});
+new({membuffer, Membuffer, Opts}) when is_binary(Membuffer); is_list(Membuffer) ->
+    thrift_membuffer_transport:new(Membuffer, Opts);
 new({tcp, Socket}) when is_port(Socket) ->
-  new({tcp, Socket, []});
+    new({tcp, Socket, []});
 new({tcp, Socket, Opts}) when is_port(Socket) ->
-  thrift_socket_transport:new(Socket, Opts);
+    thrift_socket_transport:new(Socket, Opts);
 new({file, Filename}) when is_list(Filename); is_binary(Filename) ->
-  new({file, Filename, []});
+    new({file, Filename, []});
 new({file, Filename, Opts}) when is_list(Filename); is_binary(Filename) ->
-  {ok, File} = file:open(Filename, [raw, binary]),
-  new({file, File, Opts});
+    {ok, File} = file:open(Filename, [raw, binary]),
+    new({file, File, Opts});
 new({file, File, Opts}) ->
-  thrift_file_transport:new(File, Opts).
+    thrift_file_transport:new(File, Opts).
 
--spec new(Module::module(), State::any()) -> {ok, #t_transport{}}.
+-spec new(Module :: module(), State :: any()) -> {ok, t_transport()}.
 
 new(Module, State) when is_atom(Module) ->
-  {ok, ?debug_wrap(#t_transport{module = Module, state = State})}.
+    {ok, ?debug_wrap(#t_transport{module = Module, state = State})}.
 
+read(Transport = #t_transport{module = Module}, Len) when
+    is_integer(Len), Len >= 0
+->
+    {NewState, Result} = Module:read(Transport#t_transport.state, Len),
+    {Transport#t_transport{state = NewState}, Result}.
 
--include("thrift_transport_behaviour.hrl").
-
-
-read(Transport = #t_transport{module = Module}, Len)
-when is_integer(Len), Len >= 0 ->
-  {NewState, Result} = Module:read(Transport#t_transport.state, Len),
-  {Transport#t_transport{state = NewState}, Result}.
-
-
-read_exact(Transport = #t_transport{module = Module}, Len)
-when is_integer(Len), Len >= 0 ->
-  case lists:keyfind(read_exact, 1, Module:module_info(exports)) of
-    {read_exact, 2} ->
-      {NewState, Result} = Module:read_exact(Transport#t_transport.state, Len),
-      {Transport#t_transport{state = NewState}, Result};
-    _ ->
-      read(Transport, Len)
-  end.
-
+read_exact(Transport = #t_transport{module = Module}, Len) when
+    is_integer(Len), Len >= 0
+->
+    case lists:keyfind(read_exact, 1, Module:module_info(exports)) of
+        {read_exact, 2} ->
+            {NewState, Result} = Module:read_exact(Transport#t_transport.state, Len),
+            {Transport#t_transport{state = NewState}, Result};
+        _ ->
+            read(Transport, Len)
+    end.
 
 write(Transport = #t_transport{module = Module}, Data) ->
-  {NewState, Result} = Module:write(Transport#t_transport.state, Data),
-  {Transport#t_transport{state = NewState}, Result}.
-
+    {NewState, Result} = Module:write(Transport#t_transport.state, Data),
+    {Transport#t_transport{state = NewState}, Result}.
 
 flush(Transport = #t_transport{module = Module}) ->
-  {NewState, Result} = Module:flush(Transport#t_transport.state),
-  {Transport#t_transport{state = NewState}, Result}.
-
+    {NewState, Result} = Module:flush(Transport#t_transport.state),
+    {Transport#t_transport{state = NewState}, Result}.
 
 close(Transport = #t_transport{module = Module}) ->
-  {NewState, Result} = Module:close(Transport#t_transport.state),
-  {Transport#t_transport{state = NewState}, Result}.
-
+    {NewState, Result} = Module:close(Transport#t_transport.state),
+    {Transport#t_transport{state = NewState}, Result}.
diff --git a/lib/erl/src/thrift_transport_state_test.erl b/lib/erl/src/thrift_transport_state_test.erl
index e83a44d..99b5649 100644
--- a/lib/erl/src/thrift_transport_state_test.erl
+++ b/lib/erl/src/thrift_transport_state_test.erl
@@ -26,28 +26,35 @@
 -export([new/1]).
 
 %% gen_server callbacks
--export([init/1, handle_call/3, handle_cast/2, handle_info/2,
-         terminate/2, code_change/3]).
+-export([
+    init/1,
+    handle_call/3,
+    handle_cast/2,
+    handle_info/2,
+    terminate/2,
+    code_change/3
+]).
 
 %% thrift_transport callbacks
 -export([write/2, read/2, flush/1, close/1]).
 
--record(trans, {wrapped, % #thrift_transport{}
-                version :: integer(),
-                counter :: pid()
-               }).
--type state() :: #trans{}.
--include("thrift_transport_behaviour.hrl").
+% #thrift_transport{}
+-record(trans, {
+    wrapped :: thrift_transport:t_transport(),
+    version :: integer(),
+    counter :: pid()
+}).
 
 -record(state, {cversion :: integer()}).
 
-
 new(WrappedTransport) ->
     case gen_server:start_link(?MODULE, [], []) of
         {ok, Pid} ->
-            Trans = #trans{wrapped = WrappedTransport,
-                           version = 0,
-                           counter = Pid},
+            Trans = #trans{
+                wrapped = WrappedTransport,
+                version = 0,
+                counter = Pid
+            },
             thrift_transport:new(?MODULE, Trans);
         Else ->
             Else
@@ -82,7 +89,6 @@
     Transport2 = Transport1#trans{wrapped = Wrapped1},
     {Transport2, Result}.
 
-
 %%====================================================================
 %% gen_server callbacks
 %%====================================================================
@@ -91,7 +97,7 @@
     {ok, #state{cversion = 0}}.
 
 handle_call(check_version, _From, State = #state{cversion = Version}) ->
-    {reply, Version, State#state{cversion = Version+1}}.
+    {reply, Version, State#state{cversion = Version + 1}}.
 
 handle_cast(shutdown, State) ->
     {stop, normal, State}.
@@ -107,7 +113,7 @@
 check_version(Transport = #trans{version = Version, counter = Counter}) ->
     case gen_server:call(Counter, check_version) of
         Version ->
-            Transport#trans{version = Version+1};
+            Transport#trans{version = Version + 1};
         _Else ->
             % State wasn't propagated properly.  Die.
             erlang:error(state_not_propagated)
diff --git a/lib/erl/test/legacy_names_test.erl b/lib/erl/test/legacy_names_test.erl
index c16aa3e..9076ffb 100644
--- a/lib/erl/test/legacy_names_test.erl
+++ b/lib/erl/test/legacy_names_test.erl
@@ -18,52 +18,58 @@
 %%
 
 -module(legacy_names_test).
--compile(export_all).
 
 -include_lib("eunit/include/eunit.hrl").
 
 -include("gen-erl/legacyNames_constants.hrl").
 
 record_generation_test_() ->
-  [
-    {"capitalizedStruct record", ?_assertMatch(
-      {capitalizedStruct, _, _},
-      #capitalizedStruct{id=null,message=null}
-    )}
-  ].
+    [
+        {"capitalizedStruct record",
+            ?_assertMatch(
+                {capitalizedStruct, _, _},
+                #capitalizedStruct{id = null, message = null}
+            )}
+    ].
 
 struct_info_test_() ->
-  [
-    {"capitalizedStruct extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, i32, 'id', undefined},
-        {2, undefined, string, 'message', undefined}
-      ]},
-      legacyNames_types:struct_info_ext(capitalizedStruct)
-    )},
-    {"listCapitalizedStructs extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {list, {struct, {'legacyNames_types', 'capitalizedStruct'}}}, 'structs', []}
-      ]},
-      legacyNames_types:struct_info_ext(listCapitalizedStructs)
-    )}
-  ].
+    [
+        {"capitalizedStruct extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, i32, 'id', undefined},
+                    {2, undefined, string, 'message', undefined}
+                ]},
+                legacyNames_types:struct_info_ext(capitalizedStruct)
+            )},
+        {"listCapitalizedStructs extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {list, {struct, {'legacyNames_types', 'capitalizedStruct'}}},
+                        'structs', []}
+                ]},
+                legacyNames_types:struct_info_ext(listCapitalizedStructs)
+            )}
+    ].
 
 service_info_test_() ->
-  [
-    {"names params", ?_assertEqual(
-      {struct, [
-        {1, {struct, {'legacyNames_types', 'capitalizedStruct'}}},
-        {2, {struct, {'legacyNames_types', 'capitalizedStruct'}}}
-      ]},
-      legacyNames_thrift:function_info(names, params_type)
-    )},
-    {"names reply", ?_assertEqual(
-      {struct, {'legacyNames_types', 'listCapitalizedStructs'}},
-      legacyNames_thrift:function_info(names, reply_type)
-    )},
-    {"names exceptions", ?_assertEqual(
-      {struct, [{1, {struct, {'legacyNames_types', 'xception'}}}]},
-      legacyNames_thrift:function_info(names, exceptions)
-    )}
-  ].
+    [
+        {"names params",
+            ?_assertEqual(
+                {struct, [
+                    {1, {struct, {'legacyNames_types', 'capitalizedStruct'}}},
+                    {2, {struct, {'legacyNames_types', 'capitalizedStruct'}}}
+                ]},
+                legacyNames_thrift:function_info(names, params_type)
+            )},
+        {"names reply",
+            ?_assertEqual(
+                {struct, {'legacyNames_types', 'listCapitalizedStructs'}},
+                legacyNames_thrift:function_info(names, reply_type)
+            )},
+        {"names exceptions",
+            ?_assertEqual(
+                {struct, [{1, {struct, {'legacyNames_types', 'xception'}}}]},
+                legacyNames_thrift:function_info(names, exceptions)
+            )}
+    ].
diff --git a/lib/erl/test/multiplexing_test.erl b/lib/erl/test/multiplexing_test.erl
index 0f2d616..5752e53 100644
--- a/lib/erl/test/multiplexing_test.erl
+++ b/lib/erl/test/multiplexing_test.erl
@@ -1,19 +1,37 @@
+%%
+%% 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.
+%%
+
 -module(multiplexing_test).
 
 -include_lib("eunit/include/eunit.hrl").
 
 -export([
-     handle_function/2
-    ,handle_error/2
+    handle_function/2,
+    handle_error/2
 ]).
 
 start_multiplexed_server_test() ->
-
     Port = 9090,
     Services = [
-                {"Multiplexing_Calculator",    multiplexing__calculator_thrift},
-                {"Multiplexing_WeatherReport", multiplexing__weather_report_thrift}
-               ],
+        {"Multiplexing_Calculator", multiplexing__calculator_thrift},
+        {"Multiplexing_WeatherReport", multiplexing__weather_report_thrift}
+    ],
 
     {ok, Pid} = thrift_socket_server:start([
         {ip, "127.0.0.1"},
@@ -21,21 +39,32 @@
         {name, ?MODULE},
         {service, Services},
         {handler, [
-            {"error_handler",              ?MODULE},
-            {"Multiplexing_Calculator",    ?MODULE},
+            {"error_handler", ?MODULE},
+            {"Multiplexing_Calculator", ?MODULE},
             {"Multiplexing_WeatherReport", ?MODULE}
         ]}
-     ]),
+    ]),
 
-    {ok, [{"Multiplexing_Calculator", CalculatorClient0},
-          {"Multiplexing_WeatherReport", WeatherReportClient0}]} = thrift_client_util:new_multiplexed("127.0.0.1", Port, Services, []),
+    {ok, [
+        {"Multiplexing_Calculator", CalculatorClient0},
+        {"Multiplexing_WeatherReport", WeatherReportClient0}
+    ]} = thrift_client_util:new_multiplexed("127.0.0.1", Port, Services, []),
 
-    ?assertMatch({_, {error, {bad_args, _, _}}}, thrift_client:call(WeatherReportClient0, getTemperature, [1])),
+    ?assertMatch(
+        {_, {error, {bad_args, _, _}}},
+        thrift_client:call(WeatherReportClient0, getTemperature, [1])
+    ),
     ?assertMatch({_, {error, {bad_args, _, _}}}, thrift_client:call(CalculatorClient0, add, [1])),
-    ?assertMatch({_, {error, {bad_args, _, _}}}, thrift_client:call(CalculatorClient0, add, [1,1,1])),
+    ?assertMatch(
+        {_, {error, {bad_args, _, _}}}, thrift_client:call(CalculatorClient0, add, [1, 1, 1])
+    ),
 
-    ?assertMatch({_, {error, {no_function, _}}}, thrift_client:call(CalculatorClient0, getTemperature, [])),
-    ?assertMatch({_, {error, {no_function, _}}}, thrift_client:call(WeatherReportClient0, add, [41, 1])),
+    ?assertMatch(
+        {_, {error, {no_function, _}}}, thrift_client:call(CalculatorClient0, getTemperature, [])
+    ),
+    ?assertMatch(
+        {_, {error, {no_function, _}}}, thrift_client:call(WeatherReportClient0, add, [41, 1])
+    ),
 
     ?assertMatch({_, {ok, 42}}, thrift_client:call(CalculatorClient0, add, [41, 1])),
     ?assertMatch({_, {ok, 42.0}}, thrift_client:call(WeatherReportClient0, getTemperature, [])),
@@ -47,11 +76,10 @@
 %% Calculator handles
 handle_function(add, {X, Y}) ->
     {reply, X + Y};
-
 %% WeatherReport handles
 handle_function(getTemperature, {}) ->
     {reply, 42.0}.
 
 handle_error(_F, _Reason) ->
-%%     ?debugHere, ?debugVal({_F, _Reason}),
-    ok.
\ No newline at end of file
+    %%     ?debugHere, ?debugVal({_F, _Reason}),
+    ok.
diff --git a/lib/erl/test/name_conflict_test.erl b/lib/erl/test/name_conflict_test.erl
index b01df57..30c1a8e 100644
--- a/lib/erl/test/name_conflict_test.erl
+++ b/lib/erl/test/name_conflict_test.erl
@@ -18,282 +18,333 @@
 %%
 
 -module(name_conflict_test).
--compile(export_all).
 
 -include_lib("eunit/include/eunit.hrl").
 
 -include("gen-erl/name_conflict_test_constants.hrl").
 
 record_generation_test_() ->
-  [
-    {"using record", ?_assertMatch(
-      {using, _, _},
-      #using{single=null,integer=null}
-    )},
-    {"delegate record", ?_assertMatch(
-      {delegate, _, _},
-      #delegate{partial=null,delegate=null}
-    )},
-    {"get record", ?_assertMatch(
-      {get, _},
-      #get{sbyte=null}
-    )},
-    {"partial record", ?_assertMatch(
-      {partial, _, _, _},
-      #partial{using=null}
-    )},
-    {"ClassAndProp record", ?_assertMatch(
-      {'ClassAndProp', _, _, _, _},
-      #'ClassAndProp'{
-        'ClassAndProp'=null,
-        'ClassAndProp_'=null,
-        'ClassAndProp__'=null,
-        'ClassAndProper'=null
-      }
-    )},
-    {"second_chance record", ?_assertMatch(
-      {second_chance, _, _, _, _},
-      #second_chance{
-        'SECOND_CHANCE'=null,
-        'SECOND_CHANCE_'=null,
-        'SECOND_CHANCE__'=null,
-        'SECOND_CHANCES'=null
-      }
-    )},
-    {"NOW_EAT_THIS record", ?_assertMatch(
-      {'NOW_EAT_THIS', _, _, _, _},
-      #'NOW_EAT_THIS'{
-        now_eat_this=null,
-        now_eat_this_=null,
-        now_eat_this__=null,
-        now_eat_this_and_this=null
-      }
-    )},
-    {"TheEdgeCase record", ?_assertMatch(
-      {'TheEdgeCase', _, _, _, _, _, _},
-      #'TheEdgeCase'{
-        theEdgeCase=null,
-        theEdgeCase_=null,
-        theEdgeCase__=null,
-        'TheEdgeCase'=null,
-        'TheEdgeCase_'=null,
-        'TheEdgeCase__'=null
-      }
-    )},
-    {"Tricky_ record", ?_assertMatch(
-      {'Tricky_', _, _},
-      #'Tricky_'{tricky=null,'Tricky'=null}
-    )},
-    {"Nested record", ?_assertMatch(
-      {'Nested', _, _, _, _, _, _},
-      #'Nested'{
-        'ClassAndProp'=null,
-        second_chance=null,
-        'NOW_EAT_THIS'=null,
-        'TheEdgeCase'=null,
-        'Tricky_'=null,
-        'Nested'=null
-      }
-    )},
-    {"Problem_ record", ?_assertMatch(
-      {'Problem_', _, _},
-      #'Problem_'{problem=null,'Problem'=null}
-    )}
-  ].
+    [
+        {"using record",
+            ?_assertMatch(
+                {using, _, _},
+                #using{single = null, integer = null}
+            )},
+        {"delegate record",
+            ?_assertMatch(
+                {delegate, _, _},
+                #delegate{partial = null, delegate = null}
+            )},
+        {"get record",
+            ?_assertMatch(
+                {get, _},
+                #get{sbyte = null}
+            )},
+        {"partial record",
+            ?_assertMatch(
+                {partial, _, _, _},
+                #partial{using = null}
+            )},
+        {"ClassAndProp record",
+            ?_assertMatch(
+                {'ClassAndProp', _, _, _, _},
+                #'ClassAndProp'{
+                    'ClassAndProp' = null,
+                    'ClassAndProp_' = null,
+                    'ClassAndProp__' = null,
+                    'ClassAndProper' = null
+                }
+            )},
+        {"second_chance record",
+            ?_assertMatch(
+                {second_chance, _, _, _, _},
+                #second_chance{
+                    'SECOND_CHANCE' = null,
+                    'SECOND_CHANCE_' = null,
+                    'SECOND_CHANCE__' = null,
+                    'SECOND_CHANCES' = null
+                }
+            )},
+        {"NOW_EAT_THIS record",
+            ?_assertMatch(
+                {'NOW_EAT_THIS', _, _, _, _},
+                #'NOW_EAT_THIS'{
+                    now_eat_this = null,
+                    now_eat_this_ = null,
+                    now_eat_this__ = null,
+                    now_eat_this_and_this = null
+                }
+            )},
+        {"TheEdgeCase record",
+            ?_assertMatch(
+                {'TheEdgeCase', _, _, _, _, _, _},
+                #'TheEdgeCase'{
+                    theEdgeCase = null,
+                    theEdgeCase_ = null,
+                    theEdgeCase__ = null,
+                    'TheEdgeCase' = null,
+                    'TheEdgeCase_' = null,
+                    'TheEdgeCase__' = null
+                }
+            )},
+        {"Tricky_ record",
+            ?_assertMatch(
+                {'Tricky_', _, _},
+                #'Tricky_'{tricky = null, 'Tricky' = null}
+            )},
+        {"Nested record",
+            ?_assertMatch(
+                {'Nested', _, _, _, _, _, _},
+                #'Nested'{
+                    'ClassAndProp' = null,
+                    second_chance = null,
+                    'NOW_EAT_THIS' = null,
+                    'TheEdgeCase' = null,
+                    'Tricky_' = null,
+                    'Nested' = null
+                }
+            )},
+        {"Problem_ record",
+            ?_assertMatch(
+                {'Problem_', _, _},
+                #'Problem_'{problem = null, 'Problem' = null}
+            )}
+    ].
 
 struct_info_test_() ->
-  [
-    {"using definition", ?_assertEqual(
-      {struct, [{1, double},{2, double}]},
-      name_conflict_test_types:struct_info(using)
-    )},
-    {"delegate definition", ?_assertEqual(
-      {struct, [
-        {1, string},
-        {2, {struct, {name_conflict_test_types, delegate}}}
-      ]},
-      name_conflict_test_types:struct_info(delegate)
-    )},
-    {"get definition", ?_assertEqual(
-      {struct, [{1, bool}]},
-      name_conflict_test_types:struct_info(get)
-    )},
-    {"partial definition", ?_assertEqual(
-      {struct, [
-        {1, {struct, {name_conflict_test_types, using}}},
-        {2, bool},
-        {3, bool}
-      ]},
-      name_conflict_test_types:struct_info(partial)
-    )},
-    {"ClassAndProp definition", ?_assertEqual(
-      {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]},
-      name_conflict_test_types:struct_info('ClassAndProp')
-    )},
-    {"second_chance definition", ?_assertEqual(
-      {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]},
-      name_conflict_test_types:struct_info(second_chance)
-    )},
-    {"NOW_EAT_THIS definition", ?_assertEqual(
-      {struct, [{1, bool},{2, bool},{3, bool},{4, bool}]},
-      name_conflict_test_types:struct_info('NOW_EAT_THIS')
-    )},
-    {"TheEdgeCase definition", ?_assertEqual(
-      {struct, [{1, bool},{2, bool},{3, bool},{4, bool},{5, bool},{6, bool}]},
-      name_conflict_test_types:struct_info('TheEdgeCase')
-    )},
-    {"Tricky_ definition", ?_assertEqual(
-      {struct, [{1, bool},{2, bool}]},
-      name_conflict_test_types:struct_info('Tricky_')
-    )},
-    {"Nested definition", ?_assertEqual(
-      {struct, [
-        {1, {struct, {name_conflict_test_types, 'ClassAndProp'}}},
-        {2, {struct, {name_conflict_test_types, second_chance}}},
-        {3, {struct, {name_conflict_test_types, 'NOW_EAT_THIS'}}},
-        {4, {struct, {name_conflict_test_types, 'TheEdgeCase'}}},
-        {5, {struct, {name_conflict_test_types, 'Tricky_'}}},
-        {6, {struct, {name_conflict_test_types, 'Nested'}}}
-      ]},
-      name_conflict_test_types:struct_info('Nested')
-    )},
-    {"Problem_ definition", ?_assertEqual(
-      {struct, [{1, bool},{2, bool}]},
-      name_conflict_test_types:struct_info('Problem_')
-    )},
-    {"using extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, double, single, undefined},
-        {2, undefined, double, integer, undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext(using)
-    )},
-    {"delegate extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, string, partial, undefined},
-        {2, undefined, {struct, {name_conflict_test_types, delegate}}, delegate, undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext(delegate)
-    )},
-    {"get extended definition", ?_assertEqual(
-      {struct, [{1, undefined, bool, sbyte, undefined}]},
-      name_conflict_test_types:struct_info_ext(get)
-    )},
-    {"partial extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {struct, {name_conflict_test_types, using}}, using, #using{}},
-        {2, undefined, bool, read, undefined},
-        {3, undefined, bool, write, undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext(partial)
-    )},
-    {"ClassAndProp extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, bool, 'ClassAndProp', undefined},
-        {2, undefined, bool, 'ClassAndProp_', undefined},
-        {3, undefined, bool, 'ClassAndProp__', undefined},
-        {4, undefined, bool, 'ClassAndProper', undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext('ClassAndProp')
-    )},
-    {"second_chance extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, bool, 'SECOND_CHANCE', undefined},
-        {2, undefined, bool, 'SECOND_CHANCE_', undefined},
-        {3, undefined, bool, 'SECOND_CHANCE__', undefined},
-        {4, undefined, bool, 'SECOND_CHANCES', undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext(second_chance)
-    )},
-    {"NOW_EAT_THIS extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, bool, now_eat_this, undefined},
-        {2, undefined, bool, now_eat_this_, undefined},
-        {3, undefined, bool, now_eat_this__, undefined},
-        {4, undefined, bool, now_eat_this_and_this, undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext('NOW_EAT_THIS')
-    )},
-    {"TheEdgeCase extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, bool, theEdgeCase, undefined},
-        {2, undefined, bool, theEdgeCase_, undefined},
-        {3, undefined, bool, theEdgeCase__, undefined},
-        {4, undefined, bool, 'TheEdgeCase', undefined},
-        {5, undefined, bool, 'TheEdgeCase_', undefined},
-        {6, undefined, bool, 'TheEdgeCase__', undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext('TheEdgeCase')
-    )},
-    {"Tricky_ extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, bool, tricky, undefined},
-        {2, undefined, bool, 'Tricky', undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext('Tricky_')
-    )},
-    {"Nested extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {struct, {
-          name_conflict_test_types,
-          'ClassAndProp'
-        }}, 'ClassAndProp', #'ClassAndProp'{}},
-        {2, undefined, {struct, {
-          name_conflict_test_types,
-          second_chance
-        }}, second_chance, #second_chance{}},
-        {3, undefined, {struct, {
-          name_conflict_test_types,
-          'NOW_EAT_THIS'
-        }}, 'NOW_EAT_THIS', #'NOW_EAT_THIS'{}},
-        {4, undefined, {struct, {
-          name_conflict_test_types,
-          'TheEdgeCase'
-        }}, 'TheEdgeCase', #'TheEdgeCase'{}},
-        {5, undefined, {struct, {
-          name_conflict_test_types,
-          'Tricky_'
-        }}, 'Tricky_', #'Tricky_'{}},
-        {6, undefined, {struct, {
-          name_conflict_test_types,
-          'Nested'
-        }}, 'Nested', undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext('Nested')
-    )},
-    {"Problem_ extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, bool, problem, undefined},
-        {2, undefined, bool, 'Problem', undefined}
-      ]},
-      name_conflict_test_types:struct_info_ext('Problem_')
-    )}
-  ].
+    [
+        {"using definition",
+            ?_assertEqual(
+                {struct, [{1, double}, {2, double}]},
+                name_conflict_test_types:struct_info(using)
+            )},
+        {"delegate definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, string},
+                    {2, {struct, {name_conflict_test_types, delegate}}}
+                ]},
+                name_conflict_test_types:struct_info(delegate)
+            )},
+        {"get definition",
+            ?_assertEqual(
+                {struct, [{1, bool}]},
+                name_conflict_test_types:struct_info(get)
+            )},
+        {"partial definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, {struct, {name_conflict_test_types, using}}},
+                    {2, bool},
+                    {3, bool}
+                ]},
+                name_conflict_test_types:struct_info(partial)
+            )},
+        {"ClassAndProp definition",
+            ?_assertEqual(
+                {struct, [{1, bool}, {2, bool}, {3, bool}, {4, bool}]},
+                name_conflict_test_types:struct_info('ClassAndProp')
+            )},
+        {"second_chance definition",
+            ?_assertEqual(
+                {struct, [{1, bool}, {2, bool}, {3, bool}, {4, bool}]},
+                name_conflict_test_types:struct_info(second_chance)
+            )},
+        {"NOW_EAT_THIS definition",
+            ?_assertEqual(
+                {struct, [{1, bool}, {2, bool}, {3, bool}, {4, bool}]},
+                name_conflict_test_types:struct_info('NOW_EAT_THIS')
+            )},
+        {"TheEdgeCase definition",
+            ?_assertEqual(
+                {struct, [{1, bool}, {2, bool}, {3, bool}, {4, bool}, {5, bool}, {6, bool}]},
+                name_conflict_test_types:struct_info('TheEdgeCase')
+            )},
+        {"Tricky_ definition",
+            ?_assertEqual(
+                {struct, [{1, bool}, {2, bool}]},
+                name_conflict_test_types:struct_info('Tricky_')
+            )},
+        {"Nested definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, {struct, {name_conflict_test_types, 'ClassAndProp'}}},
+                    {2, {struct, {name_conflict_test_types, second_chance}}},
+                    {3, {struct, {name_conflict_test_types, 'NOW_EAT_THIS'}}},
+                    {4, {struct, {name_conflict_test_types, 'TheEdgeCase'}}},
+                    {5, {struct, {name_conflict_test_types, 'Tricky_'}}},
+                    {6, {struct, {name_conflict_test_types, 'Nested'}}}
+                ]},
+                name_conflict_test_types:struct_info('Nested')
+            )},
+        {"Problem_ definition",
+            ?_assertEqual(
+                {struct, [{1, bool}, {2, bool}]},
+                name_conflict_test_types:struct_info('Problem_')
+            )},
+        {"using extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, double, single, undefined},
+                    {2, undefined, double, integer, undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext(using)
+            )},
+        {"delegate extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, string, partial, undefined},
+                    {2, undefined, {struct, {name_conflict_test_types, delegate}}, delegate,
+                        undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext(delegate)
+            )},
+        {"get extended definition",
+            ?_assertEqual(
+                {struct, [{1, undefined, bool, sbyte, undefined}]},
+                name_conflict_test_types:struct_info_ext(get)
+            )},
+        {"partial extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {struct, {name_conflict_test_types, using}}, using, #using{}},
+                    {2, undefined, bool, read, undefined},
+                    {3, undefined, bool, write, undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext(partial)
+            )},
+        {"ClassAndProp extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, bool, 'ClassAndProp', undefined},
+                    {2, undefined, bool, 'ClassAndProp_', undefined},
+                    {3, undefined, bool, 'ClassAndProp__', undefined},
+                    {4, undefined, bool, 'ClassAndProper', undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext('ClassAndProp')
+            )},
+        {"second_chance extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, bool, 'SECOND_CHANCE', undefined},
+                    {2, undefined, bool, 'SECOND_CHANCE_', undefined},
+                    {3, undefined, bool, 'SECOND_CHANCE__', undefined},
+                    {4, undefined, bool, 'SECOND_CHANCES', undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext(second_chance)
+            )},
+        {"NOW_EAT_THIS extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, bool, now_eat_this, undefined},
+                    {2, undefined, bool, now_eat_this_, undefined},
+                    {3, undefined, bool, now_eat_this__, undefined},
+                    {4, undefined, bool, now_eat_this_and_this, undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext('NOW_EAT_THIS')
+            )},
+        {"TheEdgeCase extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, bool, theEdgeCase, undefined},
+                    {2, undefined, bool, theEdgeCase_, undefined},
+                    {3, undefined, bool, theEdgeCase__, undefined},
+                    {4, undefined, bool, 'TheEdgeCase', undefined},
+                    {5, undefined, bool, 'TheEdgeCase_', undefined},
+                    {6, undefined, bool, 'TheEdgeCase__', undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext('TheEdgeCase')
+            )},
+        {"Tricky_ extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, bool, tricky, undefined},
+                    {2, undefined, bool, 'Tricky', undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext('Tricky_')
+            )},
+        {"Nested extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined,
+                        {struct, {
+                            name_conflict_test_types,
+                            'ClassAndProp'
+                        }},
+                        'ClassAndProp', #'ClassAndProp'{}},
+                    {2, undefined,
+                        {struct, {
+                            name_conflict_test_types,
+                            second_chance
+                        }},
+                        second_chance, #second_chance{}},
+                    {3, undefined,
+                        {struct, {
+                            name_conflict_test_types,
+                            'NOW_EAT_THIS'
+                        }},
+                        'NOW_EAT_THIS', #'NOW_EAT_THIS'{}},
+                    {4, undefined,
+                        {struct, {
+                            name_conflict_test_types,
+                            'TheEdgeCase'
+                        }},
+                        'TheEdgeCase', #'TheEdgeCase'{}},
+                    {5, undefined,
+                        {struct, {
+                            name_conflict_test_types,
+                            'Tricky_'
+                        }},
+                        'Tricky_', #'Tricky_'{}},
+                    {6, undefined,
+                        {struct, {
+                            name_conflict_test_types,
+                            'Nested'
+                        }},
+                        'Nested', undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext('Nested')
+            )},
+        {"Problem_ extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, bool, problem, undefined},
+                    {2, undefined, bool, 'Problem', undefined}
+                ]},
+                name_conflict_test_types:struct_info_ext('Problem_')
+            )}
+    ].
 
 service_info_test_() ->
-  [
-    {"event params", ?_assertEqual(
-      {struct, [{1, {struct, {name_conflict_test_types, partial}}}]},
-      extern_thrift:function_info(event, params_type)
-    )},
-    {"event reply", ?_assertEqual(
-      {struct, {name_conflict_test_types, delegate}},
-      extern_thrift:function_info(event, reply_type)
-    )},
-    {"event exceptions", ?_assertEqual(
-      {struct, []},
-      extern_thrift:function_info(event, exceptions)
-    )},
-    {"Foo params", ?_assertEqual(
-      {struct, [{1, {struct, {name_conflict_test_types, 'Nested'}}}]},
-      extern_thrift:function_info('Foo', params_type)
-    )},
-    {"Foo reply", ?_assertEqual(
-      {struct, []},
-      extern_thrift:function_info('Foo', reply_type)
-    )},
-    {"Foo exceptions", ?_assertEqual(
-      {struct, [{1, {struct, {name_conflict_test_types, 'Problem_'}}}]},
-      extern_thrift:function_info('Foo', exceptions)
-    )}
-  ].
+    [
+        {"event params",
+            ?_assertEqual(
+                {struct, [{1, {struct, {name_conflict_test_types, partial}}}]},
+                extern_thrift:function_info(event, params_type)
+            )},
+        {"event reply",
+            ?_assertEqual(
+                {struct, {name_conflict_test_types, delegate}},
+                extern_thrift:function_info(event, reply_type)
+            )},
+        {"event exceptions",
+            ?_assertEqual(
+                {struct, []},
+                extern_thrift:function_info(event, exceptions)
+            )},
+        {"Foo params",
+            ?_assertEqual(
+                {struct, [{1, {struct, {name_conflict_test_types, 'Nested'}}}]},
+                extern_thrift:function_info('Foo', params_type)
+            )},
+        {"Foo reply",
+            ?_assertEqual(
+                {struct, []},
+                extern_thrift:function_info('Foo', reply_type)
+            )},
+        {"Foo exceptions",
+            ?_assertEqual(
+                {struct, [{1, {struct, {name_conflict_test_types, 'Problem_'}}}]},
+                extern_thrift:function_info('Foo', exceptions)
+            )}
+    ].
diff --git a/lib/erl/test/stress_server.erl b/lib/erl/test/stress_server.erl
index 35fff06..78ddefe 100644
--- a/lib/erl/test/stress_server.erl
+++ b/lib/erl/test/stress_server.erl
@@ -19,33 +19,32 @@
 
 -module(stress_server).
 
+-export([
+    start_link/1,
 
--export([start_link/1,
+    handle_function/2,
 
-         handle_function/2,
-
-         echoVoid/0,
-         echoByte/1,
-         echoI32/1,
-         echoI64/1,
-         echoString/1,
-         echoList/1,
-         echoSet/1,
-         echoMap/1
-        ]).
+    echoVoid/0,
+    echoByte/1,
+    echoI32/1,
+    echoI64/1,
+    echoString/1,
+    echoList/1,
+    echoSet/1,
+    echoMap/1
+]).
 
 start_link(Port) ->
     thrift_server:start_link(Port, service_thrift, ?MODULE).
 
-
 handle_function(Function, Args) ->
     case apply(?MODULE, Function, tuple_to_list(Args)) of
         ok ->
-             ok;
-        Else -> {reply, Else}
+            ok;
+        Else ->
+            {reply, Else}
     end.
 
-
 echoVoid() ->
     ok.
 echoByte(X) ->
diff --git a/lib/erl/test/test_const.erl b/lib/erl/test/test_const.erl
index 627777b..74830e9 100644
--- a/lib/erl/test/test_const.erl
+++ b/lib/erl/test/test_const.erl
@@ -25,30 +25,31 @@
 -include("gen-erl/constants_demo_types.hrl").
 
 namespace_test() ->
-  %% Verify that records produced by ConstantsDemo.thrift have the right namespace.
-  io:format(user, "in namespace_test()\n", []),
-  {struct, _} = constants_demo_types:struct_info('consts_thing'),
-  {struct, _} = constants_demo_types:struct_info('consts_Blah'),
-  ok.
+    %% Verify that records produced by ConstantsDemo.thrift have the right namespace.
+    io:format(user, "in namespace_test()\n", []),
+    {struct, _} = constants_demo_types:struct_info('consts_thing'),
+    {struct, _} = constants_demo_types:struct_info('consts_Blah'),
+    ok.
 
 const_map_test() ->
-  ?assertEqual(233, constants_demo_constants:gen_map(35532)),
-  ?assertError(function_clause, constants_demo_constants:gen_map(0)),
+    ?assertEqual(233, constants_demo_constants:gen_map(35532)),
+    ?assertError(function_clause, constants_demo_constants:gen_map(0)),
 
-  ?assertEqual(853, constants_demo_constants:gen_map(43523, default)),
-  ?assertEqual(default, constants_demo_constants:gen_map(10110, default)),
+    ?assertEqual(853, constants_demo_constants:gen_map(43523, default)),
+    ?assertEqual(default, constants_demo_constants:gen_map(10110, default)),
 
-  ?assertEqual(98325, constants_demo_constants:gen_map2("lkjsdf")),
-  ?assertError(function_clause, constants_demo_constants:gen_map2("nonexist")),
+    ?assertEqual(98325, constants_demo_constants:gen_map2("lkjsdf")),
+    ?assertError(function_clause, constants_demo_constants:gen_map2("nonexist")),
 
-  ?assertEqual(233, constants_demo_constants:gen_map2("hello", 321)),
-  ?assertEqual(321, constants_demo_constants:gen_map2("goodbye", 321)).
+    ?assertEqual(233, constants_demo_constants:gen_map2("hello", 321)),
+    ?assertEqual(321, constants_demo_constants:gen_map2("goodbye", 321)).
 
 const_list_test() ->
-  ?assertEqual(23598352, constants_demo_constants:gen_list(2)),
-  ?assertError(function_clause, constants_demo_constants:gen_list(0)),
+    ?assertEqual(23598352, constants_demo_constants:gen_list(2)),
+    ?assertError(function_clause, constants_demo_constants:gen_list(0)),
 
-  ?assertEqual(3253523, constants_demo_constants:gen_list(3, default)),
-  ?assertEqual(default, constants_demo_constants:gen_list(10, default)).
+    ?assertEqual(3253523, constants_demo_constants:gen_list(3, default)),
+    ?assertEqual(default, constants_demo_constants:gen_list(10, default)).
 
--endif. %% TEST
+%% TEST
+-endif.
diff --git a/lib/erl/test/test_disklog.erl b/lib/erl/test/test_disklog.erl
index dcb6fc1..742e895 100644
--- a/lib/erl/test/test_disklog.erl
+++ b/lib/erl/test/test_disklog.erl
@@ -23,77 +23,83 @@
 -include_lib("eunit/include/eunit.hrl").
 
 disklog_test() ->
-  {ok, TransportFactory} =
-    thrift_disk_log_transport:new_transport_factory(
-      test_disklog,
-      [{file, "./test_log"},
-       {size, {1024*1024, 10}}]),
-  {ok, ProtocolFactory} =
-    thrift_binary_protocol:new_protocol_factory( TransportFactory, []),
-  {ok, Proto} = ProtocolFactory(),
-  {ok, Client0} = thrift_client:new(Proto, thrift_test_thrift),
+    {ok, TransportFactory} =
+        thrift_disk_log_transport:new_transport_factory(
+            test_disklog,
+            [
+                {file, "./test_log"},
+                {size, {1024 * 1024, 10}}
+            ]
+        ),
+    {ok, ProtocolFactory} =
+        thrift_binary_protocol:new_protocol_factory(TransportFactory, []),
+    {ok, Proto} = ProtocolFactory(),
+    {ok, Client0} = thrift_client:new(Proto, thrift_test_thrift),
 
-  io:format("Client started~n"),
+    io:format("Client started~n"),
 
-  % We have to make oneway calls into this client only since otherwise it
-  % will try to read from the disklog and go boom.
-  {Client1, {ok, ok}} = thrift_client:call(Client0, testOneway, [16#deadbeef]),
-  io:format("Call written~n"),
+    % We have to make oneway calls into this client only since otherwise it
+    % will try to read from the disklog and go boom.
+    {Client1, {ok, ok}} = thrift_client:call(Client0, testOneway, [16#deadbeef]),
+    io:format("Call written~n"),
 
-  % Use the send_call method to write a non-oneway call into the log
-  {Client2, ok} =
-    thrift_client:send_call(Client1, testString, [<<"hello world">>]),
-  io:format("Non-oneway call sent~n"),
+    % Use the send_call method to write a non-oneway call into the log
+    {Client2, ok} =
+        thrift_client:send_call(Client1, testString, [<<"hello world">>]),
+    io:format("Non-oneway call sent~n"),
 
-  {_Client3, ok} = thrift_client:close(Client2),
-  io:format("Client closed~n"),
-  
-  lists:foreach(fun(File) -> file:delete(File) end, [
-    "./test_log.1",
-    "./test_log.idx",
-    "./test_log.siz"
-  ]),
-  io:format("Cleaning up test files~n"),
+    {_Client3, ok} = thrift_client:close(Client2),
+    io:format("Client closed~n"),
 
-  ok.
+    lists:foreach(fun(File) -> file:delete(File) end, [
+        "./test_log.1",
+        "./test_log.idx",
+        "./test_log.siz"
+    ]),
+    io:format("Cleaning up test files~n"),
+
+    ok.
 
 disklog_base64_test() ->
-  {ok, TransportFactory} =
-    thrift_disk_log_transport:new_transport_factory(
-      test_disklog,
-      [{file, "./test_b64_log"},
-       {size, {1024*1024, 10}}]),
-  {ok, B64Factory} =
-    thrift_base64_transport:new_transport_factory(TransportFactory),
-  {ok, BufFactory} =
-    thrift_buffered_transport:new_transport_factory(B64Factory),
-  {ok, ProtocolFactory} =
-    thrift_binary_protocol:new_protocol_factory(BufFactory, []),
-  {ok, Proto} = ProtocolFactory(),
-  {ok, Client0} = thrift_client:new(Proto, thrift_test_thrift),
+    {ok, TransportFactory} =
+        thrift_disk_log_transport:new_transport_factory(
+            test_disklog,
+            [
+                {file, "./test_b64_log"},
+                {size, {1024 * 1024, 10}}
+            ]
+        ),
+    {ok, B64Factory} =
+        thrift_base64_transport:new_transport_factory(TransportFactory),
+    {ok, BufFactory} =
+        thrift_buffered_transport:new_transport_factory(B64Factory),
+    {ok, ProtocolFactory} =
+        thrift_binary_protocol:new_protocol_factory(BufFactory, []),
+    {ok, Proto} = ProtocolFactory(),
+    {ok, Client0} = thrift_client:new(Proto, thrift_test_thrift),
 
-  io:format("Client started~n"),
+    io:format("Client started~n"),
 
-  % We have to make oneway calls into this client only since otherwise
-  % it will try to read from the disklog and go boom.
-  {Client1, {ok, ok}} = thrift_client:call(Client0, testOneway, [16#deadbeef]),
-  io:format("Call written~n"),
+    % We have to make oneway calls into this client only since otherwise
+    % it will try to read from the disklog and go boom.
+    {Client1, {ok, ok}} = thrift_client:call(Client0, testOneway, [16#deadbeef]),
+    io:format("Call written~n"),
 
-  % Use the send_call method to write a non-oneway call into the log
-  {Client2, ok} =
-    thrift_client:send_call(Client1, testString, [<<"hello world">>]),
-  io:format("Non-oneway call sent~n"),
+    % Use the send_call method to write a non-oneway call into the log
+    {Client2, ok} =
+        thrift_client:send_call(Client1, testString, [<<"hello world">>]),
+    io:format("Non-oneway call sent~n"),
 
-  {_Client3, ok} = thrift_client:close(Client2),
-  io:format("Client closed~n"),
+    {_Client3, ok} = thrift_client:close(Client2),
+    io:format("Client closed~n"),
 
-  lists:foreach(fun(File) -> file:delete(File) end, [
-    "./test_b64_log.1",
-    "./test_b64_log.idx",
-    "./test_b64_log.siz"
-  ]),
-  io:format("Cleaning up test files~n"),
+    lists:foreach(fun(File) -> file:delete(File) end, [
+        "./test_b64_log.1",
+        "./test_b64_log.idx",
+        "./test_b64_log.siz"
+    ]),
+    io:format("Cleaning up test files~n"),
 
-  ok.
+    ok.
 
 -endif.
diff --git a/lib/erl/test/test_omit.erl b/lib/erl/test/test_omit.erl
index 80841e2..a51f1ed 100644
--- a/lib/erl/test/test_omit.erl
+++ b/lib/erl/test/test_omit.erl
@@ -1,3 +1,22 @@
+%%
+%% 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.
+%%
+
 -module(test_omit).
 
 -include("gen-erl/thrift_omit_with_types.hrl").
@@ -6,74 +25,83 @@
 -include_lib("eunit/include/eunit.hrl").
 
 omit_struct1_test() ->
-  %% In this test, the field that is deleted is a basic type (an i32).
-  A = #test1{one = 1, three = 3},
-  B = #test1{one = 1, two = 2, three = 3},
-  {ok, Transport} = thrift_membuffer_transport:new(),
-  {ok, P0} = thrift_binary_protocol:new(Transport),
+    %% In this test, the field that is deleted is a basic type (an i32).
+    A = #test1{one = 1, three = 3},
+    B = #test1{one = 1, two = 2, three = 3},
+    {ok, Transport} = thrift_membuffer_transport:new(),
+    {ok, P0} = thrift_binary_protocol:new(Transport),
 
-  {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, A)}}, A}),
-  {P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, A)}}),
-  ?assertEqual(element(1, A), element(1, O0)),
-  ?assertEqual(element(2, A), element(2, O0)),
-  ?assertEqual(element(4, A), element(3, O0)),
+    {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, A)}}, A}),
+    {P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, A)}}),
+    ?assertEqual(element(1, A), element(1, O0)),
+    ?assertEqual(element(2, A), element(2, O0)),
+    ?assertEqual(element(4, A), element(3, O0)),
 
-  {P3, ok} = thrift_protocol:write(P2, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
-  {_P4, {ok, O1}} = thrift_protocol:read(P3, {struct, {thrift_omit_without_types, element(1, A)}}),
-  ?assertEqual(element(1, A), element(1, O1)),
-  ?assertEqual(element(2, A), element(2, O1)),
-  ?assertEqual(element(4, A), element(3, O1)),
+    {P3, ok} = thrift_protocol:write(P2, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
+    {_P4, {ok, O1}} = thrift_protocol:read(
+        P3, {struct, {thrift_omit_without_types, element(1, A)}}
+    ),
+    ?assertEqual(element(1, A), element(1, O1)),
+    ?assertEqual(element(2, A), element(2, O1)),
+    ?assertEqual(element(4, A), element(3, O1)),
 
-  ok.
+    ok.
 
 omit_struct2_test() ->
-  %% In this test, the field that is deleted is a struct.
-  A = #test2{one = 1, two = #test2{one = 10, three = 30}, three = 3},
-  B = #test2{one = 1, two = #test2{one = 10, two = #test2{one = 100}, three = 30}, three = 3},
+    %% In this test, the field that is deleted is a struct.
+    A = #test2{one = 1, two = #test2{one = 10, three = 30}, three = 3},
+    B = #test2{one = 1, two = #test2{one = 10, two = #test2{one = 100}, three = 30}, three = 3},
 
-  {ok, Transport} = thrift_membuffer_transport:new(),
-  {ok, P0} = thrift_binary_protocol:new(Transport),
+    {ok, Transport} = thrift_membuffer_transport:new(),
+    {ok, P0} = thrift_binary_protocol:new(Transport),
 
-  {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, A)}}, A}),
-  {P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, A)}}),
-  ?assertEqual(element(1, A), element(1, O0)),
-  ?assertEqual(element(2, A), element(2, O0)),
-  ?assertEqual(element(4, A), element(3, O0)),
+    {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, A)}}, A}),
+    {P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, A)}}),
+    ?assertEqual(element(1, A), element(1, O0)),
+    ?assertEqual(element(2, A), element(2, O0)),
+    ?assertEqual(element(4, A), element(3, O0)),
 
-  {P3, ok} = thrift_protocol:write(P2, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
-  {_P4, {ok, O1}} = thrift_protocol:read(P3, {struct, {thrift_omit_without_types, element(1, A)}}),
-  ?assertEqual(element(1, A), element(1, O1)),
-  ?assertEqual(element(2, A), element(2, O1)),
-  ?assertEqual(element(4, A), element(3, O1)),
+    {P3, ok} = thrift_protocol:write(P2, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
+    {_P4, {ok, O1}} = thrift_protocol:read(
+        P3, {struct, {thrift_omit_without_types, element(1, A)}}
+    ),
+    ?assertEqual(element(1, A), element(1, O1)),
+    ?assertEqual(element(2, A), element(2, O1)),
+    ?assertEqual(element(4, A), element(3, O1)),
 
-  ok.
+    ok.
 
 omit_list_test() ->
-  %% In this test, the field that is deleted is a list.
-  A = #test1{one = 1, two = 2, three = 3},
-  B = #test3{one = 1, two = [ A ]},
+    %% In this test, the field that is deleted is a list.
+    A = #test1{one = 1, two = 2, three = 3},
+    B = #test3{one = 1, two = [A]},
 
-  {ok, Transport} = thrift_membuffer_transport:new(),
-  {ok, P0} = thrift_binary_protocol:new(Transport),
+    {ok, Transport} = thrift_membuffer_transport:new(),
+    {ok, P0} = thrift_binary_protocol:new(Transport),
 
-  {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
-  {_P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, B)}}),
-  ?assertEqual(element(2, B), element(2, O0)),
+    {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
+    {_P2, {ok, O0}} = thrift_protocol:read(
+        P1, {struct, {thrift_omit_without_types, element(1, B)}}
+    ),
+    ?assertEqual(element(2, B), element(2, O0)),
 
-  ok.
+    ok.
 
 omit_map_test() ->
-  %% In this test, the field that is deleted is a map.
-  A = #test1{one = 1, two = 2, three = 3},
-  B = #test4{one = 1, two = dict:from_list([ {2, A} ])},
+    %% In this test, the field that is deleted is a map.
+    A = #test1{one = 1, two = 2, three = 3},
+    B = #test4{one = 1, two = dict:from_list([{2, A}])},
 
-  {ok, Transport} = thrift_membuffer_transport:new(),
-  {ok, P0} = thrift_binary_protocol:new(Transport),
+    {ok, Transport} = thrift_membuffer_transport:new(),
+    {ok, P0} = thrift_binary_protocol:new(Transport),
 
-  {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
-  {_P2, {ok, O0}} = thrift_protocol:read(P1, {struct, {thrift_omit_without_types, element(1, B)}}),
-  ?assertEqual(element(2, B), element(2, O0)),
+    {P1, ok} = thrift_protocol:write(P0, {{struct, {thrift_omit_with_types, element(1, B)}}, B}),
+    {_P2, {ok, O0}} = thrift_protocol:read(
+        P1, {struct, {thrift_omit_without_types, element(1, B)}}
+    ),
+    ?assertEqual(element(2, B), element(2, O0)),
 
-  ok.
+    ok.
 
--endif. %% TEST
+%% TEST
+-endif.
diff --git a/lib/erl/test/test_rendered_double_constants.erl b/lib/erl/test/test_rendered_double_constants.erl
index 87fce81..02950f2 100644
--- a/lib/erl/test/test_rendered_double_constants.erl
+++ b/lib/erl/test/test_rendered_double_constants.erl
@@ -27,42 +27,96 @@
 -define(EPSILON, 0.0000001).
 
 rendered_double_constants_test() ->
-  ?assert(abs(1.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST) =< ?EPSILON),
-  ?assert(abs(-100.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST) =< ?EPSILON),
-  ?assert(abs(9223372036854775807.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST) =< ?EPSILON),
-  ?assert(abs(-9223372036854775807.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST) =< ?EPSILON),
-  ?assert(abs(3.14159265359 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST) =< ?EPSILON),
-  ?assert(abs(1000000.1 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON),
-  ?assert(abs(-1000000.1 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON),
-  ?assert(abs(1.7e+308 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST) =< ?EPSILON),
-  ?assert(abs(9223372036854775816.43 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON),
-  ?assert(abs(-1.7e+308 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST) =< ?EPSILON),
-  ?assert(abs(-9223372036854775816.43 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST) =< ?EPSILON),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST)),
-  ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST)).
+    ?assert(abs(1.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST) =< ?EPSILON),
+    ?assert(
+        abs(-100.0 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST) =<
+            ?EPSILON
+    ),
+    ?assert(
+        abs(
+            9223372036854775807.0 -
+                ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST
+        ) =< ?EPSILON
+    ),
+    ?assert(
+        abs(
+            -9223372036854775807.0 -
+                ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST
+        ) =< ?EPSILON
+    ),
+    ?assert(
+        abs(
+            3.14159265359 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST
+        ) =< ?EPSILON
+    ),
+    ?assert(
+        abs(1000000.1 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST) =<
+            ?EPSILON
+    ),
+    ?assert(
+        abs(-1000000.1 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST) =<
+            ?EPSILON
+    ),
+    ?assert(
+        abs(1.7e+308 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST) =< ?EPSILON
+    ),
+    ?assert(
+        abs(
+            9223372036854775816.43 -
+                ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST
+        ) =< ?EPSILON
+    ),
+    ?assert(
+        abs(-1.7e+308 - ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST) =< ?EPSILON
+    ),
+    ?assert(
+        abs(
+            -9223372036854775816.43 -
+                ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST
+        ) =< ?EPSILON
+    ),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_INT_CONSTANT_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_INT_CONSTANT_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGEST_INT_CONSTANT_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALLEST_INT_CONSTANT_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_DOUBLE_WITH_MANY_DECIMALS_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_FRACTIONAL_DOUBLE_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_FRACTIONAL_DOUBLE_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_DOUBLE_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_LARGE_FRACTIONAL_DOUBLE_TEST)),
+    ?assert(is_float(?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_SMALL_DOUBLE_TEST)),
+    ?assert(
+        is_float(
+            ?DOUBLE_CONSTANTS_TEST_DOUBLE_ASSIGNED_TO_NEGATIVE_BUT_LARGE_FRACTIONAL_DOUBLE_TEST
+        )
+    ).
 
 rendered_double_list_test() ->
-  ?assertEqual(12, length(?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)),
-  ?assert(abs(1.0 - lists:nth(1, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(-100.0 - lists:nth(2, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(100.0 - lists:nth(3, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(9223372036854775807.0 - lists:nth(4, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(-9223372036854775807.0 - lists:nth(5, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(3.14159265359 - lists:nth(6, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(1000000.1 - lists:nth(7, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(-1000000.1 - lists:nth(8, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(1.7e+308 - lists:nth(9, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(-1.7e+308 - lists:nth(10, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(9223372036854775816.43 - lists:nth(11, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
-  ?assert(abs(-9223372036854775816.43 - lists:nth(12, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON).
+    ?assertEqual(12, length(?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)),
+    ?assert(abs(1.0 - lists:nth(1, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+    ?assert(abs(-100.0 - lists:nth(2, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+    ?assert(abs(100.0 - lists:nth(3, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+    ?assert(
+        abs(9223372036854775807.0 - lists:nth(4, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =<
+            ?EPSILON
+    ),
+    ?assert(
+        abs(-9223372036854775807.0 - lists:nth(5, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =<
+            ?EPSILON
+    ),
+    ?assert(abs(3.14159265359 - lists:nth(6, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+    ?assert(abs(1000000.1 - lists:nth(7, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+    ?assert(abs(-1000000.1 - lists:nth(8, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+    ?assert(abs(1.7e+308 - lists:nth(9, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+    ?assert(abs(-1.7e+308 - lists:nth(10, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =< ?EPSILON),
+    ?assert(
+        abs(9223372036854775816.43 - lists:nth(11, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =<
+            ?EPSILON
+    ),
+    ?assert(
+        abs(-9223372036854775816.43 - lists:nth(12, ?DOUBLE_CONSTANTS_TEST_DOUBLE_LIST_TEST)) =<
+            ?EPSILON
+    ).
 
--endif. %% TEST
\ No newline at end of file
+%% TEST
+-endif.
diff --git a/lib/erl/test/test_thrift_1151.erl b/lib/erl/test/test_thrift_1151.erl
index f4a910e..141787e 100644
--- a/lib/erl/test/test_thrift_1151.erl
+++ b/lib/erl/test/test_thrift_1151.erl
@@ -1,3 +1,22 @@
+%%
+%% 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.
+%%
+
 -module(test_thrift_1151).
 
 -include("gen-erl/thrift1151_types.hrl").
@@ -6,29 +25,29 @@
 -include_lib("eunit/include/eunit.hrl").
 
 unmatched_struct_test() ->
-  S1 = #'StructC'{x=#'StructB'{x=1}},
-  {ok, Transport} = thrift_memory_buffer:new(),
-  {ok, Protocol} = thrift_binary_protocol:new(Transport),
-  ?assertException(
-    error,
-    struct_unmatched,
-    thrift_protocol:write(
-      Protocol,
-      {{struct, element(2, thrift1151_types:struct_info('StructC'))}, S1}
-    )
-  ).
+    S1 = #'StructC'{x = #'StructB'{x = 1}},
+    {ok, Transport} = thrift_memory_buffer:new(),
+    {ok, Protocol} = thrift_binary_protocol:new(Transport),
+    ?assertException(
+        error,
+        struct_unmatched,
+        thrift_protocol:write(
+            Protocol,
+            {{struct, element(2, thrift1151_types:struct_info('StructC'))}, S1}
+        )
+    ).
 
 badarg_test() ->
-  S2 = #'StructC'{x=#'StructA'{x="1"}},
-  {ok, Transport} = thrift_memory_buffer:new(),
-  {ok, Protocol} = thrift_binary_protocol:new(Transport),
-  ?assertException(
-    error,
-    badarg,
-    thrift_protocol:write(
-      Protocol,
-      {{struct, element(2, thrift1151_types:struct_info('StructC'))}, S2}
-    )
-  ).
+    S2 = #'StructC'{x = #'StructA'{x = "1"}},
+    {ok, Transport} = thrift_memory_buffer:new(),
+    {ok, Protocol} = thrift_binary_protocol:new(Transport),
+    ?assertException(
+        error,
+        badarg,
+        thrift_protocol:write(
+            Protocol,
+            {{struct, element(2, thrift1151_types:struct_info('StructC'))}, S2}
+        )
+    ).
 
 -endif.
diff --git a/lib/erl/test/test_thrift_3214.erl b/lib/erl/test/test_thrift_3214.erl
index 118e779..4d7dd3e 100644
--- a/lib/erl/test/test_thrift_3214.erl
+++ b/lib/erl/test/test_thrift_3214.erl
@@ -18,7 +18,6 @@
 %%
 
 -module(test_thrift_3214).
--compile(export_all).
 
 -include("gen-erl/thrift3214_types.hrl").
 
@@ -26,33 +25,38 @@
 -include_lib("eunit/include/eunit.hrl").
 
 record_generation_test_() ->
-  [
-    {"StringMap record", ?_assertMatch(
-      {'StringMap', _},
-      #'StringMap'{data=#{50 => "foo"}}
-    )},
-    {"StringMap record defaults", ?_assertEqual(
-      {'StringMap', #{1 => "a", 2 => "b"}},
-      #'StringMap'{}
-    )},
-    {"StringMap record dict from list", ?_assertNotEqual(
-      {'StringMap', dict:from_list([{1, "a"}, {2, "b"}])},
-      #'StringMap'{}
-    )},
-    {"StringMap record map from list", ?_assertEqual(
-      {'StringMap', maps:from_list([{1, "a"}, {2, "b"}])},
-      #'StringMap'{}
-    )}
-  ].
+    [
+        {"StringMap record",
+            ?_assertMatch(
+                {'StringMap', _},
+                #'StringMap'{data = #{50 => "foo"}}
+            )},
+        {"StringMap record defaults",
+            ?_assertEqual(
+                {'StringMap', #{1 => "a", 2 => "b"}},
+                #'StringMap'{}
+            )},
+        {"StringMap record dict from list",
+            ?_assertNotEqual(
+                {'StringMap', dict:from_list([{1, "a"}, {2, "b"}])},
+                #'StringMap'{}
+            )},
+        {"StringMap record map from list",
+            ?_assertEqual(
+                {'StringMap', maps:from_list([{1, "a"}, {2, "b"}])},
+                #'StringMap'{}
+            )}
+    ].
 
 struct_info_test_() ->
-  [
-    {"StringMap extended definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {map, i32, string}, 'data', #{1 => "a", 2 => "b"}}
-      ]},
-      thrift3214_types:struct_info_ext('StringMap')
-    )}
-  ].
+    [
+        {"StringMap extended definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {map, i32, string}, 'data', #{1 => "a", 2 => "b"}}
+                ]},
+                thrift3214_types:struct_info_ext('StringMap')
+            )}
+    ].
 
 -endif.
diff --git a/lib/erl/test/test_thrift_buffered_transport.erl b/lib/erl/test/test_thrift_buffered_transport.erl
index 8519e82..e7b23ab 100644
--- a/lib/erl/test/test_thrift_buffered_transport.erl
+++ b/lib/erl/test/test_thrift_buffered_transport.erl
@@ -20,340 +20,295 @@
 -module(test_thrift_buffered_transport).
 -include_lib("eunit/include/eunit.hrl").
 
-
 new(Transport) -> thrift_buffered_transport:new(Transport).
 
 new_test_() ->
-  [
-    {"new buffered membuffer", ?_assertMatch(
-      {ok, {t_transport, thrift_buffered_transport, {t_buffered,
-        {t_transport, thrift_membuffer_transport, {t_membuffer, []}},
-        []
-      }}},
-      new({t_transport, thrift_membuffer_transport, {t_membuffer, []}})
-    )}
-  ].
-
+    [
+        {"new buffered membuffer",
+            ?_assertMatch(
+                {ok,
+                    {t_transport, thrift_buffered_transport,
+                        {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, []}},
+                            []}}},
+                new({t_transport, thrift_membuffer_transport, {t_membuffer, []}})
+            )}
+    ].
 
 read(Frame, Bytes) -> thrift_buffered_transport:read(Frame, Bytes).
 
 read_test_() ->
-  [
-    {"read zero bytes from an empty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        {ok, <<>>}
-      },
-      read(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        0
-      )
-    )},
-    {"read 1 byte from an empty buffered membuffer", ?_assertMatch(
-      {_, {ok, <<>>}},
-      read(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        1
-      )
-    )},
-    {"read zero bytes from nonempty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<"hallo world">>
-          }},
-          []
-        },
-        {ok, <<>>}
-      },
-      read(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<"hallo world">>
-          }},
-          []
-        },
-        0
-      )
-    )},
-    {"read 1 byte from nonempty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}},
-          []
-        },
-        {ok, <<"h">>}
-      },
-      read(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
-          []
-        },
-        1
-      )
-    )},
-    {"read 1 byte from nonempty buffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}},
-          []
-        },
-        {ok, <<"h">>}
-      },
-      read(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
-          []
-        },
-        1
-      )
-    )},
-    {"read a zillion bytes from nonempty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        {ok, <<"hallo world">>}
-      },
-      read(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
-          []
-        },
-        65536
-      )
-    )}
-  ].
-
+    [
+        {"read zero bytes from an empty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    {ok, <<>>}
+                },
+                read(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    0
+                )
+            )},
+        {"read 1 byte from an empty buffered membuffer",
+            ?_assertMatch(
+                {_, {ok, <<>>}},
+                read(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    1
+                )
+            )},
+        {"read zero bytes from nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    {ok, <<>>}
+                },
+                read(
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    0
+                )
+            )},
+        {"read 1 byte from nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}},
+                        []},
+                    {ok, <<"h">>}
+                },
+                read(
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    1
+                )
+            )},
+        {"read 1 byte from nonempty buffer",
+            ?_assertMatch(
+                {
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}},
+                        []},
+                    {ok, <<"h">>}
+                },
+                read(
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    1
+                )
+            )},
+        {"read a zillion bytes from nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    {ok, <<"hallo world">>}
+                },
+                read(
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    65536
+                )
+            )}
+    ].
 
 read_exact(Frame, Bytes) -> thrift_buffered_transport:read_exact(Frame, Bytes).
 
 read_exact_test_() ->
-  [
-    {"read exactly zero bytes from an empty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        {ok, <<>>}
-      },
-      read_exact(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        0
-      )
-    )},
-    {"read exactly 1 byte from an empty buffered membuffer", ?_assertMatch(
-      {_, {error, eof}},
-      read_exact(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        1
-      )
-    )},
-    {"read exactly zero bytes from nonempty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
-          []
-        },
-        {ok, <<>>}
-      },
-      read_exact(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
-          []
-        },
-        0
-      )
-    )},
-    {"read exactly 1 byte from nonempty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}},
-          []
-        },
-        {ok, <<"h">>}
-      },
-      read_exact(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<"hallo world">>
-          }},
-          []
-        },
-        1
-      )
-    )},
-    {"read exactly 1 byte from nonempty buffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}},
-          []
-        },
-        {ok, <<"h">>}
-      },
-      read_exact(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
-          []
-        },
-        1
-      )
-    )},
-    {"read exactly a zillion bytes from nonempty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
-          []
-        },
-        {error, eof}
-      },
-      read_exact(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<"hallo world">>
-          }},
-          []
-        },
-        65536
-      )
-    )}
-  ].
-
+    [
+        {"read exactly zero bytes from an empty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    {ok, <<>>}
+                },
+                read_exact(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    0
+                )
+            )},
+        {"read exactly 1 byte from an empty buffered membuffer",
+            ?_assertMatch(
+                {_, {error, eof}},
+                read_exact(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    1
+                )
+            )},
+        {"read exactly zero bytes from nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    {ok, <<>>}
+                },
+                read_exact(
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    0
+                )
+            )},
+        {"read exactly 1 byte from nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}},
+                        []},
+                    {ok, <<"h">>}
+                },
+                read_exact(
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    1
+                )
+            )},
+        {"read exactly 1 byte from nonempty buffer",
+            ?_assertMatch(
+                {
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"allo world">>}},
+                        []},
+                    {ok, <<"h">>}
+                },
+                read_exact(
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    1
+                )
+            )},
+        {"read exactly a zillion bytes from nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    {error, eof}
+                },
+                read_exact(
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport, {t_membuffer, <<"hallo world">>}},
+                        []},
+                    65536
+                )
+            )}
+    ].
 
 write(Framed, Data) -> thrift_buffered_transport:write(Framed, Data).
 
 write_test_() ->
-  [
-    {"write empty list to empty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [[], []]
-        },
-        ok
-      },
-      write(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        []
-      )
-    )},
-    {"write empty list to nonempty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [["hallo world"], []]
-        },
-        ok
-      },
-      write(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          ["hallo world"]
-        },
-        []
-      )
-    )},
-    {"write empty binary to empty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [[], <<>>]
-        },
-        ok
-      },
-      write(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        <<>>
-      )
-    )},
-    {"write empty binary to nonempty buffered membuffer", ?_assertMatch(
-      {
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [["hallo world"], <<>>]
-        },
-        ok
-      },
-      write(
-        {t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          ["hallo world"]
-        },
-        <<>>
-      )
-    )}
-  ].
-
+    [
+        {"write empty list to empty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [
+                        [], []
+                    ]},
+                    ok
+                },
+                write(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    []
+                )
+            )},
+        {"write empty list to nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [
+                        ["hallo world"], []
+                    ]},
+                    ok
+                },
+                write(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [
+                        "hallo world"
+                    ]},
+                    []
+                )
+            )},
+        {"write empty binary to empty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [
+                        [], <<>>
+                    ]},
+                    ok
+                },
+                write(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    <<>>
+                )
+            )},
+        {"write empty binary to nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [
+                        ["hallo world"], <<>>
+                    ]},
+                    ok
+                },
+                write(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [
+                        "hallo world"
+                    ]},
+                    <<>>
+                )
+            )}
+    ].
 
 flush(Transport) -> thrift_buffered_transport:flush(Transport).
 
 flush_test_() ->
-  [
-    {"flush empty buffered membuffer", ?_assertMatch(
-      {{t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          []
-        },
-        ok
-      },
-      flush({t_buffered,
-        {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-        []
-      })
-    )},
-    {"flush nonempty buffered membuffer", ?_assertMatch(
-      {{t_buffered,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            [<<>>, <<"hallo world">>]
-          }},
-          []
-        },
-        ok
-      },
-      flush({t_buffered,
-        {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-        <<"hallo world">>
-      })
-    )}
-  ].
-
+    [
+        {"flush empty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        []},
+                    ok
+                },
+                flush(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}
+                )
+            )},
+        {"flush nonempty buffered membuffer",
+            ?_assertMatch(
+                {
+                    {t_buffered,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, [<<>>, <<"hallo world">>]}},
+                        []},
+                    ok
+                },
+                flush(
+                    {t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        <<"hallo world">>}
+                )
+            )}
+    ].
 
 close(Transport) -> thrift_buffered_transport:close(Transport).
 
 close_test_() ->
-  {"close buffered membuffer", ?_assertMatch(
-    {{t_buffered,
-        {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-        []
-      },
-      ok
-    },
-    close({t_buffered,
-      {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-      []
-    })
-  )}.
-
+    {"close buffered membuffer",
+        ?_assertMatch(
+            {{t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []}, ok},
+            close({t_buffered, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, []})
+        )}.
diff --git a/lib/erl/test/test_thrift_compact_protocol.erl b/lib/erl/test/test_thrift_compact_protocol.erl
index 5da78c6..b9efae7 100644
--- a/lib/erl/test/test_thrift_compact_protocol.erl
+++ b/lib/erl/test/test_thrift_compact_protocol.erl
@@ -22,198 +22,203 @@
 -include("thrift_constants.hrl").
 -include("thrift_protocol.hrl").
 
-
 new(Transport) -> thrift_compact_protocol:new(Transport).
 new() ->
-  {ok, Transport} = thrift_membuffer_transport:new(),
-  thrift_compact_protocol:new(Transport).
+    {ok, Transport} = thrift_membuffer_transport:new(),
+    thrift_compact_protocol:new(Transport).
 
 new_test() ->
-  new(thrift_membuffer_transport:new()).
+    new(thrift_membuffer_transport:new()).
 
 write(This, Value) -> thrift_protocol:write(This, Value).
 read(This, Type) -> thrift_protocol:read(This, Type).
 
 str(This0, Value0) ->
-  {This1, ok} = write(This0, {string, Value0}),
-  {This2, {ok, Value1}} = read(This1, string),
-  ?assertEqual(Value0, binary_to_list(Value1)),
-  {This2, ok}.
+    {This1, ok} = write(This0, {string, Value0}),
+    {This2, {ok, Value1}} = read(This1, string),
+    ?assertEqual(Value0, binary_to_list(Value1)),
+    {This2, ok}.
 string_test() ->
-  {ok, This0} = new(),
-  {This1, ok} = str(This0, "aaa"),
-  {This2, ok} = str(This1, ""),
-  {This2, ok}.
+    {ok, This0} = new(),
+    {This1, ok} = str(This0, "aaa"),
+    {This2, ok} = str(This1, ""),
+    {This2, ok}.
 
 round_trip(This0, Type, Value0) ->
-  {This1, ok} = write(This0, {Type, Value0}),
-  {This2, {ok, Value1}} = read(This1, Type),
-  ?assertEqual(Value0, Value1),
-  {This2, ok}.
+    {This1, ok} = write(This0, {Type, Value0}),
+    {This2, {ok, Value1}} = read(This1, Type),
+    ?assertEqual(Value0, Value1),
+    {This2, ok}.
 
 bool_test() ->
-  {ok, This0} = new(),
-  {This1, ok} = round_trip(This0, bool, true),
-  {This2, ok} = round_trip(This1, bool, false),
-  {This2, ok}.
+    {ok, This0} = new(),
+    {This1, ok} = round_trip(This0, bool, true),
+    {This2, ok} = round_trip(This1, bool, false),
+    {This2, ok}.
 
 byte(This0, Value0) -> round_trip(This0, byte, Value0).
 byte_test() ->
-  {ok, This0} = new(),
-  {This1, ok} = byte(This0, 0),
-  {This2, ok} = byte(This1, 42),
-  {This3, ok} = byte(This2, -1),
-  {This4, ok} = byte(This3, -128),
-  {This4, ok}.
+    {ok, This0} = new(),
+    {This1, ok} = byte(This0, 0),
+    {This2, ok} = byte(This1, 42),
+    {This3, ok} = byte(This2, -1),
+    {This4, ok} = byte(This3, -128),
+    {This4, ok}.
 
 i16(This0, Value0) -> round_trip(This0, i16, Value0).
 i16_test() ->
-  {ok, This0} = new(),
-  {This1, ok} = i16(This0, 0),
-  {This2, ok} = i16(This1, 42),
-  {This3, ok} = i16(This2, 30000),
-  {This4, ok} = i16(This3, -1),
-  {This5, ok} = i16(This4, -128),
-  {This6, ok} = i16(This5, -30000),
-  {This6, ok}.
+    {ok, This0} = new(),
+    {This1, ok} = i16(This0, 0),
+    {This2, ok} = i16(This1, 42),
+    {This3, ok} = i16(This2, 30000),
+    {This4, ok} = i16(This3, -1),
+    {This5, ok} = i16(This4, -128),
+    {This6, ok} = i16(This5, -30000),
+    {This6, ok}.
 
 i32(This0, Value0) -> round_trip(This0, i32, Value0).
 i32_test() ->
-  {ok, This0} = new(),
-  {This1, ok} = i32(This0, 0),
-  {This2, ok} = i32(This1, 42),
-  {This3, ok} = i32(This2, 30000),
-  {This4, ok} = i32(This3, 2000000002),
-  {This5, ok} = i32(This4, -1),
-  {This6, ok} = i32(This5, -128),
-  {This7, ok} = i32(This6, -30000),
-  {This8, ok} = i32(This7, -2000000002),
-  {This8, ok}.
+    {ok, This0} = new(),
+    {This1, ok} = i32(This0, 0),
+    {This2, ok} = i32(This1, 42),
+    {This3, ok} = i32(This2, 30000),
+    {This4, ok} = i32(This3, 2000000002),
+    {This5, ok} = i32(This4, -1),
+    {This6, ok} = i32(This5, -128),
+    {This7, ok} = i32(This6, -30000),
+    {This8, ok} = i32(This7, -2000000002),
+    {This8, ok}.
 
 i64(This0, Value0) -> round_trip(This0, i64, Value0).
 i64_test() ->
-  {ok, This0} = new(),
-  {This1, ok} = i64(This0, 0),
-  {This2, ok} = i64(This1, 42),
-  {This3, ok} = i64(This2, 30000),
-  {This4, ok} = i64(This3, 2000000002),
-  {This5, ok} = i64(This4, 100000000000000064),
-  {This6, ok} = i64(This5, -1),
-  {This7, ok} = i64(This6, -128),
-  {This8, ok} = i64(This7, -30000),
-  {This9, ok} = i64(This8, -2000000002),
-  {This10, ok} = i64(This9, -100000000000000064),
-  {This10, ok}.
+    {ok, This0} = new(),
+    {This1, ok} = i64(This0, 0),
+    {This2, ok} = i64(This1, 42),
+    {This3, ok} = i64(This2, 30000),
+    {This4, ok} = i64(This3, 2000000002),
+    {This5, ok} = i64(This4, 100000000000000064),
+    {This6, ok} = i64(This5, -1),
+    {This7, ok} = i64(This6, -128),
+    {This8, ok} = i64(This7, -30000),
+    {This9, ok} = i64(This8, -2000000002),
+    {This10, ok} = i64(This9, -100000000000000064),
+    {This10, ok}.
 
 struct_test() ->
-  {ok, P0} = new(),
-  {P1, ok} = write(P0, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}),
-  {P2, ok} = write(P1, #protocol_struct_begin{}),
-  {P3, ok} = write(P2, #protocol_field_begin{ name = "field1", type = ?tType_I8, id = 1}),
-  {P4, ok} = write(P3, {byte, 42}),
-  {P5, ok} = write(P4, field_end),
-  {P6, ok} = write(P5, #protocol_field_begin{ name = "field2", type = ?tType_I8, id = 14}),
-  {P7, ok} = write(P6, {byte, 3}),
-  {P8, ok} = write(P7, field_end),
-  {P9, ok} = write(P8, #protocol_field_begin{ name = "field3", type = ?tType_I8, id = 42}),
-  {P10, ok} = write(P9, {byte, 8}),
-  {P11, ok} = write(P10, field_end),
-  {P12, ok} = write(P11, field_stop),
-  {P13, ok} = write(P12, struct_end),
-  {P14, ok} = write(P13, message_end),
+    {ok, P0} = new(),
+    {P1, ok} = write(P0, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}),
+    {P2, ok} = write(P1, #protocol_struct_begin{}),
+    {P3, ok} = write(P2, #protocol_field_begin{name = "field1", type = ?tType_I8, id = 1}),
+    {P4, ok} = write(P3, {byte, 42}),
+    {P5, ok} = write(P4, field_end),
+    {P6, ok} = write(P5, #protocol_field_begin{name = "field2", type = ?tType_I8, id = 14}),
+    {P7, ok} = write(P6, {byte, 3}),
+    {P8, ok} = write(P7, field_end),
+    {P9, ok} = write(P8, #protocol_field_begin{name = "field3", type = ?tType_I8, id = 42}),
+    {P10, ok} = write(P9, {byte, 8}),
+    {P11, ok} = write(P10, field_end),
+    {P12, ok} = write(P11, field_stop),
+    {P13, ok} = write(P12, struct_end),
+    {P14, ok} = write(P13, message_end),
 
-  {P15, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}} = read(P14, message_begin),
-  {P16, ok} = read(P15, struct_begin),
-  {P17, #protocol_field_begin{ type = ?tType_I8, id = 1 }} = read(P16, field_begin),
-  {P18, {ok, 42}} = read(P17, byte),
-  {P19, ok} = read(P18, field_end),
-  {P20, #protocol_field_begin{ type = ?tType_I8, id = 14 }} = read(P19, field_begin),
-  {P21, {ok, 3}} = read(P20, byte),
-  {P22, ok} = read(P21, field_end),
-  {P23, #protocol_field_begin{ type = ?tType_I8, id = 42 }} = read(P22, field_begin),
-  {P24, {ok, 8}} = read(P23, byte),
-  {P25, ok} = read(P24, field_end),
-  {P26, #protocol_field_begin{ type = ?tType_STOP}} = read(P25, field_begin),
-  {P27, ok} = read(P26, struct_end),
-  {P28, ok} = read(P27, message_end),
-  {P28, ok}.
+    {P15, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}} = read(
+        P14, message_begin
+    ),
+    {P16, ok} = read(P15, struct_begin),
+    {P17, #protocol_field_begin{type = ?tType_I8, id = 1}} = read(P16, field_begin),
+    {P18, {ok, 42}} = read(P17, byte),
+    {P19, ok} = read(P18, field_end),
+    {P20, #protocol_field_begin{type = ?tType_I8, id = 14}} = read(P19, field_begin),
+    {P21, {ok, 3}} = read(P20, byte),
+    {P22, ok} = read(P21, field_end),
+    {P23, #protocol_field_begin{type = ?tType_I8, id = 42}} = read(P22, field_begin),
+    {P24, {ok, 8}} = read(P23, byte),
+    {P25, ok} = read(P24, field_end),
+    {P26, #protocol_field_begin{type = ?tType_STOP}} = read(P25, field_begin),
+    {P27, ok} = read(P26, struct_end),
+    {P28, ok} = read(P27, message_end),
+    {P28, ok}.
 
 bool_field_test() ->
-  {ok, P0} = new(),
-  {P1, ok} = write(P0, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}),
-  {P2, ok} = write(P1, #protocol_struct_begin{}),
-  {P3, ok} = write(P2, #protocol_field_begin{ name = "field1", type = ?tType_BOOL, id = 1}),
-  {P4, ok} = write(P3, {bool, true}),
-  {P5, ok} = write(P4, field_end),
-  {P6, ok} = write(P5, #protocol_field_begin{ name = "field2", type = ?tType_BOOL, id = 14}),
-  {P7, ok} = write(P6, {bool, false}),
-  {P8, ok} = write(P7, field_end),
-  {P9, ok} = write(P8, #protocol_field_begin{ name = "field3", type = ?tType_BOOL, id = 42}),
-  {P10, ok} = write(P9, {bool, true}),
-  {P11, ok} = write(P10, field_end),
-  {P12, ok} = write(P11, field_stop),
-  {P13, ok} = write(P12, struct_end),
-  {P14, ok} = write(P13, message_end),
+    {ok, P0} = new(),
+    {P1, ok} = write(P0, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}),
+    {P2, ok} = write(P1, #protocol_struct_begin{}),
+    {P3, ok} = write(P2, #protocol_field_begin{name = "field1", type = ?tType_BOOL, id = 1}),
+    {P4, ok} = write(P3, {bool, true}),
+    {P5, ok} = write(P4, field_end),
+    {P6, ok} = write(P5, #protocol_field_begin{name = "field2", type = ?tType_BOOL, id = 14}),
+    {P7, ok} = write(P6, {bool, false}),
+    {P8, ok} = write(P7, field_end),
+    {P9, ok} = write(P8, #protocol_field_begin{name = "field3", type = ?tType_BOOL, id = 42}),
+    {P10, ok} = write(P9, {bool, true}),
+    {P11, ok} = write(P10, field_end),
+    {P12, ok} = write(P11, field_stop),
+    {P13, ok} = write(P12, struct_end),
+    {P14, ok} = write(P13, message_end),
 
-  {P15, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}} = read(P14, message_begin),
-  {P16, ok} = read(P15, struct_begin),
-  {P17, #protocol_field_begin{ type = ?tType_BOOL, id = 1 }} = read(P16, field_begin),
-  {P18, {ok, true}} = read(P17, bool),
-  {P19, ok} = read(P18, field_end),
-  {P20, #protocol_field_begin{ type = ?tType_BOOL, id = 14 }} = read(P19, field_begin),
-  {P21, {ok, false}} = read(P20, bool),
-  {P22, ok} = read(P21, field_end),
-  {P23, #protocol_field_begin{ type = ?tType_BOOL, id = 42 }} = read(P22, field_begin),
-  {P24, {ok, true}} = read(P23, bool),
-  {P25, ok} = read(P24, field_end),
-  {P26, #protocol_field_begin{ type = ?tType_STOP}} = read(P25, field_begin),
-  {P27, ok} = read(P26, struct_end),
-  {P28, ok} = read(P27, message_end),
-  {P28, ok}.
+    {P15, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}} = read(
+        P14, message_begin
+    ),
+    {P16, ok} = read(P15, struct_begin),
+    {P17, #protocol_field_begin{type = ?tType_BOOL, id = 1}} = read(P16, field_begin),
+    {P18, {ok, true}} = read(P17, bool),
+    {P19, ok} = read(P18, field_end),
+    {P20, #protocol_field_begin{type = ?tType_BOOL, id = 14}} = read(P19, field_begin),
+    {P21, {ok, false}} = read(P20, bool),
+    {P22, ok} = read(P21, field_end),
+    {P23, #protocol_field_begin{type = ?tType_BOOL, id = 42}} = read(P22, field_begin),
+    {P24, {ok, true}} = read(P23, bool),
+    {P25, ok} = read(P24, field_end),
+    {P26, #protocol_field_begin{type = ?tType_STOP}} = read(P25, field_begin),
+    {P27, ok} = read(P26, struct_end),
+    {P28, ok} = read(P27, message_end),
+    {P28, ok}.
 
 nesting_test() ->
-  {ok, P0} = new(),
-  {P1, ok} = write(P0, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}),
-  {P2, ok} = write(P1, #protocol_struct_begin{}),
-  {P3, ok} = write(P2, #protocol_field_begin{ name = "field1", type = ?tType_BOOL, id = 14}),
-  {P4, ok} = write(P3, {bool, true}),
-  {P5, ok} = write(P4, field_end),
+    {ok, P0} = new(),
+    {P1, ok} = write(P0, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}),
+    {P2, ok} = write(P1, #protocol_struct_begin{}),
+    {P3, ok} = write(P2, #protocol_field_begin{name = "field1", type = ?tType_BOOL, id = 14}),
+    {P4, ok} = write(P3, {bool, true}),
+    {P5, ok} = write(P4, field_end),
 
-  {P6, ok} = write(P5, #protocol_field_begin{ name = "field2", type = ?tType_STRUCT, id = 28}),
-  {P7, ok} = write(P6, #protocol_struct_begin{}),
-  {P8, ok} = write(P7, #protocol_field_begin{ name = "field2_1", type = ?tType_BOOL, id = 30000}),
-  {P9, ok} = write(P8, {bool, false}),
-  {P10, ok} = write(P9, field_end),
-  {P11, ok} = write(P10, field_stop),
-  {P12, ok} = write(P11, struct_end),
-  {P13, ok} = write(P12, field_end),
+    {P6, ok} = write(P5, #protocol_field_begin{name = "field2", type = ?tType_STRUCT, id = 28}),
+    {P7, ok} = write(P6, #protocol_struct_begin{}),
+    {P8, ok} = write(P7, #protocol_field_begin{name = "field2_1", type = ?tType_BOOL, id = 30000}),
+    {P9, ok} = write(P8, {bool, false}),
+    {P10, ok} = write(P9, field_end),
+    {P11, ok} = write(P10, field_stop),
+    {P12, ok} = write(P11, struct_end),
+    {P13, ok} = write(P12, field_end),
 
-  {P14, ok} = write(P13, #protocol_field_begin{ name = "field3", type = ?tType_BOOL, id = 42}),
-  {P15, ok} = write(P14, {bool, true}),
-  {P16, ok} = write(P15, field_end),
-  {P17, ok} = write(P16, field_stop),
-  {P18, ok} = write(P17, struct_end),
-  {P19, ok} = write(P18, message_end),
+    {P14, ok} = write(P13, #protocol_field_begin{name = "field3", type = ?tType_BOOL, id = 42}),
+    {P15, ok} = write(P14, {bool, true}),
+    {P16, ok} = write(P15, field_end),
+    {P17, ok} = write(P16, field_stop),
+    {P18, ok} = write(P17, struct_end),
+    {P19, ok} = write(P18, message_end),
 
-  {P20, #protocol_message_begin{ name = "Message1", type = ?tType_I8, seqid = 3}} = read(P19, message_begin),
-  {P21, ok} = read(P20, struct_begin),
-  {P22, #protocol_field_begin{ type = ?tType_BOOL, id = 14 }} = read(P21, field_begin),
-  {P23, {ok, true}} = read(P22, bool),
-  {P24, ok} = read(P23, field_end),
+    {P20, #protocol_message_begin{name = "Message1", type = ?tType_I8, seqid = 3}} = read(
+        P19, message_begin
+    ),
+    {P21, ok} = read(P20, struct_begin),
+    {P22, #protocol_field_begin{type = ?tType_BOOL, id = 14}} = read(P21, field_begin),
+    {P23, {ok, true}} = read(P22, bool),
+    {P24, ok} = read(P23, field_end),
 
-  {P25, #protocol_field_begin{ type = ?tType_STRUCT, id = 28 }} = read(P24, field_begin),
-  {P26, ok} = read(P25, struct_begin),
-  {P27, #protocol_field_begin{ type = ?tType_BOOL, id = 30000 }} = read(P26, field_begin),
-  {P28, {ok, false}} = read(P27, bool),
-  {P29, ok} = read(P28, field_end),
-  {P30, #protocol_field_begin{ type = ?tType_STOP }} = read(P29, field_begin),
-  {P31, ok} = read(P30, struct_end),
-  {P32, ok} = read(P31, field_end),
+    {P25, #protocol_field_begin{type = ?tType_STRUCT, id = 28}} = read(P24, field_begin),
+    {P26, ok} = read(P25, struct_begin),
+    {P27, #protocol_field_begin{type = ?tType_BOOL, id = 30000}} = read(P26, field_begin),
+    {P28, {ok, false}} = read(P27, bool),
+    {P29, ok} = read(P28, field_end),
+    {P30, #protocol_field_begin{type = ?tType_STOP}} = read(P29, field_begin),
+    {P31, ok} = read(P30, struct_end),
+    {P32, ok} = read(P31, field_end),
 
-  {P33, #protocol_field_begin{ type = ?tType_BOOL, id = 42 }} = read(P32, field_begin),
-  {P34, {ok, true}} = read(P33, bool),
-  {P35, ok} = read(P34, field_end),
-  {P36, #protocol_field_begin{ type = ?tType_STOP }} = read(P35, field_begin),
-  {P37, ok} = read(P36, struct_end),
-  {P38, ok} = read(P37, message_end),
-  {P38, ok}.
+    {P33, #protocol_field_begin{type = ?tType_BOOL, id = 42}} = read(P32, field_begin),
+    {P34, {ok, true}} = read(P33, bool),
+    {P35, ok} = read(P34, field_end),
+    {P36, #protocol_field_begin{type = ?tType_STOP}} = read(P35, field_begin),
+    {P37, ok} = read(P36, struct_end),
+    {P38, ok} = read(P37, message_end),
+    {P38, ok}.
diff --git a/lib/erl/test/test_thrift_file_transport.erl b/lib/erl/test/test_thrift_file_transport.erl
index 3e5c1d1..85b6c46 100644
--- a/lib/erl/test/test_thrift_file_transport.erl
+++ b/lib/erl/test/test_thrift_file_transport.erl
@@ -20,194 +20,205 @@
 -module(test_thrift_file_transport).
 -include_lib("eunit/include/eunit.hrl").
 
-
 new(File) -> thrift_file_transport:new(File).
 new(File, Opts) -> thrift_file_transport:new(File, Opts).
 
 new_test_() ->
-  [
-    {"new file", ?_assertMatch(
-      {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}},
-      new(a_fake_file)
-    )},
-    {"new file in read mode", ?_assertMatch(
-      {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, read}}},
-      new(a_fake_file, [{mode, read}])
-    )},
-    {"new file in write mode", ?_assertMatch(
-      {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}},
-      new(a_fake_file, [{mode, write}])
-    )},
-    {"new file in should_close true mode", ?_assertMatch(
-      {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}},
-      new(a_fake_file, [{should_close, true}])
-    )},
-    {"new file in should_close false mode", ?_assertMatch(
-      {ok, {_, thrift_file_transport, {t_file, a_fake_file, false, write}}},
-      new(a_fake_file, [{should_close, false}])
-    )}
-  ].
-
+    [
+        {"new file",
+            ?_assertMatch(
+                {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}},
+                new(a_fake_file)
+            )},
+        {"new file in read mode",
+            ?_assertMatch(
+                {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, read}}},
+                new(a_fake_file, [{mode, read}])
+            )},
+        {"new file in write mode",
+            ?_assertMatch(
+                {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}},
+                new(a_fake_file, [{mode, write}])
+            )},
+        {"new file in should_close true mode",
+            ?_assertMatch(
+                {ok, {_, thrift_file_transport, {t_file, a_fake_file, true, write}}},
+                new(a_fake_file, [{should_close, true}])
+            )},
+        {"new file in should_close false mode",
+            ?_assertMatch(
+                {ok, {_, thrift_file_transport, {t_file, a_fake_file, false, write}}},
+                new(a_fake_file, [{should_close, false}])
+            )}
+    ].
 
 read(File, Bytes) -> thrift_file_transport:read(File, Bytes).
 
 read_test_() ->
-  {setup,
-    fun() ->
-      meck:new(file, [unstick, passthrough]),
-      meck:expect(file, read, fun(Bin, N) ->
-        {Result, _} = split_binary(Bin, min(iolist_size(Bin), N)),
-        {ok, Result}
-      end)
-    end,
-    fun(_) -> meck:unload(file) end,
-    [
-      {"read zero bytes from empty file", ?_assertMatch(
-        {_, {ok, <<>>}},
-        read({t_file, <<>>, true, read}, 0)
-      )},
-      {"read 1 byte from empty file", ?_assertMatch(
-        {_, {ok, <<>>}},
-        read({t_file, <<>>, true, read}, 1)
-      )},
-      {"read zero bytes from nonempty file", ?_assertMatch(
-        {_, {ok, <<>>}},
-        read({t_file, <<"hallo world">>, true, read}, 0)
-      )},
-      {"read 1 byte from nonempty file", ?_assertMatch(
-        {_, {ok, <<"h">>}},
-        read({t_file, <<"hallo world">>, true, read}, 1)
-      )},
-      {"read a zillion bytes from nonempty file", ?_assertMatch(
-        {_, {ok, <<"hallo world">>}},
-        read({t_file, <<"hallo world">>, true, read}, 65536)
-      )},
-      {"read 0 byte from file in write mode", ?_assertMatch(
-        {_, {error, write_mode}},
-        read({t_file, <<>>, true, write}, 0)
-      )},
-      {"read 1 byte from file in write mode", ?_assertMatch(
-        {_, {error, write_mode}},
-        read({t_file, <<>>, true, write}, 1)
-      )}
-    ]
-  }.
-
+    {setup,
+        fun() ->
+            meck:new(file, [unstick, passthrough]),
+            meck:expect(file, read, fun(Bin, N) ->
+                {Result, _} = split_binary(Bin, min(iolist_size(Bin), N)),
+                {ok, Result}
+            end)
+        end,
+        fun(_) -> meck:unload(file) end, [
+            {"read zero bytes from empty file",
+                ?_assertMatch(
+                    {_, {ok, <<>>}},
+                    read({t_file, <<>>, true, read}, 0)
+                )},
+            {"read 1 byte from empty file",
+                ?_assertMatch(
+                    {_, {ok, <<>>}},
+                    read({t_file, <<>>, true, read}, 1)
+                )},
+            {"read zero bytes from nonempty file",
+                ?_assertMatch(
+                    {_, {ok, <<>>}},
+                    read({t_file, <<"hallo world">>, true, read}, 0)
+                )},
+            {"read 1 byte from nonempty file",
+                ?_assertMatch(
+                    {_, {ok, <<"h">>}},
+                    read({t_file, <<"hallo world">>, true, read}, 1)
+                )},
+            {"read a zillion bytes from nonempty file",
+                ?_assertMatch(
+                    {_, {ok, <<"hallo world">>}},
+                    read({t_file, <<"hallo world">>, true, read}, 65536)
+                )},
+            {"read 0 byte from file in write mode",
+                ?_assertMatch(
+                    {_, {error, write_mode}},
+                    read({t_file, <<>>, true, write}, 0)
+                )},
+            {"read 1 byte from file in write mode",
+                ?_assertMatch(
+                    {_, {error, write_mode}},
+                    read({t_file, <<>>, true, write}, 1)
+                )}
+        ]}.
 
 read_exact(File, Bytes) -> thrift_file_transport:read_exact(File, Bytes).
 
 read_exact_test_() ->
-  {setup,
-    fun() ->
-      meck:new(file, [unstick, passthrough]),
-      meck:expect(file, read, fun(Bin, N) ->
-        {Result, _} = split_binary(Bin, min(iolist_size(Bin), N)),
-        {ok, Result}
-      end)
-    end,
-    fun(_) -> meck:unload(file) end,
-    [
-      {"read exactly zero bytes from empty file", ?_assertMatch(
-        {_, {ok, <<>>}},
-        read_exact({t_file, <<>>, true, read}, 0)
-      )},
-      {"read exactly 1 byte from empty file", ?_assertMatch(
-        {_, {error, eof}},
-        read_exact({t_file, <<>>, true, read}, 1)
-      )},
-      {"read exactly zero bytes from nonempty file", ?_assertMatch(
-        {_, {ok, <<>>}},
-        read_exact({t_file, <<"hallo world">>, true, read}, 0)
-      )},
-      {"read exactly 1 byte from nonempty file", ?_assertMatch(
-        {_, {ok, <<"h">>}},
-        read_exact({t_file, <<"hallo world">>, true, read}, 1)
-      )},
-      {"read exactly a zillion bytes from nonempty file", ?_assertMatch(
-        {_, {error, eof}},
-        read_exact({t_file, <<"hallo world">>, true, read}, 65536)
-      )},
-      {"read exactly 0 byte from file in write mode", ?_assertMatch(
-        {_, {error, write_mode}},
-        read_exact({t_file, <<>>, true, write}, 0)
-      )},
-      {"read exactly 1 byte from file in write mode", ?_assertMatch(
-        {_, {error, write_mode}},
-        read_exact({t_file, <<>>, true, write}, 1)
-      )}
-    ]
-  }.
-
+    {setup,
+        fun() ->
+            meck:new(file, [unstick, passthrough]),
+            meck:expect(file, read, fun(Bin, N) ->
+                {Result, _} = split_binary(Bin, min(iolist_size(Bin), N)),
+                {ok, Result}
+            end)
+        end,
+        fun(_) -> meck:unload(file) end, [
+            {"read exactly zero bytes from empty file",
+                ?_assertMatch(
+                    {_, {ok, <<>>}},
+                    read_exact({t_file, <<>>, true, read}, 0)
+                )},
+            {"read exactly 1 byte from empty file",
+                ?_assertMatch(
+                    {_, {error, eof}},
+                    read_exact({t_file, <<>>, true, read}, 1)
+                )},
+            {"read exactly zero bytes from nonempty file",
+                ?_assertMatch(
+                    {_, {ok, <<>>}},
+                    read_exact({t_file, <<"hallo world">>, true, read}, 0)
+                )},
+            {"read exactly 1 byte from nonempty file",
+                ?_assertMatch(
+                    {_, {ok, <<"h">>}},
+                    read_exact({t_file, <<"hallo world">>, true, read}, 1)
+                )},
+            {"read exactly a zillion bytes from nonempty file",
+                ?_assertMatch(
+                    {_, {error, eof}},
+                    read_exact({t_file, <<"hallo world">>, true, read}, 65536)
+                )},
+            {"read exactly 0 byte from file in write mode",
+                ?_assertMatch(
+                    {_, {error, write_mode}},
+                    read_exact({t_file, <<>>, true, write}, 0)
+                )},
+            {"read exactly 1 byte from file in write mode",
+                ?_assertMatch(
+                    {_, {error, write_mode}},
+                    read_exact({t_file, <<>>, true, write}, 1)
+                )}
+        ]}.
 
 write(File, Data) -> thrift_file_transport:write(File, Data).
 
 write_test_() ->
-  {setup,
-    fun() ->
-      meck:new(file, [unstick, passthrough]),
-      meck:expect(file, write, fun(_, _) -> ok end)
-    end,
-    fun(_) -> meck:unload(file) end,
-    [
-      {"write empty list to file", ?_assertMatch(
-        {{t_file, a_fake_file, true, write}, ok},
-        write({t_file, a_fake_file, true, write}, [])
-      )},
-      {"write empty binary to file", ?_assertMatch(
-        {{t_file, a_fake_file, true, write}, ok},
-        write({t_file, a_fake_file, true, write}, <<>>)
-      )},
-      {"write a list to file", ?_assertMatch(
-        {{t_file, a_fake_file, true, write}, ok},
-        write({t_file, a_fake_file, true, write}, "hallo world")
-      )},
-      {"write a binary to file", ?_assertMatch(
-        {{t_file, a_fake_file, true, write}, ok},
-        write({t_file, a_fake_file, true, write}, <<"hallo world">>)
-      )},
-      {"write a binary to file in read mode", ?_assertMatch(
-        {_, {error, read_mode}},
-        write({t_file, a_fake_file, true, read}, <<"hallo world">>)
-      )},
-      {"write a list to file in read mode", ?_assertMatch(
-        {_, {error, read_mode}},
-        write({t_file, a_fake_file, true, read}, "hallo world")
-      )}
-    ]
-  }.
-
+    {setup,
+        fun() ->
+            meck:new(file, [unstick, passthrough]),
+            meck:expect(file, write, fun(_, _) -> ok end)
+        end,
+        fun(_) -> meck:unload(file) end, [
+            {"write empty list to file",
+                ?_assertMatch(
+                    {{t_file, a_fake_file, true, write}, ok},
+                    write({t_file, a_fake_file, true, write}, [])
+                )},
+            {"write empty binary to file",
+                ?_assertMatch(
+                    {{t_file, a_fake_file, true, write}, ok},
+                    write({t_file, a_fake_file, true, write}, <<>>)
+                )},
+            {"write a list to file",
+                ?_assertMatch(
+                    {{t_file, a_fake_file, true, write}, ok},
+                    write({t_file, a_fake_file, true, write}, "hallo world")
+                )},
+            {"write a binary to file",
+                ?_assertMatch(
+                    {{t_file, a_fake_file, true, write}, ok},
+                    write({t_file, a_fake_file, true, write}, <<"hallo world">>)
+                )},
+            {"write a binary to file in read mode",
+                ?_assertMatch(
+                    {_, {error, read_mode}},
+                    write({t_file, a_fake_file, true, read}, <<"hallo world">>)
+                )},
+            {"write a list to file in read mode",
+                ?_assertMatch(
+                    {_, {error, read_mode}},
+                    write({t_file, a_fake_file, true, read}, "hallo world")
+                )}
+        ]}.
 
 flush(Transport) -> thrift_file_transport:flush(Transport).
 
 flush_test_() ->
-  {setup,
-    fun() ->
-      meck:new(file, [unstick, passthrough]),
-      meck:expect(file, sync, fun(_File) -> ok end)
-    end,
-    fun(_) -> meck:unload(file) end,
-    [
-      {"flush file", ?_assertMatch(
-        {{t_file, a_fake_file, true, write}, ok},
-        flush({t_file, a_fake_file, true, write})
-      )}
-    ]
-  }.
-
+    {setup,
+        fun() ->
+            meck:new(file, [unstick, passthrough]),
+            meck:expect(file, sync, fun(_File) -> ok end)
+        end,
+        fun(_) -> meck:unload(file) end, [
+            {"flush file",
+                ?_assertMatch(
+                    {{t_file, a_fake_file, true, write}, ok},
+                    flush({t_file, a_fake_file, true, write})
+                )}
+        ]}.
 
 close(Transport) -> thrift_file_transport:close(Transport).
 
 close_test_() ->
-  {setup,
-    fun() ->
-      meck:new(file, [unstick, passthrough]),
-      meck:expect(file, close, fun(_) -> ok end)
-    end,
-    fun(_) -> meck:unload(file) end,
-    [
-      {"close file", ?_assertMatch(
-        {{t_file, a_fake_file, true, write}, ok},
-        close({t_file, a_fake_file, true, write})
-      )}
-    ]
-  }.
\ No newline at end of file
+    {setup,
+        fun() ->
+            meck:new(file, [unstick, passthrough]),
+            meck:expect(file, close, fun(_) -> ok end)
+        end,
+        fun(_) -> meck:unload(file) end, [
+            {"close file",
+                ?_assertMatch(
+                    {{t_file, a_fake_file, true, write}, ok},
+                    close({t_file, a_fake_file, true, write})
+                )}
+        ]}.
diff --git a/lib/erl/test/test_thrift_framed_transport.erl b/lib/erl/test/test_thrift_framed_transport.erl
index 8a538a5..b960920 100644
--- a/lib/erl/test/test_thrift_framed_transport.erl
+++ b/lib/erl/test/test_thrift_framed_transport.erl
@@ -20,385 +20,302 @@
 -module(test_thrift_framed_transport).
 -include_lib("eunit/include/eunit.hrl").
 
-
 new(Transport) -> thrift_framed_transport:new(Transport).
 
 new_test_() ->
-  [
-    {"new framed membuffer", ?_assertMatch(
-      {ok, {t_transport, thrift_framed_transport, {t_framed,
-        {t_transport, thrift_membuffer_transport, {t_membuffer, []}},
-        [],
-        []
-      }}},
-      new({t_transport, thrift_membuffer_transport, {t_membuffer, []}})
-    )}
-  ].
-
+    [
+        {"new framed membuffer",
+            ?_assertMatch(
+                {ok,
+                    {t_transport, thrift_framed_transport,
+                        {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, []}}, [],
+                            []}}},
+                new({t_transport, thrift_membuffer_transport, {t_membuffer, []}})
+            )}
+    ].
 
 read(Frame, Bytes) -> thrift_framed_transport:read(Frame, Bytes).
 
 read_test_() ->
-  [
-    {"read zero bytes from an empty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          []
-        },
-        {ok, <<>>}
-      },
-      read(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          []
-        },
-        0
-      )
-    )},
-    {"read 1 byte from an empty framed membuffer", ?_assertMatch(
-      {_, {error, eof}},
-      read(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          []
-        },
-        1
-      )
-    )},
-    {"read zero bytes from nonempty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<0, 0, 0, 11, "hallo world">>
-          }},
-          [],
-          []
-        },
-        {ok, <<>>}
-      },
-      read(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<0, 0, 0, 11, "hallo world">>
-          }},
-          [],
-          []
-        },
-        0
-      )
-    )},
-    {"read 1 byte from nonempty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          <<"allo world">>,
-          []
-        },
-        {ok, <<"h">>}
-      },
-      read(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<0, 0, 0, 11, "hallo world">>
-          }},
-          [],
-          []
-        },
-        1
-      )
-    )},
-    {"read 1 byte from nonempty buffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          <<"allo world">>,
-          []
-        },
-        {ok, <<"h">>}
-      },
-      read(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          <<"hallo world">>,
-          []
-        },
-        1
-      )
-    )},
-    {"read a zillion bytes from nonempty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          <<>>,
-          []
-        },
-        {ok, <<"hallo world">>}
-      },
-      read(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<0, 0, 0, 11, "hallo world">>
-          }},
-          [],
-          []
-        },
-        65536
-      )
-    )}
-  ].
-
+    [
+        {"read zero bytes from an empty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []},
+                    {ok, <<>>}
+                },
+                read(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []},
+                    0
+                )
+            )},
+        {"read 1 byte from an empty framed membuffer",
+            ?_assertMatch(
+                {_, {error, eof}},
+                read(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []},
+                    1
+                )
+            )},
+        {"read zero bytes from nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, <<0, 0, 0, 11, "hallo world">>}},
+                        [], []},
+                    {ok, <<>>}
+                },
+                read(
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, <<0, 0, 0, 11, "hallo world">>}},
+                        [], []},
+                    0
+                )
+            )},
+        {"read 1 byte from nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        <<"allo world">>, []},
+                    {ok, <<"h">>}
+                },
+                read(
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, <<0, 0, 0, 11, "hallo world">>}},
+                        [], []},
+                    1
+                )
+            )},
+        {"read 1 byte from nonempty buffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        <<"allo world">>, []},
+                    {ok, <<"h">>}
+                },
+                read(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        <<"hallo world">>, []},
+                    1
+                )
+            )},
+        {"read a zillion bytes from nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<>>,
+                        []},
+                    {ok, <<"hallo world">>}
+                },
+                read(
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, <<0, 0, 0, 11, "hallo world">>}},
+                        [], []},
+                    65536
+                )
+            )}
+    ].
 
 read_exact(Frame, Bytes) -> thrift_framed_transport:read_exact(Frame, Bytes).
 
 read_exact_test_() ->
-  [
-    {"read exactly zero bytes from an empty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          <<>>,
-          []
-        },
-        {ok, <<>>}
-      },
-      read_exact(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          []
-        },
-        0
-      )
-    )},
-    {"read exactly 1 byte from an empty framed membuffer", ?_assertMatch(
-      {_, {error, eof}},
-      read_exact(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          []
-        },
-        1
-      )
-    )},
-    {"read exactly zero bytes from nonempty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<0, 0, 0, 11, "hallo world">>
-          }},
-          <<>>,
-          []
-        },
-        {ok, <<>>}
-      },
-      read_exact(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<0, 0, 0, 11, "hallo world">>
-          }},
-          [],
-          []
-        },
-        0
-      )
-    )},
-    {"read exactly 1 byte from nonempty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          <<"allo world">>,
-          []
-        },
-        {ok, <<"h">>}
-      },
-      read_exact(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<0, 0, 0, 11, "hallo world">>
-          }},
-          [],
-          []
-        },
-        1
-      )
-    )},
-    {"read exactly 1 byte from nonempty buffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          <<"allo world">>,
-          []
-        },
-        {ok, <<"h">>}
-      },
-      read_exact(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          <<"hallo world">>,
-          []
-        },
-        1
-      )
-    )},
-    {"read exactly a zillion bytes from nonempty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [[],<<"hallo world">>],
-          []
-        },
-        {error, eof}
-      },
-      read_exact(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            <<0, 0, 0, 11, "hallo world">>
-          }},
-          [],
-          []
-        },
-        65536
-      )
-    )}
-  ].
-
+    [
+        {"read exactly zero bytes from an empty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, <<>>,
+                        []},
+                    {ok, <<>>}
+                },
+                read_exact(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []},
+                    0
+                )
+            )},
+        {"read exactly 1 byte from an empty framed membuffer",
+            ?_assertMatch(
+                {_, {error, eof}},
+                read_exact(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []},
+                    1
+                )
+            )},
+        {"read exactly zero bytes from nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, <<0, 0, 0, 11, "hallo world">>}},
+                        <<>>, []},
+                    {ok, <<>>}
+                },
+                read_exact(
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, <<0, 0, 0, 11, "hallo world">>}},
+                        [], []},
+                    0
+                )
+            )},
+        {"read exactly 1 byte from nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        <<"allo world">>, []},
+                    {ok, <<"h">>}
+                },
+                read_exact(
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, <<0, 0, 0, 11, "hallo world">>}},
+                        [], []},
+                    1
+                )
+            )},
+        {"read exactly 1 byte from nonempty buffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        <<"allo world">>, []},
+                    {ok, <<"h">>}
+                },
+                read_exact(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        <<"hallo world">>, []},
+                    1
+                )
+            )},
+        {"read exactly a zillion bytes from nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
+                        [[], <<"hallo world">>], []},
+                    {error, eof}
+                },
+                read_exact(
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, <<0, 0, 0, 11, "hallo world">>}},
+                        [], []},
+                    65536
+                )
+            )}
+    ].
 
 write(Framed, Data) -> thrift_framed_transport:write(Framed, Data).
 
 write_test_() ->
-  [
-    {"write empty list to empty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          [[], []]
-        },
-        ok
-      },
-      write(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          []
-        },
-        []
-      )
-    )},
-    {"write empty list to nonempty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          [["hallo world"], []]
-        },
-        ok
-      },
-      write(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          ["hallo world"]
-        },
-        []
-      )
-    )},
-    {"write empty binary to empty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          [[], <<>>]
-        },
-        ok
-      },
-      write(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          []
-        },
-        <<>>
-      )
-    )},
-    {"write empty binary to nonempty framed membuffer", ?_assertMatch(
-      {
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          [["hallo world"], <<>>]
-        },
-        ok
-      },
-      write(
-        {t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          ["hallo world"]
-        },
-        <<>>
-      )
-    )}
-  ].
-
+    [
+        {"write empty list to empty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [
+                            [], []
+                        ]},
+                    ok
+                },
+                write(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []},
+                    []
+                )
+            )},
+        {"write empty list to nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [
+                            ["hallo world"], []
+                        ]},
+                    ok
+                },
+                write(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [
+                            "hallo world"
+                        ]},
+                    []
+                )
+            )},
+        {"write empty binary to empty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [
+                            [], <<>>
+                        ]},
+                    ok
+                },
+                write(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []},
+                    <<>>
+                )
+            )},
+        {"write empty binary to nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [
+                            ["hallo world"], <<>>
+                        ]},
+                    ok
+                },
+                write(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], [
+                            "hallo world"
+                        ]},
+                    <<>>
+                )
+            )}
+    ].
 
 flush(Transport) -> thrift_framed_transport:flush(Transport).
 
 flush_test_() ->
-  [
-    {"flush empty framed membuffer", ?_assertMatch(
-      {{t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-          [],
-          []
-        },
-        ok
-      },
-      flush({t_framed,
-        {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-        [],
-        []
-      })
-    )},
-    {"flush nonempty framed membuffer", ?_assertMatch(
-      {{t_framed,
-          {t_transport, thrift_membuffer_transport, {t_membuffer,
-            [<<>>, [<<0, 0, 0, 11>>, <<"hallo world">>]]
-          }},
-          [],
-          []
-        },
-        ok
-      },
-      flush({t_framed,
-        {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-        [],
-        <<"hallo world">>
-      })
-    )}
-  ].
-
+    [
+        {"flush empty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []},
+                    ok
+                },
+                flush(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        []}
+                )
+            )},
+        {"flush nonempty framed membuffer",
+            ?_assertMatch(
+                {
+                    {t_framed,
+                        {t_transport, thrift_membuffer_transport,
+                            {t_membuffer, [<<>>, [<<0, 0, 0, 11>>, <<"hallo world">>]]}},
+                        [], []},
+                    ok
+                },
+                flush(
+                    {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [],
+                        <<"hallo world">>}
+                )
+            )}
+    ].
 
 close(Transport) -> thrift_framed_transport:close(Transport).
 
 close_test_() ->
-  {"close framed membuffer", ?_assertMatch(
-    {{t_framed,
-        {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-        [],
-        []
-      },
-      ok
-    },
-    close({t_framed,
-      {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}},
-      [],
-      []
-    })
-  )}.
-
+    {"close framed membuffer",
+        ?_assertMatch(
+            {
+                {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []},
+                ok
+            },
+            close(
+                {t_framed, {t_transport, thrift_membuffer_transport, {t_membuffer, <<>>}}, [], []}
+            )
+        )}.
diff --git a/lib/erl/test/test_thrift_membuffer_transport.erl b/lib/erl/test/test_thrift_membuffer_transport.erl
index 9689c79..e388311 100644
--- a/lib/erl/test/test_thrift_membuffer_transport.erl
+++ b/lib/erl/test/test_thrift_membuffer_transport.erl
@@ -20,148 +20,168 @@
 -module(test_thrift_membuffer_transport).
 -include_lib("eunit/include/eunit.hrl").
 
-
 new() -> thrift_membuffer_transport:new().
 new(Data) -> thrift_membuffer_transport:new(Data).
 
 new_test_() ->
-  [
-    {"new empty membuffer", ?_assertMatch(
-      {ok, {_, _, {t_membuffer, []}}},
-      new()
-    )},
-    {"new membuffer with <<>>", ?_assertMatch(
-      {ok, {_, _, {t_membuffer, [<<>>]}}},
-      new(<<>>)
-    )},
-    {"new membuffer with []", ?_assertMatch(
-      {ok, {_, _, {t_membuffer, []}}},
-      new([])
-    )},
-    {"new membuffer with <<\"hallo world\">>", ?_assertMatch(
-      {ok, {_, _, {t_membuffer, [<<"hallo world">>]}}},
-      new(<<"hallo world">>)
-    )},
-    {"new membuffer with \"hallo world\"", ?_assertMatch(
-      {ok, {_, _, {t_membuffer, "hallo world"}}},
-      new("hallo world")
-    )}
-  ].
-
+    [
+        {"new empty membuffer",
+            ?_assertMatch(
+                {ok, {_, _, {t_membuffer, []}}},
+                new()
+            )},
+        {"new membuffer with <<>>",
+            ?_assertMatch(
+                {ok, {_, _, {t_membuffer, [<<>>]}}},
+                new(<<>>)
+            )},
+        {"new membuffer with []",
+            ?_assertMatch(
+                {ok, {_, _, {t_membuffer, []}}},
+                new([])
+            )},
+        {"new membuffer with <<\"hallo world\">>",
+            ?_assertMatch(
+                {ok, {_, _, {t_membuffer, [<<"hallo world">>]}}},
+                new(<<"hallo world">>)
+            )},
+        {"new membuffer with \"hallo world\"",
+            ?_assertMatch(
+                {ok, {_, _, {t_membuffer, "hallo world"}}},
+                new("hallo world")
+            )}
+    ].
 
 read(Membuffer, Bytes) -> thrift_membuffer_transport:read(Membuffer, Bytes).
 
 read_test_() ->
-  [
-    {"read zero bytes from an empty membuffer", ?_assertMatch(
-      {_, {ok, <<>>}},
-      read({t_membuffer, []}, 0)
-    )},
-    {"read 1 byte from an empty membuffer", ?_assertMatch(
-      {_, {ok, <<>>}},
-      read({t_membuffer, []}, 1)
-    )},
-    {"read zero bytes from nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, <<"hallo world">>}, {ok, <<>>}},
-      read({t_membuffer, [["hallo", " "], "world"]}, 0)
-    )},
-    {"read 1 byte from nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, <<"allo world">>}, {ok, <<"h">>}},
-      read({t_membuffer, [["hallo", " "], "world"]}, 1)
-    )},
-    {"read a zillion bytes from nonempty buffer", ?_assertMatch(
-      {{t_membuffer, <<>>}, {ok, <<"hallo world">>}},
-      read({t_membuffer, [["hallo", " "], "world"]}, 65536)
-    )}
-  ].
-
+    [
+        {"read zero bytes from an empty membuffer",
+            ?_assertMatch(
+                {_, {ok, <<>>}},
+                read({t_membuffer, []}, 0)
+            )},
+        {"read 1 byte from an empty membuffer",
+            ?_assertMatch(
+                {_, {ok, <<>>}},
+                read({t_membuffer, []}, 1)
+            )},
+        {"read zero bytes from nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, <<"hallo world">>}, {ok, <<>>}},
+                read({t_membuffer, [["hallo", " "], "world"]}, 0)
+            )},
+        {"read 1 byte from nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, <<"allo world">>}, {ok, <<"h">>}},
+                read({t_membuffer, [["hallo", " "], "world"]}, 1)
+            )},
+        {"read a zillion bytes from nonempty buffer",
+            ?_assertMatch(
+                {{t_membuffer, <<>>}, {ok, <<"hallo world">>}},
+                read({t_membuffer, [["hallo", " "], "world"]}, 65536)
+            )}
+    ].
 
 read_exact(Membuffer, Bytes) ->
-  thrift_membuffer_transport:read_exact(Membuffer, Bytes).
+    thrift_membuffer_transport:read_exact(Membuffer, Bytes).
 
 read_exact_test_() ->
-  [
-    {"read exactly zero bytes from an empty membuffer", ?_assertMatch(
-      {_, {ok, <<>>}},
-      read_exact({t_membuffer, []}, 0)
-    )},
-    {"read exactly 1 byte from an empty membuffer", ?_assertMatch(
-      {_, {error, eof}},
-      read_exact({t_membuffer, []}, 1)
-    )},
-    {"read exactly zero bytes from nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, <<"hallo world">>}, {ok, <<>>}},
-      read_exact({t_membuffer, [["hallo", " "], "world"]}, 0)
-    )},
-    {"read exactly 1 byte from nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, <<"allo world">>}, {ok, <<"h">>}},
-      read_exact({t_membuffer, [["hallo", " "], "world"]}, 1)
-    )},
-    {"read exactly a zillion bytes from nonempty buffer", ?_assertMatch(
-      {{t_membuffer, [["hallo", " "], "world"]}, {error, eof}},
-      read_exact({t_membuffer, [["hallo", " "], "world"]}, 65536)
-    )}
-  ].
-
+    [
+        {"read exactly zero bytes from an empty membuffer",
+            ?_assertMatch(
+                {_, {ok, <<>>}},
+                read_exact({t_membuffer, []}, 0)
+            )},
+        {"read exactly 1 byte from an empty membuffer",
+            ?_assertMatch(
+                {_, {error, eof}},
+                read_exact({t_membuffer, []}, 1)
+            )},
+        {"read exactly zero bytes from nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, <<"hallo world">>}, {ok, <<>>}},
+                read_exact({t_membuffer, [["hallo", " "], "world"]}, 0)
+            )},
+        {"read exactly 1 byte from nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, <<"allo world">>}, {ok, <<"h">>}},
+                read_exact({t_membuffer, [["hallo", " "], "world"]}, 1)
+            )},
+        {"read exactly a zillion bytes from nonempty buffer",
+            ?_assertMatch(
+                {{t_membuffer, [["hallo", " "], "world"]}, {error, eof}},
+                read_exact({t_membuffer, [["hallo", " "], "world"]}, 65536)
+            )}
+    ].
 
 write(Membuffer, Data) -> thrift_membuffer_transport:write(Membuffer, Data).
 
 write_test_() ->
-  [
-    {"write empty list to empty membuffer", ?_assertMatch(
-      {{t_membuffer, [[], []]}, ok},
-      write({t_membuffer, []}, [])
-    )},
-    {"write empty list to nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, ["hallo world", []]}, ok},
-      write({t_membuffer, "hallo world"}, [])
-    )},
-    {"write empty binary to empty membuffer", ?_assertMatch(
-      {{t_membuffer, [[], <<>>]}, ok},
-      write({t_membuffer, []}, <<>>)
-    )},
-    {"write empty binary to nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, ["hallo world", <<>>]}, ok},
-      write({t_membuffer, "hallo world"}, <<>>)
-    )},
-    {"write a list to empty membuffer", ?_assertMatch(
-      {{t_membuffer, [[], "hallo world"]}, ok},
-      write({t_membuffer, []}, "hallo world")
-    )},
-    {"write a list to nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, [["hallo", " "], "world"]}, ok},
-      write({t_membuffer, ["hallo", " "]}, "world")
-    )},
-    {"write a binary to empty membuffer", ?_assertMatch(
-      {{t_membuffer, [[], <<"hallo world">>]}, ok},
-      write({t_membuffer, []}, <<"hallo world">>)
-    )},
-    {"write a binary to nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, [["hallo", " "], <<"world">>]}, ok},
-      write({t_membuffer, ["hallo", " "]}, <<"world">>)
-    )}
-  ].
-
+    [
+        {"write empty list to empty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, [[], []]}, ok},
+                write({t_membuffer, []}, [])
+            )},
+        {"write empty list to nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, ["hallo world", []]}, ok},
+                write({t_membuffer, "hallo world"}, [])
+            )},
+        {"write empty binary to empty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, [[], <<>>]}, ok},
+                write({t_membuffer, []}, <<>>)
+            )},
+        {"write empty binary to nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, ["hallo world", <<>>]}, ok},
+                write({t_membuffer, "hallo world"}, <<>>)
+            )},
+        {"write a list to empty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, [[], "hallo world"]}, ok},
+                write({t_membuffer, []}, "hallo world")
+            )},
+        {"write a list to nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, [["hallo", " "], "world"]}, ok},
+                write({t_membuffer, ["hallo", " "]}, "world")
+            )},
+        {"write a binary to empty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, [[], <<"hallo world">>]}, ok},
+                write({t_membuffer, []}, <<"hallo world">>)
+            )},
+        {"write a binary to nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, [["hallo", " "], <<"world">>]}, ok},
+                write({t_membuffer, ["hallo", " "]}, <<"world">>)
+            )}
+    ].
 
 flush(Transport) -> thrift_membuffer_transport:flush(Transport).
 
 flush_test_() ->
-  [
-    {"flush empty membuffer", ?_assertMatch(
-      {{t_membuffer, []}, ok},
-      flush({t_membuffer, []})
-    )},
-    {"flush nonempty membuffer", ?_assertMatch(
-      {{t_membuffer, [<<"hallo world">>]}, ok},
-      flush({t_membuffer, [<<"hallo world">>]})
-    )}
-  ].
-
+    [
+        {"flush empty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, []}, ok},
+                flush({t_membuffer, []})
+            )},
+        {"flush nonempty membuffer",
+            ?_assertMatch(
+                {{t_membuffer, [<<"hallo world">>]}, ok},
+                flush({t_membuffer, [<<"hallo world">>]})
+            )}
+    ].
 
 close(Transport) -> thrift_membuffer_transport:close(Transport).
 
 close_test_() ->
-  {"close membuffer", ?_assertMatch(
-    {{t_membuffer, _}, ok},
-    close({t_membuffer, []})
-  )}.
\ No newline at end of file
+    {"close membuffer",
+        ?_assertMatch(
+            {{t_membuffer, _}, ok},
+            close({t_membuffer, []})
+        )}.
diff --git a/lib/erl/test/test_thrift_socket_transport.erl b/lib/erl/test/test_thrift_socket_transport.erl
index 757c6d9..7e47314 100644
--- a/lib/erl/test/test_thrift_socket_transport.erl
+++ b/lib/erl/test/test_thrift_socket_transport.erl
@@ -20,185 +20,197 @@
 -module(test_thrift_socket_transport).
 -include_lib("eunit/include/eunit.hrl").
 
-
 new(Socket) -> thrift_socket_transport:new(Socket).
 new(Socket, Opts) -> thrift_socket_transport:new(Socket, Opts).
 
 new_test_() ->
-  [
-    {"new socket", ?_assertMatch(
-      {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 60000, []}}},
-      new(a_fake_socket)
-    )},
-    {"new socket with no options", ?_assertMatch(
-      {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 60000, []}}},
-      new(a_fake_socket, [])
-    )},
-    {"new socket with integer timeout", ?_assertMatch(
-      {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 5000, []}}},
-      new(a_fake_socket, [{recv_timeout, 5000}])
-    )},
-    {"new socket with infinity timeout", ?_assertMatch(
-      {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, infinity, []}}},
-      new(a_fake_socket, [{recv_timeout, infinity}])
-    )}
-  ].
-
+    [
+        {"new socket",
+            ?_assertMatch(
+                {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 60000, []}}},
+                new(a_fake_socket)
+            )},
+        {"new socket with no options",
+            ?_assertMatch(
+                {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 60000, []}}},
+                new(a_fake_socket, [])
+            )},
+        {"new socket with integer timeout",
+            ?_assertMatch(
+                {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, 5000, []}}},
+                new(a_fake_socket, [{recv_timeout, 5000}])
+            )},
+        {"new socket with infinity timeout",
+            ?_assertMatch(
+                {ok, {_, thrift_socket_transport, {t_socket, a_fake_socket, infinity, []}}},
+                new(a_fake_socket, [{recv_timeout, infinity}])
+            )}
+    ].
 
 read(Socket, Bytes) -> thrift_socket_transport:read(Socket, Bytes).
 
 read_test_() ->
-  {setup,
-    fun() ->
-      meck:new(gen_tcp, [unstick, passthrough]),
-      meck:expect(gen_tcp, recv, fun(Bin, 0, _) ->
-        case Bin of
-          <<"empty">> -> {error, timeout};
-          _ -> {ok, Bin}
-        end end),
-      meck:expect(gen_tcp, close, fun(_) -> ok end)
-    end,
-    fun(_) -> meck:unload(gen_tcp) end,
-    [
-      {"read zero bytes from empty socket", ?_assertMatch(
-        {_, {ok, <<>>}},
-        read({t_socket, <<>>, 60000, []}, 0)
-      )},
-      {"read 1 byte from empty socket", ?_assertMatch(
-        {_, {error, timeout}},
-        read({t_socket, <<"empty">>, 60000, []}, 1)
-      )},
-      {"read zero bytes from nonempty socket", ?_assertMatch(
-        {{t_socket, _, _, _}, {ok, <<>>}},
-        read({t_socket, <<"hallo world">>, 60000, []}, 0)
-      )},
-      {"read 1 byte from nonempty socket", ?_assertMatch(
-        {{t_socket, _, _, <<"allo world">>}, {ok, <<"h">>}},
-        read({t_socket, <<"hallo world">>, 60000, []}, 1)
-      )},
-      {"read a zillion bytes from nonempty socket", ?_assertMatch(
-        {{t_socket, _, _, <<"ld">>}, {ok, <<"hallo world world world world wor">>}},
-        read({t_socket, <<"hallo world world world world world">>, 60000, []}, 33)
-      )},
-      {"read 1 byte from previously buffered socket", ?_assertMatch(
-        {{t_socket, _, _, <<"allo">>}, {ok, <<"h">>}},
-        read({t_socket, <<" world">>, 60000, <<"hallo">>}, 1)
-      )},
-      {"read 6 byte from previously buffered socket", ?_assertMatch(
-        {{t_socket, _, _, <<"world">>}, {ok, <<"hallo ">>}},
-        read({t_socket, <<" world">>, 60000, <<"hallo">>}, 6)
-      )},
-      {"read a zillion bytes from previously buffered socket", ?_assertMatch(
-        {{t_socket, _, _, <<"ld">>}, {ok, <<"hallo world world world world wor">>}},
-        read({t_socket, <<" world">>, 60000, <<"hallo">>}, 33)
-      )}
-    ]
-  }.
-
+    {setup,
+        fun() ->
+            meck:new(gen_tcp, [unstick, passthrough]),
+            meck:expect(gen_tcp, recv, fun(Bin, 0, _) ->
+                case Bin of
+                    <<"empty">> -> {error, timeout};
+                    _ -> {ok, Bin}
+                end
+            end),
+            meck:expect(gen_tcp, close, fun(_) -> ok end)
+        end,
+        fun(_) -> meck:unload(gen_tcp) end, [
+            {"read zero bytes from empty socket",
+                ?_assertMatch(
+                    {_, {ok, <<>>}},
+                    read({t_socket, <<>>, 60000, []}, 0)
+                )},
+            {"read 1 byte from empty socket",
+                ?_assertMatch(
+                    {_, {error, timeout}},
+                    read({t_socket, <<"empty">>, 60000, []}, 1)
+                )},
+            {"read zero bytes from nonempty socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, _}, {ok, <<>>}},
+                    read({t_socket, <<"hallo world">>, 60000, []}, 0)
+                )},
+            {"read 1 byte from nonempty socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, <<"allo world">>}, {ok, <<"h">>}},
+                    read({t_socket, <<"hallo world">>, 60000, []}, 1)
+                )},
+            {"read a zillion bytes from nonempty socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, <<"ld">>}, {ok, <<"hallo world world world world wor">>}},
+                    read({t_socket, <<"hallo world world world world world">>, 60000, []}, 33)
+                )},
+            {"read 1 byte from previously buffered socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, <<"allo">>}, {ok, <<"h">>}},
+                    read({t_socket, <<" world">>, 60000, <<"hallo">>}, 1)
+                )},
+            {"read 6 byte from previously buffered socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, <<"world">>}, {ok, <<"hallo ">>}},
+                    read({t_socket, <<" world">>, 60000, <<"hallo">>}, 6)
+                )},
+            {"read a zillion bytes from previously buffered socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, <<"ld">>}, {ok, <<"hallo world world world world wor">>}},
+                    read({t_socket, <<" world">>, 60000, <<"hallo">>}, 33)
+                )}
+        ]}.
 
 read_exact(Socket, Bytes) -> thrift_socket_transport:read_exact(Socket, Bytes).
 
 read_exact_test_() ->
-  {setup,
-    fun() ->
-      meck:new(gen_tcp, [unstick, passthrough]),
-      meck:expect(gen_tcp, recv, fun(Bin, N, _) ->
-        case N of
-          0 -> {ok, Bin};
-          1 -> {ok, <<"h">>};
-          N when N > 2 -> {error, timeout}
-        end
-      end),
-      meck:expect(gen_tcp, close, fun(_) -> ok end)
-    end,
-    fun(_) -> meck:unload(gen_tcp) end,
-    [
-      {"read_exact zero bytes from empty socket", ?_assertMatch(
-        {_, {ok, <<>>}},
-        read_exact({t_socket, <<>>, 60000, []}, 0)
-      )},
-      {"read_exact zero bytes from nonempty socket", ?_assertMatch(
-        {{t_socket, _, _, _}, {ok, <<>>}},
-        read_exact({t_socket, <<"hallo world">>, 60000, []}, 0)
-      )},
-      {"read_exact 1 byte from nonempty socket", ?_assertMatch(
-        {{t_socket, _, _, []}, {ok, <<"h">>}},
-        read_exact({t_socket, <<"hallo world">>, 60000, []}, 1)
-      )},
-      {"read_exact a zillion bytes from nonempty socket", ?_assertMatch(
-        {{t_socket, _, _, []}, {error, timeout}},
-        read_exact({t_socket, <<"hallo world">>, 60000, []}, 65536)
-      )},
-      {"read_exact 1 byte from previously buffered socket", ?_assertMatch(
-        {{t_socket, _, _, <<"allo">>}, {ok, <<"h">>}},
-        read_exact({t_socket, <<" world">>, 60000, <<"hallo">>}, 1)
-      )},
-      {"read_exact 6 byte from previously buffered socket", ?_assertMatch(
-        {{t_socket, _, _, []}, {ok, <<"more h">>}},
-        read_exact({t_socket, <<"hallo">>, 60000, <<"more ">>}, 6)
-      )},
-      {"read_exact a zillion bytes from previously buffered socket", ?_assertMatch(
-        {{t_socket, _, _, <<"hallo">>}, {error, timeout}},
-        read_exact({t_socket, <<" world">>, 60000, <<"hallo">>}, 65536)
-      )}
-    ]
-  }.
-
+    {setup,
+        fun() ->
+            meck:new(gen_tcp, [unstick, passthrough]),
+            meck:expect(gen_tcp, recv, fun(Bin, N, _) ->
+                case N of
+                    0 -> {ok, Bin};
+                    1 -> {ok, <<"h">>};
+                    N when N > 2 -> {error, timeout}
+                end
+            end),
+            meck:expect(gen_tcp, close, fun(_) -> ok end)
+        end,
+        fun(_) -> meck:unload(gen_tcp) end, [
+            {"read_exact zero bytes from empty socket",
+                ?_assertMatch(
+                    {_, {ok, <<>>}},
+                    read_exact({t_socket, <<>>, 60000, []}, 0)
+                )},
+            {"read_exact zero bytes from nonempty socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, _}, {ok, <<>>}},
+                    read_exact({t_socket, <<"hallo world">>, 60000, []}, 0)
+                )},
+            {"read_exact 1 byte from nonempty socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, []}, {ok, <<"h">>}},
+                    read_exact({t_socket, <<"hallo world">>, 60000, []}, 1)
+                )},
+            {"read_exact a zillion bytes from nonempty socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, []}, {error, timeout}},
+                    read_exact({t_socket, <<"hallo world">>, 60000, []}, 65536)
+                )},
+            {"read_exact 1 byte from previously buffered socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, <<"allo">>}, {ok, <<"h">>}},
+                    read_exact({t_socket, <<" world">>, 60000, <<"hallo">>}, 1)
+                )},
+            {"read_exact 6 byte from previously buffered socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, []}, {ok, <<"more h">>}},
+                    read_exact({t_socket, <<"hallo">>, 60000, <<"more ">>}, 6)
+                )},
+            {"read_exact a zillion bytes from previously buffered socket",
+                ?_assertMatch(
+                    {{t_socket, _, _, <<"hallo">>}, {error, timeout}},
+                    read_exact({t_socket, <<" world">>, 60000, <<"hallo">>}, 65536)
+                )}
+        ]}.
 
 write(Socket, Data) -> thrift_socket_transport:write(Socket, Data).
 
 write_test_() ->
-  {setup,
-    fun() ->
-      meck:new(gen_tcp, [unstick, passthrough]),
-      meck:expect(gen_tcp, send, fun(_, _) -> ok end)
-    end,
-    fun(_) -> meck:unload(gen_tcp) end,
-    [
-      {"write empty list to socket", ?_assertMatch(
-        {{t_socket, a_fake_socket, 60000, []}, ok},
-        write({t_socket, a_fake_socket, 60000, []}, [])
-      )},
-      {"write empty binary to socket", ?_assertMatch(
-        {{t_socket, a_fake_socket, 60000, []}, ok},
-        write({t_socket, a_fake_socket, 60000, []}, <<>>)
-      )},
-      {"write a list to socket", ?_assertMatch(
-        {{t_socket, a_fake_socket, 60000, []}, ok},
-        write({t_socket, a_fake_socket, 60000, []}, "hallo world")
-      )},
-      {"write a binary to socket", ?_assertMatch(
-        {{t_socket, a_fake_socket, 60000, []}, ok},
-        write({t_socket, a_fake_socket, 60000, []}, <<"hallo world">>)
-      )}
-    ]
-  }.
-
+    {setup,
+        fun() ->
+            meck:new(gen_tcp, [unstick, passthrough]),
+            meck:expect(gen_tcp, send, fun(_, _) -> ok end)
+        end,
+        fun(_) -> meck:unload(gen_tcp) end, [
+            {"write empty list to socket",
+                ?_assertMatch(
+                    {{t_socket, a_fake_socket, 60000, []}, ok},
+                    write({t_socket, a_fake_socket, 60000, []}, [])
+                )},
+            {"write empty binary to socket",
+                ?_assertMatch(
+                    {{t_socket, a_fake_socket, 60000, []}, ok},
+                    write({t_socket, a_fake_socket, 60000, []}, <<>>)
+                )},
+            {"write a list to socket",
+                ?_assertMatch(
+                    {{t_socket, a_fake_socket, 60000, []}, ok},
+                    write({t_socket, a_fake_socket, 60000, []}, "hallo world")
+                )},
+            {"write a binary to socket",
+                ?_assertMatch(
+                    {{t_socket, a_fake_socket, 60000, []}, ok},
+                    write({t_socket, a_fake_socket, 60000, []}, <<"hallo world">>)
+                )}
+        ]}.
 
 flush(Transport) -> thrift_socket_transport:flush(Transport).
 
 flush_test_() ->
-  [
-    {"flush socket", ?_assertMatch(
-      {{t_socket, a_fake_socket, 60000, []}, ok},
-      flush({t_socket, a_fake_socket, 60000, []})
-    )}
-  ].
-
+    [
+        {"flush socket",
+            ?_assertMatch(
+                {{t_socket, a_fake_socket, 60000, []}, ok},
+                flush({t_socket, a_fake_socket, 60000, []})
+            )}
+    ].
 
 close(Transport) -> thrift_socket_transport:close(Transport).
 
 close_test_() ->
-  {setup,
-    fun() ->
-      meck:new(gen_tcp, [unstick, passthrough]),
-      meck:expect(gen_tcp, close, fun(_) -> ok end)
-    end,
-    fun(_) -> meck:unload(gen_tcp) end,
-    [
-      {"close membuffer", ?_assertMatch(
-        {{t_socket, a_fake_socket, 60000, []}, ok},
-        close({t_socket, a_fake_socket, 60000, []})
-      )}
-    ]
-  }.
+    {setup,
+        fun() ->
+            meck:new(gen_tcp, [unstick, passthrough]),
+            meck:expect(gen_tcp, close, fun(_) -> ok end)
+        end,
+        fun(_) -> meck:unload(gen_tcp) end, [
+            {"close membuffer",
+                ?_assertMatch(
+                    {{t_socket, a_fake_socket, 60000, []}, ok},
+                    close({t_socket, a_fake_socket, 60000, []})
+                )}
+        ]}.
diff --git a/lib/erl/test/thrift_socket_server_test.erl b/lib/erl/test/thrift_socket_server_test.erl
index 0818b84..0330198 100644
--- a/lib/erl/test/thrift_socket_server_test.erl
+++ b/lib/erl/test/thrift_socket_server_test.erl
@@ -1,49 +1,133 @@
--module (thrift_socket_server_test).
+%%
+%% 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.
+%%
+
+-module(thrift_socket_server_test).
 
 -include_lib("eunit/include/eunit.hrl").
 
--include ("thrift_constants.hrl").
+-include("thrift_constants.hrl").
 
 parse_handler_options_test_() ->
-    CorrectServiceHandlerOptionList = [{?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {"Service1", ?MODULE}, {"Service2", ?MODULE}],
-    MissingErrorHandlerOptionList   = [{"Service1", ?MODULE}, {"Service2", ?MODULE}],
-    WrongService2HandlerOptionList  = [{?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {"Service1", ?MODULE}, {"Service2", "Module"}],
-    WrongServiceKeyOptionList       = [{?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {'service1', ?MODULE}, {"Service2", ?MODULE}],
+    CorrectServiceHandlerOptionList = [
+        {?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {"Service1", ?MODULE}, {"Service2", ?MODULE}
+    ],
+    MissingErrorHandlerOptionList = [{"Service1", ?MODULE}, {"Service2", ?MODULE}],
+    WrongService2HandlerOptionList = [
+        {?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {"Service1", ?MODULE}, {"Service2", "Module"}
+    ],
+    WrongServiceKeyOptionList = [
+        {?MULTIPLEXED_ERROR_HANDLER_KEY, ?MODULE}, {'service1', ?MODULE}, {"Service2", ?MODULE}
+    ],
     CorrectHandlerTestFunction = fun() ->
-        ?assertMatch({thrift_socket_server,_,_,_,_,_,_,_,_,_,_,_,_,_}, thrift_socket_server:parse_options([{handler, CorrectServiceHandlerOptionList}])),
-        {thrift_socket_server,_,_, HandlerList,_,_,_,_,_,_,_,_,_,_} = thrift_socket_server:parse_options([{handler, CorrectServiceHandlerOptionList}]),
-        lists:foreach(fun
-            ({ServiceName, HandlerModule}) ->
-                ?assertMatch({ok, HandlerModule} when is_atom(HandlerModule), thrift_multiplexed_map_wrapper:find(ServiceName, HandlerList))
-        end, CorrectServiceHandlerOptionList)
+        ?assertMatch(
+            #{},
+            thrift_socket_server:parse_options([{handler, CorrectServiceHandlerOptionList}])
+        ),
+        #{handler := HandlerList} = thrift_socket_server:parse_options(
+            [
+                {handler, CorrectServiceHandlerOptionList}
+            ]
+        ),
+        lists:foreach(
+            fun({ServiceName, HandlerModule}) ->
+                ?assertMatch(
+                    {ok, HandlerModule} when is_atom(HandlerModule),
+                    thrift_multiplexed_map_wrapper:find(ServiceName, HandlerList)
+                )
+            end,
+            CorrectServiceHandlerOptionList
+        )
     end,
     [
-     {"Bad argument for the handler option", ?_assertThrow(_, thrift_socket_server:parse_options([{handler, []}]))},
-     {"Try to parse the handler option twice", ?_assertThrow(_, thrift_socket_server:parse_options([{handler, ?MODULE}, {handler, CorrectServiceHandlerOptionList}]))},
-     {"Parse the handler option as a non multiplexed service handler", ?_assertMatch({thrift_socket_server,_,_,?MODULE,_,_,_,_,_,_,_,_,_,_}, thrift_socket_server:parse_options([{handler, ?MODULE}]))},
-     {"No error handler was defined", ?_assertThrow(_, thrift_socket_server:parse_options([{handler, MissingErrorHandlerOptionList}]))},
-     {"Bad handler module for Service2", ?_assertThrow(_, thrift_socket_server:parse_options([{handler, WrongService2HandlerOptionList}]))},
-     {"Bad service key for Service1", ?_assertThrow(_, thrift_socket_server:parse_options([{handler, WrongServiceKeyOptionList}]))},
-     {"Try to parse a correct handler option list", CorrectHandlerTestFunction}
+        {"Bad argument for the handler option",
+            ?_assertThrow(_, thrift_socket_server:parse_options([{handler, []}]))},
+        {"Try to parse the handler option twice",
+            ?_assertThrow(
+                _,
+                thrift_socket_server:parse_options([
+                    {handler, ?MODULE}, {handler, CorrectServiceHandlerOptionList}
+                ])
+            )},
+        {"Parse the handler option as a non multiplexed service handler",
+            ?_assertMatch(
+                #{handler := ?MODULE},
+                thrift_socket_server:parse_options([{handler, ?MODULE}])
+            )},
+        {"No error handler was defined",
+            ?_assertThrow(
+                _, thrift_socket_server:parse_options([{handler, MissingErrorHandlerOptionList}])
+            )},
+        {"Bad handler module for Service2",
+            ?_assertThrow(
+                _, thrift_socket_server:parse_options([{handler, WrongService2HandlerOptionList}])
+            )},
+        {"Bad service key for Service1",
+            ?_assertThrow(
+                _, thrift_socket_server:parse_options([{handler, WrongServiceKeyOptionList}])
+            )},
+        {"Try to parse a correct handler option list", CorrectHandlerTestFunction}
     ].
 
 parse_service_options_test_() ->
     CorrectServiceModuleOptionList = [{"Service1", ?MODULE}, {"Service2", ?MODULE}],
-    WrongService2ModuleOptionList  = [{"Service1", ?MODULE}, {"Service2", "thrift_service_module"}],
-    WrongServiceKeyOptionList       = [{'service1', ?MODULE}, {"Service2", ?MODULE}],
+    WrongService2ModuleOptionList = [{"Service1", ?MODULE}, {"Service2", "thrift_service_module"}],
+    WrongServiceKeyOptionList = [{'service1', ?MODULE}, {"Service2", ?MODULE}],
     CorrectServiceModuleTestFunction = fun() ->
-        ?assertMatch({thrift_socket_server,_,_,_,_,_,_,_,_,_,_,_,_,_}, thrift_socket_server:parse_options([{service, CorrectServiceModuleOptionList}])),
-        {thrift_socket_server,_, ServiceModuleList,_,_,_,_,_,_,_,_,_,_,_} = thrift_socket_server:parse_options([{service, CorrectServiceModuleOptionList}]),
-        lists:foreach(fun
-            ({ServiceName, ServiceModule}) ->
-                ?assertMatch({ok, ServiceModule} when is_atom(ServiceModule), thrift_multiplexed_map_wrapper:find(ServiceName, ServiceModuleList))
-        end, CorrectServiceModuleOptionList)
+        ?assertMatch(
+            #{},
+            thrift_socket_server:parse_options([{service, CorrectServiceModuleOptionList}])
+        ),
+        #{service := ServiceModuleList} = thrift_socket_server:parse_options(
+            [{service, CorrectServiceModuleOptionList}]
+        ),
+        lists:foreach(
+            fun({ServiceName, ServiceModule}) ->
+                ?assertMatch(
+                    {ok, ServiceModule} when is_atom(ServiceModule),
+                    thrift_multiplexed_map_wrapper:find(ServiceName, ServiceModuleList)
+                )
+            end,
+            CorrectServiceModuleOptionList
+        )
     end,
     [
-     {"Bad argument for the service option", ?_assertThrow(_, thrift_socket_server:parse_options([{service, []}]))},
-     {"Try to parse the service option twice", ?_assertThrow(_, thrift_socket_server:parse_options([{service, ?MODULE}, {service, CorrectServiceModuleOptionList}]))},
-     {"Parse a service module for a non multiplexed service", ?_assertMatch({thrift_socket_server,_,?MODULE,_,_,_,_,_,_,_,_,_,_,_}, thrift_socket_server:parse_options([{service, ?MODULE}]))},
-     {"Bad service module for Service2", ?_assertThrow(_, thrift_socket_server:parse_options([{service, WrongService2ModuleOptionList}]))},
-     {"Bad service key for Service1", ?_assertThrow(_, thrift_socket_server:parse_options([{service, WrongServiceKeyOptionList}]))},
-     {"Try to parse a correct service option list", CorrectServiceModuleTestFunction}
+        {"Bad argument for the service option",
+            ?_assertThrow(_, thrift_socket_server:parse_options([{service, []}]))},
+        {"Try to parse the service option twice",
+            ?_assertThrow(
+                _,
+                thrift_socket_server:parse_options([
+                    {service, ?MODULE}, {service, CorrectServiceModuleOptionList}
+                ])
+            )},
+        {"Parse a service module for a non multiplexed service",
+            ?_assertMatch(
+                #{service := ?MODULE},
+                thrift_socket_server:parse_options([{service, ?MODULE}])
+            )},
+        {"Bad service module for Service2",
+            ?_assertThrow(
+                _, thrift_socket_server:parse_options([{service, WrongService2ModuleOptionList}])
+            )},
+        {"Bad service key for Service1",
+            ?_assertThrow(
+                _, thrift_socket_server:parse_options([{service, WrongServiceKeyOptionList}])
+            )},
+        {"Try to parse a correct service option list", CorrectServiceModuleTestFunction}
     ].
diff --git a/lib/erl/test/thrift_test_test.erl b/lib/erl/test/thrift_test_test.erl
index 77df61d..f86627b 100644
--- a/lib/erl/test/thrift_test_test.erl
+++ b/lib/erl/test/thrift_test_test.erl
@@ -19,625 +19,768 @@
 
 % don't rename this thrift_test, it clobbers generated files
 -module(thrift_test_test).
--compile(export_all).
 
 -include_lib("eunit/include/eunit.hrl").
 
 -include("gen-erl/thrift_test_constants.hrl").
 
 constant_test_() ->
-  [
-    {"myNumberz equals 1", ?_assertEqual(1, ?THRIFT_TEST_MYNUMBERZ)}
-  ].
+    [
+        {"myNumberz equals 1", ?_assertEqual(1, ?THRIFT_TEST_MYNUMBERZ)}
+    ].
 
 record_generation_test_() ->
-  [
-    {"Bonk record", ?_assertMatch(
-      {'thrift.test.Bonk', _, _},
-      #'thrift.test.Bonk'{message=null,type=null}
-    )},
-    {"Bools record", ?_assertMatch(
-      {'thrift.test.Bools', _, _},
-      #'thrift.test.Bools'{im_true=null,im_false=null}
-    )},
-    {"Xtruct record", ?_assertMatch(
-      {'thrift.test.Xtruct', _, _, _, _},
-      #'thrift.test.Xtruct'{string_thing=null,byte_thing=null,i32_thing=null,i64_thing=null}
-    )},
-    {"Xtruct2 record", ?_assertMatch(
-      {'thrift.test.Xtruct2', _, _, _},
-      #'thrift.test.Xtruct2'{byte_thing=null,struct_thing=null,i32_thing=null}
-    )},
-    {"Xtruct3 record", ?_assertMatch(
-      {'thrift.test.Xtruct3', _, _, _, _},
-      #'thrift.test.Xtruct3'{string_thing=null,changed=null,i32_thing=null,i64_thing=null}
-    )},
-    {"Insanity record", ?_assertMatch(
-      {'thrift.test.Insanity', _, _},
-      #'thrift.test.Insanity'{userMap=null,xtructs=null}
-    )},
-    {"CrazyNesting record", ?_assertMatch(
-      {'thrift.test.CrazyNesting', _, _, _, _},
-      #'thrift.test.CrazyNesting'{
-        string_field=null,
-        set_field=null,
-        list_field=null,
-        binary_field=null
-      }
-    )},
-    {"Xception record", ?_assertMatch(
-      {'thrift.test.Xception', _, _},
-      #'thrift.test.Xception'{errorCode=null,message=null}
-    )},
-    {"Xception2 record", ?_assertMatch(
-      {'thrift.test.Xception2', _, _},
-      #'thrift.test.Xception2'{errorCode=null,struct_thing=null}
-    )},
-    {"EmptyStruct record", ?_assertMatch({'thrift.test.EmptyStruct'}, #'thrift.test.EmptyStruct'{})},
-    {"OneField record", ?_assertMatch({'thrift.test.OneField', _}, #'thrift.test.OneField'{field=null})},
-    {"VersioningTestV1 record", ?_assertMatch(
-      {'thrift.test.VersioningTestV1', _, _, _},
-      #'thrift.test.VersioningTestV1'{begin_in_both=null,old_string=null,end_in_both=null}
-    )},
-    {"VersioningTestV2 record", ?_assertMatch(
-      {'thrift.test.VersioningTestV2', _, _, _, _, _, _, _, _, _, _, _, _},
-      #'thrift.test.VersioningTestV2'{
-        begin_in_both=null,
-        newint=null,
-        newbyte=null,
-        newshort=null,
-        newlong=null,
-        newdouble=null,
-        newstruct=null,
-        newlist=null,
-        newset=null,
-        newmap=null,
-        newstring=null,
-        end_in_both=null
-      }
-    )},
-    {"ListTypeVersioningV1 record", ?_assertMatch(
-      {'thrift.test.ListTypeVersioningV1', _, _},
-      #'thrift.test.ListTypeVersioningV1'{myints=null,hello=null}
-    )},
-    {"ListTypeVersioningV2 record", ?_assertMatch(
-      {'thrift.test.ListTypeVersioningV2', _, _},
-      #'thrift.test.ListTypeVersioningV2'{strings=null,hello=null}
-    )},
-    {"GuessProtocolStruct record", ?_assertMatch(
-      {'thrift.test.GuessProtocolStruct', _},
-      #'thrift.test.GuessProtocolStruct'{map_field=null}
-    )},
-    {"LargeDeltas record", ?_assertMatch(
-      {'thrift.test.LargeDeltas', _, _, _, _, _, _, _, _, _, _},
-      #'thrift.test.LargeDeltas'{
-        b1=null,
-        b10=null,
-        b100=null,
-        check_true=null,
-        b1000=null,
-        check_false=null,
-        vertwo2000=null,
-        a_set2500=null,
-        vertwo3000=null,
-        big_numbers=null
-      }
-    )},
-    {"NestedListsI32x2 record", ?_assertMatch(
-      {'thrift.test.NestedListsI32x2', _},
-      #'thrift.test.NestedListsI32x2'{integerlist=null}
-    )},
-    {"NestedListsI32x3 record", ?_assertMatch(
-      {'thrift.test.NestedListsI32x3', _},
-      #'thrift.test.NestedListsI32x3'{integerlist=null}
-    )},
-    {"NestedMixedx2 record", ?_assertMatch(
-      {'thrift.test.NestedMixedx2', _, _, _},
-      #'thrift.test.NestedMixedx2'{
-        int_set_list=null,
-        map_int_strset=null,
-        map_int_strset_list=null
-      }
-    )},
-    {"ListBonks record", ?_assertMatch({'thrift.test.ListBonks', _}, #'thrift.test.ListBonks'{bonk=null})},
-    {"NestedListsBonk record", ?_assertMatch(
-      {'thrift.test.NestedListsBonk', _},
-      #'thrift.test.NestedListsBonk'{bonk=null}
-    )},
-    {"BoolTest record", ?_assertMatch(
-      {'thrift.test.BoolTest', _, _},
-      #'thrift.test.BoolTest'{b=null,s=null}
-    )},
-    {"StructA record", ?_assertMatch({'thrift.test.StructA', _}, #'thrift.test.StructA'{s=null})},
-    {"StructB record", ?_assertMatch(
-      {'thrift.test.StructB', _, _},
-      #'thrift.test.StructB'{aa=null,ab=null}
-    )}
-  ].
+    [
+        {"Bonk record",
+            ?_assertMatch(
+                {'thrift.test.Bonk', _, _},
+                #'thrift.test.Bonk'{message = null, type = null}
+            )},
+        {"Bools record",
+            ?_assertMatch(
+                {'thrift.test.Bools', _, _},
+                #'thrift.test.Bools'{im_true = null, im_false = null}
+            )},
+        {"Xtruct record",
+            ?_assertMatch(
+                {'thrift.test.Xtruct', _, _, _, _},
+                #'thrift.test.Xtruct'{
+                    string_thing = null, byte_thing = null, i32_thing = null, i64_thing = null
+                }
+            )},
+        {"Xtruct2 record",
+            ?_assertMatch(
+                {'thrift.test.Xtruct2', _, _, _},
+                #'thrift.test.Xtruct2'{byte_thing = null, struct_thing = null, i32_thing = null}
+            )},
+        {"Xtruct3 record",
+            ?_assertMatch(
+                {'thrift.test.Xtruct3', _, _, _, _},
+                #'thrift.test.Xtruct3'{
+                    string_thing = null, changed = null, i32_thing = null, i64_thing = null
+                }
+            )},
+        {"Insanity record",
+            ?_assertMatch(
+                {'thrift.test.Insanity', _, _},
+                #'thrift.test.Insanity'{userMap = null, xtructs = null}
+            )},
+        {"CrazyNesting record",
+            ?_assertMatch(
+                {'thrift.test.CrazyNesting', _, _, _, _},
+                #'thrift.test.CrazyNesting'{
+                    string_field = null,
+                    set_field = null,
+                    list_field = null,
+                    binary_field = null
+                }
+            )},
+        {"Xception record",
+            ?_assertMatch(
+                {'thrift.test.Xception', _, _},
+                #'thrift.test.Xception'{errorCode = null, message = null}
+            )},
+        {"Xception2 record",
+            ?_assertMatch(
+                {'thrift.test.Xception2', _, _},
+                #'thrift.test.Xception2'{errorCode = null, struct_thing = null}
+            )},
+        {"EmptyStruct record",
+            ?_assertMatch({'thrift.test.EmptyStruct'}, #'thrift.test.EmptyStruct'{})},
+        {"OneField record",
+            ?_assertMatch({'thrift.test.OneField', _}, #'thrift.test.OneField'{field = null})},
+        {"VersioningTestV1 record",
+            ?_assertMatch(
+                {'thrift.test.VersioningTestV1', _, _, _},
+                #'thrift.test.VersioningTestV1'{
+                    begin_in_both = null, old_string = null, end_in_both = null
+                }
+            )},
+        {"VersioningTestV2 record",
+            ?_assertMatch(
+                {'thrift.test.VersioningTestV2', _, _, _, _, _, _, _, _, _, _, _, _},
+                #'thrift.test.VersioningTestV2'{
+                    begin_in_both = null,
+                    newint = null,
+                    newbyte = null,
+                    newshort = null,
+                    newlong = null,
+                    newdouble = null,
+                    newstruct = null,
+                    newlist = null,
+                    newset = null,
+                    newmap = null,
+                    newstring = null,
+                    end_in_both = null
+                }
+            )},
+        {"ListTypeVersioningV1 record",
+            ?_assertMatch(
+                {'thrift.test.ListTypeVersioningV1', _, _},
+                #'thrift.test.ListTypeVersioningV1'{myints = null, hello = null}
+            )},
+        {"ListTypeVersioningV2 record",
+            ?_assertMatch(
+                {'thrift.test.ListTypeVersioningV2', _, _},
+                #'thrift.test.ListTypeVersioningV2'{strings = null, hello = null}
+            )},
+        {"GuessProtocolStruct record",
+            ?_assertMatch(
+                {'thrift.test.GuessProtocolStruct', _},
+                #'thrift.test.GuessProtocolStruct'{map_field = null}
+            )},
+        {"LargeDeltas record",
+            ?_assertMatch(
+                {'thrift.test.LargeDeltas', _, _, _, _, _, _, _, _, _, _},
+                #'thrift.test.LargeDeltas'{
+                    b1 = null,
+                    b10 = null,
+                    b100 = null,
+                    check_true = null,
+                    b1000 = null,
+                    check_false = null,
+                    vertwo2000 = null,
+                    a_set2500 = null,
+                    vertwo3000 = null,
+                    big_numbers = null
+                }
+            )},
+        {"NestedListsI32x2 record",
+            ?_assertMatch(
+                {'thrift.test.NestedListsI32x2', _},
+                #'thrift.test.NestedListsI32x2'{integerlist = null}
+            )},
+        {"NestedListsI32x3 record",
+            ?_assertMatch(
+                {'thrift.test.NestedListsI32x3', _},
+                #'thrift.test.NestedListsI32x3'{integerlist = null}
+            )},
+        {"NestedMixedx2 record",
+            ?_assertMatch(
+                {'thrift.test.NestedMixedx2', _, _, _},
+                #'thrift.test.NestedMixedx2'{
+                    int_set_list = null,
+                    map_int_strset = null,
+                    map_int_strset_list = null
+                }
+            )},
+        {"ListBonks record",
+            ?_assertMatch({'thrift.test.ListBonks', _}, #'thrift.test.ListBonks'{bonk = null})},
+        {"NestedListsBonk record",
+            ?_assertMatch(
+                {'thrift.test.NestedListsBonk', _},
+                #'thrift.test.NestedListsBonk'{bonk = null}
+            )},
+        {"BoolTest record",
+            ?_assertMatch(
+                {'thrift.test.BoolTest', _, _},
+                #'thrift.test.BoolTest'{b = null, s = null}
+            )},
+        {"StructA record",
+            ?_assertMatch({'thrift.test.StructA', _}, #'thrift.test.StructA'{s = null})},
+        {"StructB record",
+            ?_assertMatch(
+                {'thrift.test.StructB', _, _},
+                #'thrift.test.StructB'{aa = null, ab = null}
+            )}
+    ].
 
 struct_info_test_() ->
-  [
-    {"Bonk definition (short version)", ?_assertEqual(
-      {struct, [{1, string}, {2, i32}]},
-      thrift_test_types:struct_info('thrift.test.Bonk')
-    )},
-    {"Bonk definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, string, message, undefined},
-        {2, undefined, i32, type, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.Bonk')
-    )},
-    {"Bools definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, bool, im_true, undefined},
-        {2, undefined, bool, im_false, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.Bools')
-    )},
-    {"Xtruct definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, string, string_thing, undefined},
-        {4, undefined, byte, byte_thing, undefined},
-        {9, undefined, i32, i32_thing, undefined},
-        {11, undefined, i64, i64_thing, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.Xtruct')
-    )},
-    {"Xtruct2 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, byte, byte_thing, undefined},
-        {2, undefined, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}}, struct_thing, #'thrift.test.Xtruct'{}},
-        {3, undefined, i32, i32_thing, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.Xtruct2')
-    )},
-    {"Xtruct3 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, string, string_thing, undefined},
-        {4, undefined, i32, changed, undefined},
-        {9, undefined, i32, i32_thing, undefined},
-        {11, undefined, i64, i64_thing, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.Xtruct3')
-    )},
-    {"Insanity definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {map, i32, i64}, userMap, dict:new()},
-        {2, undefined, {list, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}}}, xtructs, []}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.Insanity')
-    )},
-    {"CrazyNesting definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, string, string_field, undefined},
-        {2, optional, {set, {struct, {'thrift_test_types', 'thrift.test.Insanity'}}}, set_field, sets:new()},
-        {3, required, {list, {map,
-          {set, i32},
-          {map, i32, {set, {list, {map, {struct, {'thrift_test_types', 'thrift.test.Insanity'}}, string}}}}
-        }}, list_field, []},
-        {4, undefined, string, binary_field, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.CrazyNesting')
-    )},
-    {"Xception definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, i32, errorCode, undefined},
-        {2, undefined, string, message, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.Xception')
-    )},
-    {"Xception2 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, i32, errorCode, undefined},
-        {2, undefined, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}}, struct_thing, #'thrift.test.Xtruct'{}}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.Xception2')
-    )},
-    {"EmptyStruct definition", ?_assertEqual(
-      {struct, []},
-      thrift_test_types:struct_info_ext('thrift.test.EmptyStruct')
-    )},
-    {"OneField definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {struct, {'thrift_test_types', 'thrift.test.EmptyStruct'}}, field, #'thrift.test.EmptyStruct'{}}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.OneField')
-    )},
-    {"VersioningTestV1 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, i32, begin_in_both, undefined},
-        {3, undefined, string, old_string, undefined},
-        {12, undefined, i32, end_in_both, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.VersioningTestV1')
-    )},
-    {"VersioningTestV2 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, i32, begin_in_both, undefined},
-        {2, undefined, i32, newint, undefined},
-        {3, undefined, byte, newbyte, undefined},
-        {4, undefined, i16, newshort, undefined},
-        {5, undefined, i64, newlong, undefined},
-        {6, undefined, double, newdouble, undefined},
-        {7, undefined, {struct, {thrift_test_types, 'thrift.test.Bonk'}}, newstruct, #'thrift.test.Bonk'{}},
-        {8, undefined, {list, i32}, newlist, []},
-        {9, undefined, {set, i32}, newset, sets:new()},
-        {10, undefined, {map, i32, i32}, newmap, dict:new()},
-        {11, undefined, string, newstring, undefined},
-        {12, undefined, i32, end_in_both, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.VersioningTestV2')
-    )},
-    {"ListTypeVersioningV1 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {list, i32}, myints, []},
-        {2, undefined, string, hello, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.ListTypeVersioningV1')
-    )},
-    {"ListTypeVersioningV2 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {list, string}, strings, []},
-        {2, undefined, string, hello, undefined}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.ListTypeVersioningV2')
-    )},
-    {"GuessProtocolStruct definition", ?_assertEqual(
-      {struct, [
-        {7, undefined, {map, string, string}, map_field, dict:new()}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.GuessProtocolStruct')
-    )},
-    {"LargeDeltas definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b1, #'thrift.test.Bools'{}},
-        {10, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b10, #'thrift.test.Bools'{}},
-        {100, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b100, #'thrift.test.Bools'{}},
-        {500, undefined, bool, check_true, undefined},
-        {1000, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b1000, #'thrift.test.Bools'{}},
-        {1500, undefined, bool, check_false, undefined},
-        {2000, undefined, {struct, {thrift_test_types, 'thrift.test.VersioningTestV2'}}, vertwo2000, #'thrift.test.VersioningTestV2'{}},
-        {2500, undefined, {set, string}, a_set2500, sets:new()},
-        {3000, undefined, {struct, {thrift_test_types, 'thrift.test.VersioningTestV2'}}, vertwo3000, #'thrift.test.VersioningTestV2'{}},
-        {4000, undefined, {list, i32}, big_numbers, []}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.LargeDeltas')
-    )},
-    {"NestedListsI32x2 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {list, {list, i32}}, integerlist, []}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.NestedListsI32x2')
-    )},
-    {"NestedListsI32x3 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {list, {list, {list, i32}}}, integerlist, []}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.NestedListsI32x3')
-    )},
-    {"NestedMixedx2 definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {list, {set, i32}}, int_set_list, []},
-        {2, undefined, {map, i32, {set, string}}, map_int_strset, dict:new()},
-        {3, undefined, {list, {map, i32, {set, string}}}, map_int_strset_list, []}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.NestedMixedx2')
-    )},
-    {"ListBonks definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {list, {struct, {thrift_test_types, 'thrift.test.Bonk'}}}, bonk, []}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.ListBonks')
-    )},
-    {"NestedListsBonk definition", ?_assertEqual(
-      {struct, [
-        {1, undefined, {list, {list, {list, {struct, {thrift_test_types, 'thrift.test.Bonk'}}}}}, bonk, []}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.NestedListsBonk')
-    )},
-    {"BoolTest definition", ?_assertEqual(
-      {struct, [
-        {1, optional, bool, b, true},
-        {2, optional, string, s, "true"}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.BoolTest')
-    )},
-    {"StructA definition", ?_assertEqual(
-      {struct, [{1, required, string, s, undefined}]},
-      thrift_test_types:struct_info_ext('thrift.test.StructA')
-    )},
-    {"StructB definition", ?_assertEqual(
-      {struct, [
-        {1, optional, {struct, {thrift_test_types, 'thrift.test.StructA'}}, aa, #'thrift.test.StructA'{}},
-        {2, required, {struct, {thrift_test_types, 'thrift.test.StructA'}}, ab, #'thrift.test.StructA'{}}
-      ]},
-      thrift_test_types:struct_info_ext('thrift.test.StructB')
-    )}
-  ].
+    [
+        {"Bonk definition (short version)",
+            ?_assertEqual(
+                {struct, [{1, string}, {2, i32}]},
+                thrift_test_types:struct_info('thrift.test.Bonk')
+            )},
+        {"Bonk definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, string, message, undefined},
+                    {2, undefined, i32, type, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.Bonk')
+            )},
+        {"Bools definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, bool, im_true, undefined},
+                    {2, undefined, bool, im_false, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.Bools')
+            )},
+        {"Xtruct definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, string, string_thing, undefined},
+                    {4, undefined, byte, byte_thing, undefined},
+                    {9, undefined, i32, i32_thing, undefined},
+                    {11, undefined, i64, i64_thing, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.Xtruct')
+            )},
+        {"Xtruct2 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, byte, byte_thing, undefined},
+                    {2, undefined, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}},
+                        struct_thing, #'thrift.test.Xtruct'{}},
+                    {3, undefined, i32, i32_thing, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.Xtruct2')
+            )},
+        {"Xtruct3 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, string, string_thing, undefined},
+                    {4, undefined, i32, changed, undefined},
+                    {9, undefined, i32, i32_thing, undefined},
+                    {11, undefined, i64, i64_thing, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.Xtruct3')
+            )},
+        {"Insanity definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {map, i32, i64}, userMap, dict:new()},
+                    {2, undefined, {list, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}}},
+                        xtructs, []}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.Insanity')
+            )},
+        {"CrazyNesting definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, string, string_field, undefined},
+                    {2, optional, {set, {struct, {'thrift_test_types', 'thrift.test.Insanity'}}},
+                        set_field, sets:new()},
+                    {3, required,
+                        {list,
+                            {map, {set, i32},
+                                {map, i32,
+                                    {set,
+                                        {list,
+                                            {map,
+                                                {struct,
+                                                    {'thrift_test_types', 'thrift.test.Insanity'}},
+                                                string}}}}}},
+                        list_field, []},
+                    {4, undefined, string, binary_field, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.CrazyNesting')
+            )},
+        {"Xception definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, i32, errorCode, undefined},
+                    {2, undefined, string, message, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.Xception')
+            )},
+        {"Xception2 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, i32, errorCode, undefined},
+                    {2, undefined, {struct, {'thrift_test_types', 'thrift.test.Xtruct'}},
+                        struct_thing, #'thrift.test.Xtruct'{}}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.Xception2')
+            )},
+        {"EmptyStruct definition",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_types:struct_info_ext('thrift.test.EmptyStruct')
+            )},
+        {"OneField definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {struct, {'thrift_test_types', 'thrift.test.EmptyStruct'}},
+                        field, #'thrift.test.EmptyStruct'{}}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.OneField')
+            )},
+        {"VersioningTestV1 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, i32, begin_in_both, undefined},
+                    {3, undefined, string, old_string, undefined},
+                    {12, undefined, i32, end_in_both, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.VersioningTestV1')
+            )},
+        {"VersioningTestV2 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, i32, begin_in_both, undefined},
+                    {2, undefined, i32, newint, undefined},
+                    {3, undefined, byte, newbyte, undefined},
+                    {4, undefined, i16, newshort, undefined},
+                    {5, undefined, i64, newlong, undefined},
+                    {6, undefined, double, newdouble, undefined},
+                    {7, undefined, {struct, {thrift_test_types, 'thrift.test.Bonk'}}, newstruct,
+                        #'thrift.test.Bonk'{}},
+                    {8, undefined, {list, i32}, newlist, []},
+                    {9, undefined, {set, i32}, newset, sets:new()},
+                    {10, undefined, {map, i32, i32}, newmap, dict:new()},
+                    {11, undefined, string, newstring, undefined},
+                    {12, undefined, i32, end_in_both, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.VersioningTestV2')
+            )},
+        {"ListTypeVersioningV1 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {list, i32}, myints, []},
+                    {2, undefined, string, hello, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.ListTypeVersioningV1')
+            )},
+        {"ListTypeVersioningV2 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {list, string}, strings, []},
+                    {2, undefined, string, hello, undefined}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.ListTypeVersioningV2')
+            )},
+        {"GuessProtocolStruct definition",
+            ?_assertEqual(
+                {struct, [
+                    {7, undefined, {map, string, string}, map_field, dict:new()}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.GuessProtocolStruct')
+            )},
+        {"LargeDeltas definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b1,
+                        #'thrift.test.Bools'{}},
+                    {10, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b10,
+                        #'thrift.test.Bools'{}},
+                    {100, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b100,
+                        #'thrift.test.Bools'{}},
+                    {500, undefined, bool, check_true, undefined},
+                    {1000, undefined, {struct, {thrift_test_types, 'thrift.test.Bools'}}, b1000,
+                        #'thrift.test.Bools'{}},
+                    {1500, undefined, bool, check_false, undefined},
+                    {2000, undefined, {struct, {thrift_test_types, 'thrift.test.VersioningTestV2'}},
+                        vertwo2000, #'thrift.test.VersioningTestV2'{}},
+                    {2500, undefined, {set, string}, a_set2500, sets:new()},
+                    {3000, undefined, {struct, {thrift_test_types, 'thrift.test.VersioningTestV2'}},
+                        vertwo3000, #'thrift.test.VersioningTestV2'{}},
+                    {4000, undefined, {list, i32}, big_numbers, []}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.LargeDeltas')
+            )},
+        {"NestedListsI32x2 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {list, {list, i32}}, integerlist, []}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.NestedListsI32x2')
+            )},
+        {"NestedListsI32x3 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {list, {list, {list, i32}}}, integerlist, []}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.NestedListsI32x3')
+            )},
+        {"NestedMixedx2 definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {list, {set, i32}}, int_set_list, []},
+                    {2, undefined, {map, i32, {set, string}}, map_int_strset, dict:new()},
+                    {3, undefined, {list, {map, i32, {set, string}}}, map_int_strset_list, []}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.NestedMixedx2')
+            )},
+        {"ListBonks definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined, {list, {struct, {thrift_test_types, 'thrift.test.Bonk'}}}, bonk,
+                        []}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.ListBonks')
+            )},
+        {"NestedListsBonk definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, undefined,
+                        {list, {list, {list, {struct, {thrift_test_types, 'thrift.test.Bonk'}}}}},
+                        bonk, []}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.NestedListsBonk')
+            )},
+        {"BoolTest definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, optional, bool, b, true},
+                    {2, optional, string, s, "true"}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.BoolTest')
+            )},
+        {"StructA definition",
+            ?_assertEqual(
+                {struct, [{1, required, string, s, undefined}]},
+                thrift_test_types:struct_info_ext('thrift.test.StructA')
+            )},
+        {"StructB definition",
+            ?_assertEqual(
+                {struct, [
+                    {1, optional, {struct, {thrift_test_types, 'thrift.test.StructA'}}, aa,
+                        #'thrift.test.StructA'{}},
+                    {2, required, {struct, {thrift_test_types, 'thrift.test.StructA'}}, ab,
+                        #'thrift.test.StructA'{}}
+                ]},
+                thrift_test_types:struct_info_ext('thrift.test.StructB')
+            )}
+    ].
 
 service_info_test_() ->
-  [
-    {"testVoid params", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testVoid, params_type)
-    )},
-    {"testVoid reply", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testVoid, reply_type)
-    )},
-    {"testVoid exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testVoid, exceptions)
-    )},
-    {"testString params", ?_assertEqual(
-      {struct, [{1, string}]},
-      thrift_test_thrift:function_info(testString, params_type)
-    )},
-    {"testString reply", ?_assertEqual(
-      string,
-      thrift_test_thrift:function_info(testString, reply_type)
-    )},
-    {"testString exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testString, exceptions)
-    )},
-    {"testByte params", ?_assertEqual(
-      {struct, [{1, byte}]},
-      thrift_test_thrift:function_info(testByte, params_type)
-    )},
-    {"testByte reply", ?_assertEqual(
-      byte,
-      thrift_test_thrift:function_info(testByte, reply_type)
-    )},
-    {"testByte exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testByte, exceptions)
-    )},
-    {"testI32 params", ?_assertEqual(
-      {struct, [{1, i32}]},
-      thrift_test_thrift:function_info(testI32, params_type)
-    )},
-    {"testI32 reply", ?_assertEqual(
-      i32,
-      thrift_test_thrift:function_info(testI32, reply_type)
-    )},
-    {"testI32 exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testI32, exceptions)
-    )},
-    {"testI64 params", ?_assertEqual(
-      {struct, [{1, i64}]},
-      thrift_test_thrift:function_info(testI64, params_type)
-    )},
-    {"testI64 reply", ?_assertEqual(
-      i64,
-      thrift_test_thrift:function_info(testI64, reply_type)
-    )},
-    {"testI64 exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testI64, exceptions)
-    )},
-    {"testDouble params", ?_assertEqual(
-      {struct, [{1, double}]},
-      thrift_test_thrift:function_info(testDouble, params_type)
-    )},
-    {"testDouble reply", ?_assertEqual(
-      double,
-      thrift_test_thrift:function_info(testDouble, reply_type)
-    )},
-    {"testDouble exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testDouble, exceptions)
-    )},
-    {"testStruct params", ?_assertEqual(
-      {struct, [
-        {1, {struct, {thrift_test_types, 'thrift.test.Xtruct'}}}
-      ]},
-      thrift_test_thrift:function_info(testStruct, params_type)
-    )},
-    {"testStruct reply", ?_assertEqual(
-      {struct, {thrift_test_types, 'thrift.test.Xtruct'}},
-      thrift_test_thrift:function_info(testStruct, reply_type)
-    )},
-    {"testStruct exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testStruct, exceptions)
-    )},
-    {"testNest params", ?_assertEqual(
-      {struct, [
-        {1, {struct, {thrift_test_types, 'thrift.test.Xtruct2'}}}
-      ]},
-      thrift_test_thrift:function_info(testNest, params_type)
-    )},
-    {"testNest reply", ?_assertEqual(
-      {struct, {thrift_test_types, 'thrift.test.Xtruct2'}},
-      thrift_test_thrift:function_info(testNest, reply_type)
-    )},
-    {"testNest exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testNest, exceptions)
-    )},
-    {"testMap params", ?_assertEqual(
-      {struct, [
-        {1, {map, i32, i32}}
-      ]},
-      thrift_test_thrift:function_info(testMap, params_type)
-    )},
-    {"testMap reply", ?_assertEqual(
-      {map, i32, i32},
-      thrift_test_thrift:function_info(testMap, reply_type)
-    )},
-    {"testMap exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testMap, exceptions)
-    )},
-    {"testStringMap params", ?_assertEqual(
-      {struct, [
-        {1, {map, string, string}}
-      ]},
-      thrift_test_thrift:function_info(testStringMap, params_type)
-    )},
-    {"testStringMap reply", ?_assertEqual(
-      {map, string, string},
-      thrift_test_thrift:function_info(testStringMap, reply_type)
-    )},
-    {"testStringMap exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testStringMap, exceptions)
-    )},
-    {"testSet params", ?_assertEqual(
-      {struct, [
-        {1, {set, i32}}
-      ]},
-      thrift_test_thrift:function_info(testSet, params_type)
-    )},
-    {"testSet reply", ?_assertEqual(
-      {set, i32},
-      thrift_test_thrift:function_info(testSet, reply_type)
-    )},
-    {"testSet exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testSet, exceptions)
-    )},
-    {"testList params", ?_assertEqual(
-      {struct, [
-        {1, {list, i32}}
-      ]},
-      thrift_test_thrift:function_info(testList, params_type)
-    )},
-    {"testList reply", ?_assertEqual(
-      {list, i32},
-      thrift_test_thrift:function_info(testList, reply_type)
-    )},
-    {"testList exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testList, exceptions)
-    )},
-    {"testEnum params", ?_assertEqual(
-      {struct, [
-        {1, i32}
-      ]},
-      thrift_test_thrift:function_info(testEnum, params_type)
-    )},
-    {"testEnum reply", ?_assertEqual(
-      i32,
-      thrift_test_thrift:function_info(testEnum, reply_type)
-    )},
-    {"testEnum exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testEnum, exceptions)
-    )},
-    {"testTypedef params", ?_assertEqual(
-      {struct, [{1, i64}]},
-      thrift_test_thrift:function_info(testTypedef, params_type)
-    )},
-    {"testTypedef reply", ?_assertEqual(
-      i64,
-      thrift_test_thrift:function_info(testTypedef, reply_type)
-    )},
-    {"testTypedef exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testTypedef, exceptions)
-    )},
-    {"testMapMap params", ?_assertEqual(
-      {struct, [
-        {1, i32}
-      ]},
-      thrift_test_thrift:function_info(testMapMap, params_type)
-    )},
-    {"testMapMap reply", ?_assertEqual(
-      {map, i32, {map, i32,i32}},
-      thrift_test_thrift:function_info(testMapMap, reply_type)
-    )},
-    {"testMapMap exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testMapMap, exceptions)
-    )},
-    {"testInsanity params", ?_assertEqual(
-      {struct, [
-        {1, {struct, {thrift_test_types, 'thrift.test.Insanity'}}}
-      ]},
-      thrift_test_thrift:function_info(testInsanity, params_type)
-    )},
-    {"testInsanity reply", ?_assertEqual(
-      {map, i64, {map, i32, {struct, {'thrift_test_types', 'thrift.test.Insanity'}}}},
-      thrift_test_thrift:function_info(testInsanity, reply_type)
-    )},
-    {"testInsanity exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testInsanity, exceptions)
-    )},
-    {"testMulti params", ?_assertEqual(
-      {struct, [
-        {1, byte},
-        {2, i32},
-        {3, i64},
-        {4, {map, i16, string}},
-        {5, i32},
-        {6, i64}
-      ]},
-      thrift_test_thrift:function_info(testMulti, params_type)
-    )},
-    {"testMulti reply", ?_assertEqual(
-      {struct, {thrift_test_types, 'thrift.test.Xtruct'}},
-      thrift_test_thrift:function_info(testMulti, reply_type)
-    )},
-    {"testMulti exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testMulti, exceptions)
-    )},
-    {"testException params", ?_assertEqual(
-      {struct, [{1, string}]},
-      thrift_test_thrift:function_info(testException, params_type)
-    )},
-    {"testException reply", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testException, reply_type)
-    )},
-    {"testException exceptions", ?_assertEqual(
-      {struct, [
-        {1, {struct, {thrift_test_types, 'thrift.test.Xception'}}}
-      ]},
-      thrift_test_thrift:function_info(testException, exceptions)
-    )},
-    {"testMultiException params", ?_assertEqual(
-      {struct, [{1, string}, {2, string}]},
-      thrift_test_thrift:function_info(testMultiException, params_type)
-    )},
-    {"testMultiException reply", ?_assertEqual(
-      {struct, {thrift_test_types, 'thrift.test.Xtruct'}},
-      thrift_test_thrift:function_info(testMultiException, reply_type)
-    )},
-    {"testMultiException exceptions", ?_assertEqual(
-      {struct, [
-        {1, {struct, {thrift_test_types, 'thrift.test.Xception'}}},
-        {2, {struct, {thrift_test_types, 'thrift.test.Xception2'}}}
-      ]},
-      thrift_test_thrift:function_info(testMultiException, exceptions)
-    )},
-    {"testOneway params", ?_assertEqual(
-      {struct, [{1, i32}]},
-      thrift_test_thrift:function_info(testOneway, params_type)
-    )},
-    {"testOneway reply", ?_assertEqual(
-      oneway_void,
-      thrift_test_thrift:function_info(testOneway, reply_type)
-    )},
-    {"testOneway exceptions", ?_assertEqual(
-      {struct, []},
-      thrift_test_thrift:function_info(testOneway, exceptions)
-    )},
-    {"secondtestString params", ?_assertEqual(
-      {struct, [{1, string}]},
-      second_service_thrift:function_info(secondtestString, params_type)
-    )},
-    {"secondtestString reply", ?_assertEqual(
-      string,
-      second_service_thrift:function_info(secondtestString, reply_type)
-    )},
-    {"secondtestString exceptions", ?_assertEqual(
-      {struct, []},
-      second_service_thrift:function_info(secondtestString, exceptions)
-    )}
-  ].
+    [
+        {"testVoid params",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testVoid, params_type)
+            )},
+        {"testVoid reply",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testVoid, reply_type)
+            )},
+        {"testVoid exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testVoid, exceptions)
+            )},
+        {"testString params",
+            ?_assertEqual(
+                {struct, [{1, string}]},
+                thrift_test_thrift:function_info(testString, params_type)
+            )},
+        {"testString reply",
+            ?_assertEqual(
+                string,
+                thrift_test_thrift:function_info(testString, reply_type)
+            )},
+        {"testString exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testString, exceptions)
+            )},
+        {"testByte params",
+            ?_assertEqual(
+                {struct, [{1, byte}]},
+                thrift_test_thrift:function_info(testByte, params_type)
+            )},
+        {"testByte reply",
+            ?_assertEqual(
+                byte,
+                thrift_test_thrift:function_info(testByte, reply_type)
+            )},
+        {"testByte exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testByte, exceptions)
+            )},
+        {"testI32 params",
+            ?_assertEqual(
+                {struct, [{1, i32}]},
+                thrift_test_thrift:function_info(testI32, params_type)
+            )},
+        {"testI32 reply",
+            ?_assertEqual(
+                i32,
+                thrift_test_thrift:function_info(testI32, reply_type)
+            )},
+        {"testI32 exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testI32, exceptions)
+            )},
+        {"testI64 params",
+            ?_assertEqual(
+                {struct, [{1, i64}]},
+                thrift_test_thrift:function_info(testI64, params_type)
+            )},
+        {"testI64 reply",
+            ?_assertEqual(
+                i64,
+                thrift_test_thrift:function_info(testI64, reply_type)
+            )},
+        {"testI64 exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testI64, exceptions)
+            )},
+        {"testDouble params",
+            ?_assertEqual(
+                {struct, [{1, double}]},
+                thrift_test_thrift:function_info(testDouble, params_type)
+            )},
+        {"testDouble reply",
+            ?_assertEqual(
+                double,
+                thrift_test_thrift:function_info(testDouble, reply_type)
+            )},
+        {"testDouble exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testDouble, exceptions)
+            )},
+        {"testStruct params",
+            ?_assertEqual(
+                {struct, [
+                    {1, {struct, {thrift_test_types, 'thrift.test.Xtruct'}}}
+                ]},
+                thrift_test_thrift:function_info(testStruct, params_type)
+            )},
+        {"testStruct reply",
+            ?_assertEqual(
+                {struct, {thrift_test_types, 'thrift.test.Xtruct'}},
+                thrift_test_thrift:function_info(testStruct, reply_type)
+            )},
+        {"testStruct exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testStruct, exceptions)
+            )},
+        {"testNest params",
+            ?_assertEqual(
+                {struct, [
+                    {1, {struct, {thrift_test_types, 'thrift.test.Xtruct2'}}}
+                ]},
+                thrift_test_thrift:function_info(testNest, params_type)
+            )},
+        {"testNest reply",
+            ?_assertEqual(
+                {struct, {thrift_test_types, 'thrift.test.Xtruct2'}},
+                thrift_test_thrift:function_info(testNest, reply_type)
+            )},
+        {"testNest exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testNest, exceptions)
+            )},
+        {"testMap params",
+            ?_assertEqual(
+                {struct, [
+                    {1, {map, i32, i32}}
+                ]},
+                thrift_test_thrift:function_info(testMap, params_type)
+            )},
+        {"testMap reply",
+            ?_assertEqual(
+                {map, i32, i32},
+                thrift_test_thrift:function_info(testMap, reply_type)
+            )},
+        {"testMap exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testMap, exceptions)
+            )},
+        {"testStringMap params",
+            ?_assertEqual(
+                {struct, [
+                    {1, {map, string, string}}
+                ]},
+                thrift_test_thrift:function_info(testStringMap, params_type)
+            )},
+        {"testStringMap reply",
+            ?_assertEqual(
+                {map, string, string},
+                thrift_test_thrift:function_info(testStringMap, reply_type)
+            )},
+        {"testStringMap exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testStringMap, exceptions)
+            )},
+        {"testSet params",
+            ?_assertEqual(
+                {struct, [
+                    {1, {set, i32}}
+                ]},
+                thrift_test_thrift:function_info(testSet, params_type)
+            )},
+        {"testSet reply",
+            ?_assertEqual(
+                {set, i32},
+                thrift_test_thrift:function_info(testSet, reply_type)
+            )},
+        {"testSet exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testSet, exceptions)
+            )},
+        {"testList params",
+            ?_assertEqual(
+                {struct, [
+                    {1, {list, i32}}
+                ]},
+                thrift_test_thrift:function_info(testList, params_type)
+            )},
+        {"testList reply",
+            ?_assertEqual(
+                {list, i32},
+                thrift_test_thrift:function_info(testList, reply_type)
+            )},
+        {"testList exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testList, exceptions)
+            )},
+        {"testEnum params",
+            ?_assertEqual(
+                {struct, [
+                    {1, i32}
+                ]},
+                thrift_test_thrift:function_info(testEnum, params_type)
+            )},
+        {"testEnum reply",
+            ?_assertEqual(
+                i32,
+                thrift_test_thrift:function_info(testEnum, reply_type)
+            )},
+        {"testEnum exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testEnum, exceptions)
+            )},
+        {"testTypedef params",
+            ?_assertEqual(
+                {struct, [{1, i64}]},
+                thrift_test_thrift:function_info(testTypedef, params_type)
+            )},
+        {"testTypedef reply",
+            ?_assertEqual(
+                i64,
+                thrift_test_thrift:function_info(testTypedef, reply_type)
+            )},
+        {"testTypedef exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testTypedef, exceptions)
+            )},
+        {"testMapMap params",
+            ?_assertEqual(
+                {struct, [
+                    {1, i32}
+                ]},
+                thrift_test_thrift:function_info(testMapMap, params_type)
+            )},
+        {"testMapMap reply",
+            ?_assertEqual(
+                {map, i32, {map, i32, i32}},
+                thrift_test_thrift:function_info(testMapMap, reply_type)
+            )},
+        {"testMapMap exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testMapMap, exceptions)
+            )},
+        {"testInsanity params",
+            ?_assertEqual(
+                {struct, [
+                    {1, {struct, {thrift_test_types, 'thrift.test.Insanity'}}}
+                ]},
+                thrift_test_thrift:function_info(testInsanity, params_type)
+            )},
+        {"testInsanity reply",
+            ?_assertEqual(
+                {map, i64, {map, i32, {struct, {'thrift_test_types', 'thrift.test.Insanity'}}}},
+                thrift_test_thrift:function_info(testInsanity, reply_type)
+            )},
+        {"testInsanity exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testInsanity, exceptions)
+            )},
+        {"testMulti params",
+            ?_assertEqual(
+                {struct, [
+                    {1, byte},
+                    {2, i32},
+                    {3, i64},
+                    {4, {map, i16, string}},
+                    {5, i32},
+                    {6, i64}
+                ]},
+                thrift_test_thrift:function_info(testMulti, params_type)
+            )},
+        {"testMulti reply",
+            ?_assertEqual(
+                {struct, {thrift_test_types, 'thrift.test.Xtruct'}},
+                thrift_test_thrift:function_info(testMulti, reply_type)
+            )},
+        {"testMulti exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testMulti, exceptions)
+            )},
+        {"testException params",
+            ?_assertEqual(
+                {struct, [{1, string}]},
+                thrift_test_thrift:function_info(testException, params_type)
+            )},
+        {"testException reply",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testException, reply_type)
+            )},
+        {"testException exceptions",
+            ?_assertEqual(
+                {struct, [
+                    {1, {struct, {thrift_test_types, 'thrift.test.Xception'}}}
+                ]},
+                thrift_test_thrift:function_info(testException, exceptions)
+            )},
+        {"testMultiException params",
+            ?_assertEqual(
+                {struct, [{1, string}, {2, string}]},
+                thrift_test_thrift:function_info(testMultiException, params_type)
+            )},
+        {"testMultiException reply",
+            ?_assertEqual(
+                {struct, {thrift_test_types, 'thrift.test.Xtruct'}},
+                thrift_test_thrift:function_info(testMultiException, reply_type)
+            )},
+        {"testMultiException exceptions",
+            ?_assertEqual(
+                {struct, [
+                    {1, {struct, {thrift_test_types, 'thrift.test.Xception'}}},
+                    {2, {struct, {thrift_test_types, 'thrift.test.Xception2'}}}
+                ]},
+                thrift_test_thrift:function_info(testMultiException, exceptions)
+            )},
+        {"testOneway params",
+            ?_assertEqual(
+                {struct, [{1, i32}]},
+                thrift_test_thrift:function_info(testOneway, params_type)
+            )},
+        {"testOneway reply",
+            ?_assertEqual(
+                oneway_void,
+                thrift_test_thrift:function_info(testOneway, reply_type)
+            )},
+        {"testOneway exceptions",
+            ?_assertEqual(
+                {struct, []},
+                thrift_test_thrift:function_info(testOneway, exceptions)
+            )},
+        {"secondtestString params",
+            ?_assertEqual(
+                {struct, [{1, string}]},
+                second_service_thrift:function_info(secondtestString, params_type)
+            )},
+        {"secondtestString reply",
+            ?_assertEqual(
+                string,
+                second_service_thrift:function_info(secondtestString, reply_type)
+            )},
+        {"secondtestString exceptions",
+            ?_assertEqual(
+                {struct, []},
+                second_service_thrift:function_info(secondtestString, exceptions)
+            )}
+    ].
diff --git a/lib/haxe/haxelib.json b/lib/haxe/haxelib.json
index c2dab34..78779da 100644
--- a/lib/haxe/haxelib.json
+++ b/lib/haxe/haxelib.json
@@ -10,7 +10,7 @@
 		"framework"
 	],
 	"description": "Haxe bindings for the Apache Thrift RPC and serialization framework",
-	"version": "0.19.0",
+	"version": "0.20.0",
 	"releasenote": "Licensed under Apache License, Version 2.0. The Apache Thrift compiler needs to be installed separately.",
 	"contributors": ["ApacheThrift"],
 	"dependencies": { 
diff --git a/lib/java/build.gradle b/lib/java/build.gradle
index 41083d0..f5c3d66 100644
--- a/lib/java/build.gradle
+++ b/lib/java/build.gradle
@@ -41,8 +41,8 @@
     id 'signing'
     id 'pmd'
     id 'com.github.johnrengelman.shadow' version '8.1.1'
-    id "com.github.spotbugs" version "5.0.14"
-    id "com.diffplug.spotless" version "6.19.0"
+    id "com.github.spotbugs" version "5.1.3"
+    id "com.diffplug.spotless" version "6.21.0"
 }
 
 description = 'Apache Thrift Java Library'
diff --git a/lib/java/gradle.properties b/lib/java/gradle.properties
index 2e3d041..404318b 100644
--- a/lib/java/gradle.properties
+++ b/lib/java/gradle.properties
@@ -1,7 +1,7 @@
 # This file is shared currently between this Gradle build and the
 # Ant builds for fd303 and JavaScript. Keep the dotted notation for
 # the properties to minimize the changes in the dependencies.
-thrift.version=0.19.0
+thrift.version=0.20.0
 thrift.groupid=org.apache.thrift
 release=false
 
diff --git a/lib/js/package-lock.json b/lib/js/package-lock.json
index cbd36f5..5559790 100644
--- a/lib/js/package-lock.json
+++ b/lib/js/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.19.0",
+  "version": "0.20.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
diff --git a/lib/js/package.json b/lib/js/package.json
index 57b4bb2..8543b25 100644
--- a/lib/js/package.json
+++ b/lib/js/package.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.19.0",
+  "version": "0.20.0",
   "description": "Thrift is a software framework for scalable cross-language services development.",
   "main": "./src/thrift",
   "author": {
diff --git a/lib/js/src/thrift.js b/lib/js/src/thrift.js
index 78fdfb2..7dbb560 100644
--- a/lib/js/src/thrift.js
+++ b/lib/js/src/thrift.js
@@ -46,7 +46,7 @@
      * @const {string} Version
      * @memberof Thrift
      */
-    Version: '0.19.0',
+    Version: '0.20.0',
 
     /**
      * Thrift IDL type string to Id mapping.
diff --git a/lib/kotlin/build.gradle.kts b/lib/kotlin/build.gradle.kts
index 754df89..5c9929b 100644
--- a/lib/kotlin/build.gradle.kts
+++ b/lib/kotlin/build.gradle.kts
@@ -29,7 +29,7 @@
 dependencies {
     implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
     implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
-    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.1")
+    implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.7.3")
     implementation("org.apache.thrift:libthrift:INCLUDED")
     testImplementation(kotlin("test"))
 }
diff --git a/lib/lua/Thrift.lua b/lib/lua/Thrift.lua
index c249278..1f9a562 100644
--- a/lib/lua/Thrift.lua
+++ b/lib/lua/Thrift.lua
@@ -48,7 +48,7 @@
   return count
 end
 
-version = '0.19.0'
+version = '0.20.0'
 
 TType = {
   STOP   = 0,
diff --git a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj
index aed36cd..b5afef5 100644
--- a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj
+++ b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj
@@ -27,7 +27,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="BenchmarkDotNet" Version="0.13.4" />
+    <PackageReference Include="BenchmarkDotNet" Version="0.13.6" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
index 19065c6..98e8007 100644
--- a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
+++ b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
@@ -22,7 +22,7 @@
     <TargetFramework>net7.0</TargetFramework>
     <AssemblyName>Thrift.IntegrationTests</AssemblyName>
     <PackageId>Thrift.IntegrationTests</PackageId>
-    <Version>0.19.0.0</Version>
+    <Version>0.20.0.0</Version>
     <OutputType>Exe</OutputType>
     <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
     <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
@@ -35,10 +35,10 @@
 
   <ItemGroup>
     <PackageReference Include="CompareNETObjects" Version="4.79.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
-    <PackageReference Include="MSTest.TestAdapter" Version="3.0.2" />
-    <PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.10.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
+    <PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
+    <PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="6.0.0" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
index 990b240..6f3abb1 100644
--- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
@@ -19,7 +19,7 @@
   -->
 
   <PropertyGroup>
-    <ThriftVersion>0.19.0</ThriftVersion>
+    <ThriftVersion>0.20.0</ThriftVersion>
     <ThriftVersionOutput>Thrift version $(ThriftVersion)</ThriftVersionOutput>
     <TargetFramework>net7.0</TargetFramework>
     <Version>$(ThriftVersion).0</Version>
@@ -37,7 +37,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.10.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="6.0.0" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
index bae55ea..94b7b09 100644
--- a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
+++ b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
@@ -20,15 +20,15 @@
 
   <PropertyGroup>
     <TargetFramework>net7.0</TargetFramework>
-    <Version>0.19.0.0</Version>
+    <Version>0.20.0.0</Version>
     <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>
     <PackageReference Include="CompareNETObjects" Version="4.79.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
-    <PackageReference Include="MSTest.TestAdapter" Version="3.0.2" />
-    <PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.3" />
+    <PackageReference Include="MSTest.TestAdapter" Version="3.1.1" />
+    <PackageReference Include="MSTest.TestFramework" Version="3.1.1" />
     <PackageReference Include="NSubstitute" Version="5.0.0" />
   </ItemGroup>
 
diff --git a/lib/netstd/Thrift/Properties/AssemblyInfo.cs b/lib/netstd/Thrift/Properties/AssemblyInfo.cs
index 3dd0cc6..bd84c4e 100644
--- a/lib/netstd/Thrift/Properties/AssemblyInfo.cs
+++ b/lib/netstd/Thrift/Properties/AssemblyInfo.cs
@@ -52,5 +52,5 @@
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 
-[assembly: AssemblyVersion("0.19.0.0")]
-[assembly: AssemblyFileVersion("0.19.0.0")]
+[assembly: AssemblyVersion("0.20.0.0")]
+[assembly: AssemblyFileVersion("0.20.0.0")]
diff --git a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
index 82e758b..9f761ae 100644
--- a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
@@ -435,11 +435,11 @@
                     // escaped?
                     if (ch != TJSONProtocolConstants.EscSequences[0])
                     {
-#if NETSTANDARD2_0
-                        await buffer.WriteAsync(new[] {ch}, 0, 1, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
                         var wbuf = new[] { ch };
                         await buffer.WriteAsync(wbuf.AsMemory(0, 1), cancellationToken);
+#else
+                        await buffer.WriteAsync(new[] { ch }, 0, 1, cancellationToken);
 #endif
                         continue;
                     }
@@ -454,11 +454,11 @@
                             throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected control char");
                         }
                         ch = TJSONProtocolConstants.EscapeCharValues[off];
-#if NETSTANDARD2_0
-                        await buffer.WriteAsync(new[] {ch}, 0, 1, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
                         var wbuf = new[] { ch };
                         await buffer.WriteAsync( wbuf.AsMemory(0, 1), cancellationToken);
+#else
+                        await buffer.WriteAsync(new[] { ch }, 0, 1, cancellationToken);
 #endif
                         continue;
                     }
@@ -488,20 +488,20 @@
 
                         codeunits.Add((char) wch);
                         var tmp = Utf8Encoding.GetBytes(codeunits.ToArray());
-#if NETSTANDARD2_0
-                        await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
                         await buffer.WriteAsync(tmp.AsMemory(0, tmp.Length), cancellationToken);
+#else
+                        await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken);
 #endif
                         codeunits.Clear();
                     }
                     else
                     {
                         var tmp = Utf8Encoding.GetBytes(new[] { (char)wch });
-#if NETSTANDARD2_0
-                        await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
                         await buffer.WriteAsync(tmp.AsMemory( 0, tmp.Length), cancellationToken);
+#else
+                        await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken);
 #endif
                     }
                 }
diff --git a/lib/netstd/Thrift/Thrift.csproj b/lib/netstd/Thrift/Thrift.csproj
index 760ffe4..2ebfb06 100644
--- a/lib/netstd/Thrift/Thrift.csproj
+++ b/lib/netstd/Thrift/Thrift.csproj
@@ -40,8 +40,8 @@
     <SignAssembly>true</SignAssembly>
     <AssemblyOriginatorKeyFile>thrift.snk</AssemblyOriginatorKeyFile>
     <DelaySign>false</DelaySign>
-    <Title>Apache Thrift 0.19.0</Title>
-    <Version>0.19.0.0</Version>
+    <Title>Apache Thrift 0.20.0</Title>
+    <Version>0.20.0.0</Version>
     <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
     <PackageProjectUrl>http://thrift.apache.org/</PackageProjectUrl>
     <Authors>Apache Thrift Developers</Authors>
@@ -50,18 +50,18 @@
     <PackageDescription>C# .NET Core bindings for the Apache Thrift RPC system</PackageDescription>
     <PackageReleaseNotes></PackageReleaseNotes>
     <PackageTags>Apache Thrift RPC</PackageTags>
-    <PackageReleaseNotes>https://github.com/apache/thrift/blob/0.19.0/CHANGES.md</PackageReleaseNotes>
+    <PackageReleaseNotes>https://github.com/apache/thrift/blob/0.20.0/CHANGES.md</PackageReleaseNotes>
 	<PackageReadmeFile>README.md</PackageReadmeFile>
     <Copyright>Copyright 2023 The Apache Software Foundation</Copyright>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
+    <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" Condition="'$(TargetFramework.StartsWith(`netstandard2.`))' == 'true'" />
     <PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0" />
     <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="7.0.0" />
     <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="7.0.0" />
     <PackageReference Include="System.IO.Pipes" Version="[4.3,)" />
-    <PackageReference Include="System.IO.Pipes.AccessControl" Version="5.0.0" />
+    <PackageReference Include="System.IO.Pipes.AccessControl" Version="5.0.0" Condition="'$(TargetFramework.StartsWith(`netstandard2.`))' == 'true'" />
     <PackageReference Include="System.Net.Http.WinHttpHandler" Version="7.0.0" />
     <PackageReference Include="System.Net.NameResolution" Version="[4.3,)" />
     <PackageReference Include="System.Net.Requests" Version="[4.3,)" />
@@ -70,12 +70,22 @@
   </ItemGroup>
 
   <ItemGroup>
+    <FrameworkReference Include="Microsoft.AspNetCore.App" Condition="'$(TargetFramework.StartsWith(`netstandard2.`))' == 'false'" />
+  </ItemGroup>
+	
+  <ItemGroup>
     <PackageReference Update="Microsoft.NETFramework.ReferenceAssemblies" Version="1.0.3" />
   </ItemGroup>
 
   <ItemGroup>
     <None Include="..\README.md" Pack="true" PackagePath="\" />
   </ItemGroup>
+
+  <ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
+    <PackageReference Include="Microsoft.AspNetCore.Components.Web">
+      <Version>7.0.9</Version>
+    </PackageReference>
+  </ItemGroup>
 	
   <Target Name="SetTFMAssemblyAttributesPath" BeforeTargets="GenerateTargetFrameworkMonikerAttribute">
     <PropertyGroup>
diff --git a/lib/netstd/Thrift/Transport/Client/THttpTransport.cs b/lib/netstd/Thrift/Transport/Client/THttpTransport.cs
index 60ed59c..1ab1caf 100644
--- a/lib/netstd/Thrift/Transport/Client/THttpTransport.cs
+++ b/lib/netstd/Thrift/Transport/Client/THttpTransport.cs
@@ -150,10 +150,10 @@
 
             try
             {
-#if NETSTANDARD2_0
-                var ret = await _inputStream.ReadAsync(buffer, offset, length, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
                 var ret = await _inputStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
+#else
+                var ret = await _inputStream.ReadAsync(buffer, offset, length, cancellationToken);
 #endif
                 if (ret == -1)
                 {
@@ -173,10 +173,10 @@
         {
             cancellationToken.ThrowIfCancellationRequested();
 
-#if NETSTANDARD2_0
-            await _outputStream.WriteAsync(buffer, offset, length, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
             await _outputStream.WriteAsync(buffer.AsMemory(offset, length), cancellationToken);
+#else
+            await _outputStream.WriteAsync(buffer, offset, length, cancellationToken);
 #endif
         }
 
@@ -245,10 +245,10 @@
                     var response = (await _httpClient.PostAsync(_uri, contentStream, cancellationToken)).EnsureSuccessStatusCode();
 
                     _inputStream?.Dispose();
-#if NETSTANDARD2_0 || NETSTANDARD2_1
-                    _inputStream = await response.Content.ReadAsStreamAsync();
-#else
+#if NET5_0_OR_GREATER
                     _inputStream = await response.Content.ReadAsStreamAsync(cancellationToken);
+#else
+                    _inputStream = await response.Content.ReadAsStreamAsync();
 #endif
                     if (_inputStream.CanSeek)
                     {
diff --git a/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs b/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs
index 071c660..8e60f9f 100644
--- a/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs
+++ b/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs
@@ -76,10 +76,10 @@
             }
 
             CheckReadBytesAvailable(length);
-#if NETSTANDARD2_0
-            var numRead = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
             var numRead = await PipeStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
+#else
+            var numRead = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken);
 #endif
             CountConsumedMessageBytes(numRead);
             return numRead;
@@ -98,10 +98,10 @@
             var nBytes = Math.Min(15 * 4096, length); // 16 would exceed the limit
             while (nBytes > 0)
             {
-#if NETSTANDARD2_0
-                await PipeStream.WriteAsync(buffer, offset, nBytes, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
                 await PipeStream.WriteAsync(buffer.AsMemory(offset, nBytes), cancellationToken);
+#else
+                await PipeStream.WriteAsync(buffer, offset, nBytes, cancellationToken);
 #endif
                 offset += nBytes;
                 length -= nBytes;
diff --git a/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs b/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
index 55b636d..7237b8d 100644
--- a/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
+++ b/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
@@ -81,10 +81,10 @@
                     "Cannot read from null inputstream");
             }
 
-#if NETSTANDARD2_0
-            return await InputStream.ReadAsync(buffer, offset, length, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
             return await InputStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
+#else
+            return await InputStream.ReadAsync(buffer, offset, length, cancellationToken);
 #endif
         }
 
@@ -96,10 +96,10 @@
                     "Cannot write to null outputstream");
             }
 
-#if NETSTANDARD2_0
-            await OutputStream.WriteAsync(buffer, offset, length, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
             await OutputStream.WriteAsync(buffer.AsMemory(offset, length), cancellationToken);
+#else
+            await OutputStream.WriteAsync(buffer, offset, length, cancellationToken);
 #endif
         }
 
diff --git a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
index 66018b0..b1ed91e 100644
--- a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
+++ b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
@@ -382,10 +382,10 @@
                 }
 
                 CheckReadBytesAvailable(length);
-#if NETSTANDARD2_0
-                var numBytes = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken);
-#else
+#if NET5_0_OR_GREATER
                 var numBytes = await PipeStream.ReadAsync(buffer.AsMemory(offset, length), cancellationToken);
+#else
+                var numBytes = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken);
 #endif
                 CountConsumedMessageBytes(numBytes);
                 return numBytes;
diff --git a/lib/ocaml/_oasis b/lib/ocaml/_oasis
index cd4a0c7..be1ce12 100644
--- a/lib/ocaml/_oasis
+++ b/lib/ocaml/_oasis
@@ -1,5 +1,5 @@
 Name: libthrift-ocaml
-Version: 0.19.0
+Version: 0.20.0
 OASISFormat: 0.3
 Synopsis: OCaml bindings for the Apache Thrift RPC system
 Authors: Apache Thrift Developers <dev@thrift.apache.org>
diff --git a/lib/perl/lib/Thrift.pm b/lib/perl/lib/Thrift.pm
index 08eb841..4b5f781 100644
--- a/lib/perl/lib/Thrift.pm
+++ b/lib/perl/lib/Thrift.pm
@@ -31,6 +31,6 @@
 #
 
 package Thrift;
-use version 0.77; our $VERSION = version->declare("v0.19.0");
+use version 0.77; our $VERSION = version->declare("v0.20.0");
 
 1;
diff --git a/lib/py/setup.py b/lib/py/setup.py
index 6e365f8..f5371af 100644
--- a/lib/py/setup.py
+++ b/lib/py/setup.py
@@ -105,7 +105,7 @@
     twisted_deps = ['twisted']
 
     setup(name='thrift',
-          version='0.19.0',
+          version='0.20.0',
           description='Python bindings for the Apache Thrift RPC system',
           long_description=read_file("README.md"),
           long_description_content_type="text/markdown",
diff --git a/lib/rb/thrift.gemspec b/lib/rb/thrift.gemspec
index 5de4408..6b510c7 100644
--- a/lib/rb/thrift.gemspec
+++ b/lib/rb/thrift.gemspec
@@ -3,7 +3,7 @@
 
 Gem::Specification.new do |s|
   s.name        = 'thrift'
-  s.version     = '0.19.0'
+  s.version     = '0.20.0'
   s.authors     = ['Apache Thrift Developers']
   s.email       = ['dev@thrift.apache.org']
   s.homepage    = 'http://thrift.apache.org'
diff --git a/lib/rs/Cargo.toml b/lib/rs/Cargo.toml
index 4b3c857..38c277d 100644
--- a/lib/rs/Cargo.toml
+++ b/lib/rs/Cargo.toml
@@ -2,7 +2,7 @@
 name = "thrift"
 description = "Rust bindings for the Apache Thrift RPC system"
 edition = "2021"
-version = "0.19.0"
+version = "0.20.0"
 license = "Apache-2.0"
 authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
 homepage = "http://thrift.apache.org"
diff --git a/lib/rs/src/server/threaded.rs b/lib/rs/src/server/threaded.rs
index ad55b44..ee86395 100644
--- a/lib/rs/src/server/threaded.rs
+++ b/lib/rs/src/server/threaded.rs
@@ -183,6 +183,7 @@
         for stream in listener.incoming() {
             match stream {
                 Ok(s) => {
+                    s.set_nodelay(true).ok();
                     let channel = TTcpChannel::with_stream(s);
                     self.handle_stream(channel)?;
                 }
diff --git a/lib/st/package.xml b/lib/st/package.xml
index 63dd3af..7af883e 100644
--- a/lib/st/package.xml
+++ b/lib/st/package.xml
@@ -17,7 +17,7 @@
  specific language governing permissions and limitations
  under the License.
  -->
-<!-- Apache Thrift Smalltalk library version 0.19.0 -->
+<!-- Apache Thrift Smalltalk library version 0.20.0 -->
 <package>
   <name>libthrift-st</name>
   <file>thrift.st</file>
diff --git a/lib/swift/Sources/Thrift.swift b/lib/swift/Sources/Thrift.swift
index df1b658..22981a0 100644
--- a/lib/swift/Sources/Thrift.swift
+++ b/lib/swift/Sources/Thrift.swift
@@ -1,3 +1,3 @@
 class Thrift {
-	let version = "0.19.0"
+	let version = "0.20.0"
 }
diff --git a/lib/swift/Tests/ThriftTests/ThriftTests.swift b/lib/swift/Tests/ThriftTests/ThriftTests.swift
index aea9bc8..3c6854c 100644
--- a/lib/swift/Tests/ThriftTests/ThriftTests.swift
+++ b/lib/swift/Tests/ThriftTests/ThriftTests.swift
@@ -3,7 +3,7 @@
 
 class ThriftTests: XCTestCase {
   func testVersion() {
-    XCTAssertEqual(Thrift().version, "0.19.0")
+    XCTAssertEqual(Thrift().version, "0.20.0")
   }
 
   static var allTests : [(String, (ThriftTests) -> () throws -> Void)] {
diff --git a/lib/ts/package-lock.json b/lib/ts/package-lock.json
index de1254c..b7a591b 100644
--- a/lib/ts/package-lock.json
+++ b/lib/ts/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.19.0",
+  "version": "0.20.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
diff --git a/lib/ts/package.json b/lib/ts/package.json
index 2d93d32..054807f 100644
--- a/lib/ts/package.json
+++ b/lib/ts/package.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.19.0",
+  "version": "0.20.0",
   "description": "Thrift is a software framework for scalable cross-language services development.",
   "author": {
     "name": "Apache Thrift Developers",
diff --git a/package-lock.json b/package-lock.json
index cc367e5..e1440f0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.19.0",
+  "version": "0.20.0",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
diff --git a/package.json b/package.json
index 28d7a15..47f9e87 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
     "type": "git",
     "url": "https://github.com/apache/thrift.git"
   },
-  "version": "0.19.0",
+  "version": "0.20.0",
   "author": {
     "name": "Apache Thrift Developers",
     "email": "dev@thrift.apache.org",
diff --git a/sonar-project.properties b/sonar-project.properties
index cac8e8c..258dfe9 100644
--- a/sonar-project.properties
+++ b/sonar-project.properties
@@ -16,7 +16,7 @@
 services that work efficiently and seamlessly between all major languages.
 
 # Apache Thrift Version
-sonar.projectVersion=0.19.0
+sonar.projectVersion=0.20.0
 # use this to set another version string
 # $ sonar-runner -D sonar.projectVersion=`git rev-parse HEAD`
 # set projectDate in combination with projectVersion for imports of old releases
@@ -54,7 +54,7 @@
 module1.sonar.projectBaseDir=lib/java
 module1.sonar.sources=src
 module1.sonar.tests=test
-module1.sonar.binaries=build/libs/libthrift-0.19.0.jar
+module1.sonar.binaries=build/libs/libthrift-0.20.0.jar
 module1.sonar.libraries=build/deps/*.jar
 module1.sonar.language=java
 
@@ -62,7 +62,7 @@
 module2.sonar.projectBaseDir=.
 module2.sonar.sources=tutorial/java/src, tutorial/java/gen-java
 module2.sonar.binaries=tutorial/java/tutorial.jar
-module2.sonar.libraries=lib/java/build/deps/*.jar,lib/java/build/libs/libthrift-0.19.0.jar
+module2.sonar.libraries=lib/java/build/deps/*.jar,lib/java/build/libs/libthrift-0.20.0.jar
 module2.sonar.language=java
 
 module3.sonar.projectName=Apache Thrift - JavaScript Library
diff --git a/test/dart/test_client/pubspec.yaml b/test/dart/test_client/pubspec.yaml
index 45a7a4e..177e2cd 100644
--- a/test/dart/test_client/pubspec.yaml
+++ b/test/dart/test_client/pubspec.yaml
@@ -16,7 +16,7 @@
 # under the License.
 
 name: thrift_test_client
-version: 0.19.0
+version: 0.20.0
 description: A client integration test for the Dart Thrift library
 author: Apache Thrift Developers <dev@thrift.apache.org>
 homepage: http://thrift.apache.org
diff --git a/test/erl/src/thrift_test.app.src b/test/erl/src/thrift_test.app.src
index 4a850d0..9d68a56 100644
--- a/test/erl/src/thrift_test.app.src
+++ b/test/erl/src/thrift_test.app.src
@@ -22,7 +22,7 @@
   {description, "Thrift cross language test"},
 
   % The version of the applicaton
-  {vsn, "0.19.0"},
+  {vsn, "0.20.0"},
 
   % All modules used by the application.
   {modules, [
diff --git a/test/netstd/Client/Client.csproj b/test/netstd/Client/Client.csproj
index bd7d1ee..1ae67fa 100644
--- a/test/netstd/Client/Client.csproj
+++ b/test/netstd/Client/Client.csproj
@@ -24,7 +24,7 @@
     <AssemblyName>Client</AssemblyName>
     <PackageId>Client</PackageId>
     <OutputType>Exe</OutputType>
-    <Version>0.19.0.0</Version>
+    <Version>0.20.0.0</Version>
     <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
     <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
@@ -37,7 +37,7 @@
   <ItemGroup>
     <PackageReference Include="System.Net.Http.WinHttpHandler" Version="7.0.0" />
     <PackageReference Include="System.Runtime.Serialization.Primitives" Version="[4.3,)" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.10.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="6.0.0" />
     <PackageReference Include="System.Threading" Version="[4.3,)" />
   </ItemGroup>
 
diff --git a/test/netstd/Server/Server.csproj b/test/netstd/Server/Server.csproj
index 85c1ad4..020b8d5 100644
--- a/test/netstd/Server/Server.csproj
+++ b/test/netstd/Server/Server.csproj
@@ -24,7 +24,7 @@
     <AssemblyName>Server</AssemblyName>
     <PackageId>Server</PackageId>
     <OutputType>Exe</OutputType>
-    <Version>0.19.0.0</Version>
+    <Version>0.20.0.0</Version>
     <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
     <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
@@ -36,10 +36,9 @@
 
   <ItemGroup>
     <PackageReference Include="System.IO.Pipes" Version="4.3.0" />
-    <PackageReference Include="System.IO.Pipes.AccessControl" Version="5.0.0" />
     <PackageReference Include="System.Net.Http.WinHttpHandler" Version="7.0.0" />
     <PackageReference Include="System.Runtime.Serialization.Primitives" Version="[4.3,)" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.10.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="6.0.0" />
     <PackageReference Include="System.Threading" Version="[4.3,)" />
   </ItemGroup>
 
diff --git a/tutorial/dart/client/pubspec.yaml b/tutorial/dart/client/pubspec.yaml
index 626c8f9..e8c6db8 100644
--- a/tutorial/dart/client/pubspec.yaml
+++ b/tutorial/dart/client/pubspec.yaml
@@ -16,7 +16,7 @@
 # under the License.
 
 name: tutorial_client
-version: 0.19.0
+version: 0.20.0
 description: A Dart client implementation of the Apache Thrift tutorial
 author: Apache Thrift Developers <dev@thrift.apache.org>
 homepage: http://thrift.apache.org
diff --git a/tutorial/dart/console_client/pubspec.yaml b/tutorial/dart/console_client/pubspec.yaml
index 957b96c..e5c0938 100644
--- a/tutorial/dart/console_client/pubspec.yaml
+++ b/tutorial/dart/console_client/pubspec.yaml
@@ -16,7 +16,7 @@
 # under the License.
 
 name: tutorial_console_client
-version: 0.19.0
+version: 0.20.0
 description: >
   A Dart console client to implementation of the Apache Thrift tutorial
 author: Apache Thrift Developers <dev@thrift.apache.org>
diff --git a/tutorial/dart/server/pubspec.yaml b/tutorial/dart/server/pubspec.yaml
index 6ad5cdd..5f7edb9 100644
--- a/tutorial/dart/server/pubspec.yaml
+++ b/tutorial/dart/server/pubspec.yaml
@@ -16,7 +16,7 @@
 # under the License.
 
 name: tutorial_server
-version: 0.19.0
+version: 0.20.0
 description: A Dart server to support the Apache Thrift tutorial
 author: Apache Thrift Developers <dev@thrift.apache.org>
 homepage: http://thrift.apache.org
diff --git a/tutorial/delphi/DelphiClient/DelphiClient.dproj b/tutorial/delphi/DelphiClient/DelphiClient.dproj
index e55cc06..34d9f03 100644
--- a/tutorial/delphi/DelphiClient/DelphiClient.dproj
+++ b/tutorial/delphi/DelphiClient/DelphiClient.dproj
@@ -124,13 +124,13 @@
 					<VersionInfoKeys>
 						<VersionInfoKeys Name="CompanyName"/>
 						<VersionInfoKeys Name="FileDescription">Thrift Tutorial</VersionInfoKeys>
-						<VersionInfoKeys Name="FileVersion">0.19.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="FileVersion">0.20.0.0</VersionInfoKeys>
 						<VersionInfoKeys Name="InternalName">DelphiClient</VersionInfoKeys>
 						<VersionInfoKeys Name="LegalCopyright">Copyright © 2012 The Apache Software Foundation</VersionInfoKeys>
 						<VersionInfoKeys Name="LegalTrademarks"/>
 						<VersionInfoKeys Name="OriginalFilename">DelphiClient.exe</VersionInfoKeys>
 						<VersionInfoKeys Name="ProductName">Thrift</VersionInfoKeys>
-						<VersionInfoKeys Name="ProductVersion">0.19.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="ProductVersion">0.20.0.0</VersionInfoKeys>
 						<VersionInfoKeys Name="Comments"/>
 					</VersionInfoKeys>
 					<Source>
diff --git a/tutorial/delphi/DelphiServer/DelphiServer.dproj b/tutorial/delphi/DelphiServer/DelphiServer.dproj
index 4080b92..fa8cb92 100644
--- a/tutorial/delphi/DelphiServer/DelphiServer.dproj
+++ b/tutorial/delphi/DelphiServer/DelphiServer.dproj
@@ -121,13 +121,13 @@
 					<VersionInfoKeys>
 						<VersionInfoKeys Name="CompanyName"/>
 						<VersionInfoKeys Name="FileDescription">Thrift Tutorial</VersionInfoKeys>
-						<VersionInfoKeys Name="FileVersion">0.19.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="FileVersion">0.20.0.0</VersionInfoKeys>
 						<VersionInfoKeys Name="InternalName">DelphiServer</VersionInfoKeys>
 						<VersionInfoKeys Name="LegalCopyright">Copyright © 2012 The Apache Software Foundation</VersionInfoKeys>
 						<VersionInfoKeys Name="LegalTrademarks"/>
 						<VersionInfoKeys Name="OriginalFilename">DelphiServer.exe</VersionInfoKeys>
 						<VersionInfoKeys Name="ProductName">Thrift</VersionInfoKeys>
-						<VersionInfoKeys Name="ProductVersion">0.19.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="ProductVersion">0.20.0.0</VersionInfoKeys>
 						<VersionInfoKeys Name="Comments"/>
 					</VersionInfoKeys>
 					<Source>
diff --git a/tutorial/netstd/Client/Client.csproj b/tutorial/netstd/Client/Client.csproj
index c21b58d..ee0bc82 100644
--- a/tutorial/netstd/Client/Client.csproj
+++ b/tutorial/netstd/Client/Client.csproj
@@ -24,7 +24,7 @@
     <AssemblyName>Client</AssemblyName>
     <PackageId>Client</PackageId>
     <OutputType>Exe</OutputType>
-    <Version>0.19.0.0</Version>
+    <Version>0.20.0.0</Version>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
     <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
     <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
diff --git a/tutorial/netstd/Interfaces/Interfaces.csproj b/tutorial/netstd/Interfaces/Interfaces.csproj
index 1e1193b..ff7891e 100644
--- a/tutorial/netstd/Interfaces/Interfaces.csproj
+++ b/tutorial/netstd/Interfaces/Interfaces.csproj
@@ -22,7 +22,7 @@
     <TargetFramework>net7.0</TargetFramework>
     <AssemblyName>Interfaces</AssemblyName>
     <PackageId>Interfaces</PackageId>
-    <Version>0.19.0.0</Version>
+    <Version>0.20.0.0</Version>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
     <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
     <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
@@ -34,7 +34,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.10.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="6.0.0" />
   </ItemGroup>
 
   <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
diff --git a/tutorial/netstd/Server/Server.csproj b/tutorial/netstd/Server/Server.csproj
index 193e3c3..9aa3bc6 100644
--- a/tutorial/netstd/Server/Server.csproj
+++ b/tutorial/netstd/Server/Server.csproj
@@ -24,7 +24,7 @@
     <AssemblyName>Server</AssemblyName>
     <PackageId>Server</PackageId>
     <OutputType>Exe</OutputType>
-    <Version>0.19.0.0</Version>
+    <Version>0.20.0.0</Version>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
     <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
     <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
@@ -36,10 +36,9 @@
     <ProjectReference Include="../../../lib/netstd/Thrift/Thrift.csproj" />
   </ItemGroup>
 
-  <ItemGroup>
-    <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
-    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.2.1" />
-    <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
-    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="7.0.0" />
+  <ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
+    <PackageReference Include="Microsoft.AspNetCore.Components.Web">
+      <Version>7.0.9</Version>
+    </PackageReference>
   </ItemGroup>
 </Project>
diff --git a/tutorial/ocaml/_oasis b/tutorial/ocaml/_oasis
index 1101740..6072e4b 100644
--- a/tutorial/ocaml/_oasis
+++ b/tutorial/ocaml/_oasis
@@ -1,5 +1,5 @@
 Name: tutorial
-Version: 0.19.0
+Version: 0.20.0
 OASISFormat: 0.3
 Synopsis: OCaml Tutorial example
 Authors: Apache Thrift Developers <dev@thrift.apache.org>