Merge branch '0.14.2' into upstream
diff --git a/.gitignore b/.gitignore
index cf73c4c..6d07751 100644
--- a/.gitignore
+++ b/.gitignore
@@ -105,8 +105,6 @@
 /contrib/fb303/py/fb303/ttypes.py
 /depcomp
 /install-sh
-/lib/as3/.gradle/
-/lib/as3/build/
 /lib/cl/backport-update.zip
 /lib/cl/lib
 /lib/cl/run-tests
@@ -200,14 +198,12 @@
 /lib/dart/**/packages
 /lib/dart/**/.pub/
 /lib/dart/**/pubspec.lock
-/lib/delphi/test/skip/*.request
-/lib/delphi/test/skip/*.response
+/lib/delphi/test/skip/bin
 /lib/delphi/test/serializer/*.dat
 /lib/delphi/**/*.identcache
 /lib/delphi/**/*.local
 /lib/delphi/**/*.dcu
 /lib/delphi/**/*.2007
-/lib/delphi/**/*.dproj
 /lib/delphi/**/codegen/*.bat
 /lib/erl/_build/
 /lib/erl/.eunit
@@ -301,6 +297,17 @@
 /lib/rs/test/src/recursive.rs
 /lib/rs/test/src/ultimate.rs
 /lib/rs/test/src/identifiers.rs
+/lib/rs/test_recursive/Cargo.lock
+/lib/rs/test_recursive/src/vehicles.rs
+/lib/rs/test_recursive/src/maintenance/maintenance_facility.rs
+/lib/rs/test_recursive/src/transit/buses.rs
+/lib/rs/test_recursive/src/transit/trains.rs
+/lib/rs/test_recursive/src/transit/transporters.rs
+/lib/rs/test_recursive/src/transit/light/light_rail.rs
+/lib/rs/test_recursive/src/transit/light/streetcars.rs
+/lib/rs/test_recursive/src/transit/services/city_services.rs
+/lib/rs/test_recursive/target/
+/lib/rs/test_recursive/bin/
 /lib/rs/*.iml
 /lib/rs/**/*.iml
 /lib/swift/.build
@@ -346,6 +353,7 @@
 /test/go/src/gen/
 /test/go/src/thrift
 /test/haxe/bin
+/test/haxe/.buildtemp
 /test/hs/TestClient
 /test/hs/TestServer
 /test/php/php_ext_dir/
@@ -353,6 +361,7 @@
 /test/rb/Gemfile.lock
 /test/netstd/**/bin
 /test/netstd/**/obj
+/test/netstd/**/launchSettings.json
 /test/netstd/*.psess
 /test/netstd/*.vspx
 /test/netstd/*.vsp
@@ -417,5 +426,7 @@
 /tutorial/rs/Cargo.lock
 /tutorial/netstd/Interfaces/shared
 /tutorial/netstd/Interfaces/tutorial
+/tutorial/netstd/Server/Properties/launchSettings.json
+/tutorial/netstd/Client/Properties/launchSettings.json
 /ylwrap
 
diff --git a/.rustfmt.toml b/.rustfmt.toml
deleted file mode 100644
index dca5afd..0000000
--- a/.rustfmt.toml
+++ /dev/null
@@ -1,64 +0,0 @@
-max_width = 100
-hard_tabs = false
-tab_spaces = 4
-newline_style = "Auto"
-use_small_heuristics = "Default"
-indent_style = "Block"
-wrap_comments = false
-format_doc_comments = false
-comment_width = 80
-normalize_comments = false
-normalize_doc_attributes = false
-license_template_path = ""
-format_strings = false
-format_macro_matchers = false
-format_macro_bodies = true
-empty_item_single_line = true
-struct_lit_single_line = true
-fn_single_line = false
-where_single_line = false
-imports_indent = "Block"
-imports_layout = "Mixed"
-merge_imports = false
-reorder_imports = true
-reorder_modules = true
-reorder_impl_items = false
-type_punctuation_density = "Wide"
-space_before_colon = false
-space_after_colon = true
-spaces_around_ranges = false
-binop_separator = "Front"
-remove_nested_parens = true
-combine_control_expr = true
-overflow_delimited_expr = false
-struct_field_align_threshold = 0
-enum_discrim_align_threshold = 0
-match_arm_blocks = true
-force_multiline_blocks = false
-fn_args_density = "Tall"
-brace_style = "SameLineWhere"
-control_brace_style = "AlwaysSameLine"
-trailing_semicolon = true
-trailing_comma = "Vertical"
-match_block_trailing_comma = false
-blank_lines_upper_bound = 1
-blank_lines_lower_bound = 0
-edition = "2015"
-merge_derives = true
-use_try_shorthand = false
-use_field_init_shorthand = false
-force_explicit_abi = true
-condense_wildcard_suffixes = false
-color = "Auto"
-required_version = "1.0.0"
-unstable_features = false
-disable_all_formatting = false
-skip_children = false
-hide_parse_errors = false
-error_on_line_overflow = false
-error_on_unformatted = false
-report_todo = "Never"
-report_fixme = "Never"
-ignore = []
-emit_mode = "Files"
-make_backup = false
diff --git a/.travis.yml b/.travis.yml
index f3dc7e4..409eee7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -44,7 +44,7 @@
     - BUILD_ARG=""
     - BUILD_ENV="-e CC=gcc -e CXX=g++ -e THRIFT_CROSSTEST_CONCURRENCY=4"
     - DISTRO=ubuntu-bionic
-    - BUILD_LIBS="CPP C_GLIB HASKELL JAVA PYTHON TESTING TUTORIALS"  # only meaningful for CMake builds
+    - BUILD_LIBS="CPP C_GLIB JAVA PYTHON TESTING TUTORIALS"  # only meaningful for CMake builds
     - TRAVIS_BUILD_STAGE=test
     # DOCKER_REPO (this works for all builds as a source for docker images - you can override for fork builds in your Travis settings)
     - DOCKER_REPO="thrift/thrift-build"
diff --git a/ApacheThrift.nuspec b/ApacheThrift.nuspec
index 44b76da..4a6e99b 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.14.2.nupkg -Source https://api.nuget.org/v3/index.json
+  4. nuget push ApacheThrift.0.15.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.14.2</version>
-    <title>Apache Thrift 0.14.2</title>
+    <version>0.15.0</version>
+    <title>Apache Thrift 0.15.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.14.2" />
+    <repository type="GitHub" url="https://github.com/apache/thrift" branch="release/0.15.0" />
     <tags>Apache Thrift RPC</tags>
   </metadata>
   <files>
diff --git a/CHANGES.md b/CHANGES.md
index d7ef279..98d889d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,5 +1,20 @@
 # Apache Thrift Changelog
 
+## 0.15.0
+
+### Breaking Changes
+
+- [THRIFT-5229](https://issues.apache.org/jira/browse/THRIFT-5229) - ActionScript 3 support dropped
+- [THRIFT-5347](https://issues.apache.org/jira/browse/THRIFT-5347) - Haskell support dropped
+- [THRIFT-5381](https://issues.apache.org/jira/browse/THRIFT-5381) - possible collisions at VOID type with some 3rd-party libraries on Haxe cpp targets
+- [THRIFT-5396](https://issues.apache.org/jira/browse/THRIFT-5396) - deprecate netstd "Async" method postfix
+
+### Go
+
+- [THRIFT-5369](https://issues.apache.org/jira/browse/THRIFT-5369) - TConfiguration.GetMaxMessageSize() now also applies to container sizes in TProtocol implementations provided
+- [THRIFT-5404](https://issues.apache.org/jira/browse/THRIFT-5404) - TTransportException.Timeout would correctly return true when it's connect timeout during TSocket.Open call
+
+
 ## 0.14.2
 
 ### Java
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3487abf..3b341d0 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.14.2")
+set(thrift_VERSION "0.15.0")
 set(PACKAGE_VERSION ${thrift_VERSION})
 
 project("thrift" VERSION ${PACKAGE_VERSION})
@@ -98,10 +98,6 @@
     endif()
 endif()
 
-if(BUILD_AS3)
-    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/as3)
-endif()
-
 if(BUILD_C_GLIB)
     add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/c_glib)
     if(BUILD_TESTING)
@@ -128,13 +124,6 @@
     endif()
 endif()
 
-if(BUILD_HASKELL)
-    add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib/hs)
-    if(BUILD_TESTING)
-        add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test/hs)
-    endif()
-endif()
-
 # Create the uninstall target
 add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${PROJECT_SOURCE_DIR}/build/cmake/uninstall.cmake")
 
diff --git a/LANGUAGES.md b/LANGUAGES.md
index 08c431d..46a7838 100644
--- a/LANGUAGES.md
+++ b/LANGUAGES.md
@@ -1,6 +1,8 @@
 # Apache Thrift Language Support #
 
-Guidance For: 0.13.0 | 
+Guidance For: 0.15.0 | 
+[0.14.0](https://github.com/apache/thrift/blob/v0.14.0/LANGUAGES.md) | 
+[0.13.0](https://github.com/apache/thrift/blob/v0.13.0/LANGUAGES.md) | 
 [0.12.0](https://github.com/apache/thrift/blob/v0.12.0/LANGUAGES.md) | 
 [0.11.0](https://github.com/apache/thrift/blob/0.11.0/LANGUAGES.md)
 
@@ -58,17 +60,6 @@
 </thead>
 <tbody>
 <tr align=center>
-<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/as3/README.md">ActionScript</a></td>
-<!-- Since -----------------><td>0.3.0</td>
-<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Language Levels -------><td colspan=2>FLEX SDK 4.6</td>
-<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22AS3%20-%20Compiler%22%2C%20%22AS3%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">ActionScript</a></td>
-</tr>
-<tr align=center>
 <td align=left><a href="https://github.com/apache/thrift/blob/master/lib/c_glib/README.md">C (glib)</a></td>
 <!-- Since -----------------><td>0.6.0</td>
 <!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
@@ -105,7 +96,7 @@
 <td align=left><a href="https://github.com/apache/thrift/blob/master/lib/d/README.md">Dlang</a></td>
 <!-- Since -----------------><td>0.9.0</td>
 <!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>2.075.1</td><td>2.087.0</td>
+<!-- Language Levels -------><td>2.087.0</td><td>2.087.0</td>
 <!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
 <!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
 <!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
@@ -127,7 +118,7 @@
 <td align=left><a href="https://github.com/apache/thrift/blob/master/lib/delphi/README.md">Delphi</a></td>
 <!-- Since -----------------><td>0.8.0</td>
 <!-- Build Systems ---------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>2010</td><td>unknown</td>
+<!-- Language Levels -------><td>2010</td><td>Sydney 10.4.1</td>
 <!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
 <!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
 <!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
@@ -138,7 +129,7 @@
 <td align=left><a href="https://github.com/apache/thrift/blob/master/lib/netstd/README.md">.NET Standard</a></td>
 <!-- Since -----------------><td>0.13.0</td>
 <!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td colspan=2>.NET 4.5+, .NET Standard 2.x</td>
+<!-- Language Levels -------><td colspan=2>.NET 4.5+, .NET Standard 2.x, .NET 5.0</td>
 <!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
 <!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
 <!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
@@ -168,21 +159,10 @@
 <td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Go%20-%20Compiler%22%2C%20%22Go%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Go</a></td>
 </tr>
 <tr align=center>
-<td align=left><a href="https://github.com/apache/thrift/blob/master/lib/hs/README.md">Haskell</a></td>
-<!-- Since -----------------><td>0.5.0</td>
-<!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Language Levels -------><td>7.10.3</td><td>8.0.2</td>
-<!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
-<!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Servers ---------------><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<td align=left><a href="https://issues.apache.org/jira/issues/?jql=project%20%3D%20THRIFT%20AND%20component%20in%20(%22Haskell%20-%20Compiler%22%2C%20%22Haskell%20-%20Library%22)%20and%20status%20not%20in%20(fixed%2C%20resolved%2C%20closed)">Haskell</a></td>
-</tr>
-<tr align=center>
 <td align=left><a href="https://github.com/apache/thrift/blob/master/lib/haxe/README.md">Haxe</a></td>
 <!-- Since -----------------><td>0.9.3</td>
 <!-- Build Systems ---------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
-<!-- Language Levels -------><td>3.2.1</td><td>3.4.4</td>
+<!-- Language Levels -------><td>4.1.5</td><td>4.2.1</td>
 <!-- Low-Level Transports --><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
 <!-- Transport Wrappers ----><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cred.png" alt=""/></td>
 <!-- Protocols -------------><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td><td><img src="doc/images/cgrn.png" alt="Yes"/></td>
diff --git a/Makefile.am b/Makefile.am
index c5d9c41..a132209 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -78,7 +78,7 @@
 space := $(empty) $(empty)
 comma := ,
 
-CROSS_LANGS = @MAYBE_CPP@ @MAYBE_C_GLIB@ @MAYBE_CL@ @MAYBE_D@ @MAYBE_JAVA@ @MAYBE_PYTHON@ @MAYBE_PY3@ @MAYBE_RUBY@ @MAYBE_HASKELL@ @MAYBE_PERL@ @MAYBE_PHP@ @MAYBE_GO@ @MAYBE_NODEJS@ @MAYBE_DART@ @MAYBE_ERLANG@ @MAYBE_LUA@ @MAYBE_RS@ @MAYBE_NETSTD@ @MAYBE_NODETS@
+CROSS_LANGS = @MAYBE_CPP@ @MAYBE_C_GLIB@ @MAYBE_CL@ @MAYBE_D@ @MAYBE_JAVA@ @MAYBE_PYTHON@ @MAYBE_PY3@ @MAYBE_RUBY@ @MAYBE_PERL@ @MAYBE_PHP@ @MAYBE_GO@ @MAYBE_NODEJS@ @MAYBE_DART@ @MAYBE_ERLANG@ @MAYBE_LUA@ @MAYBE_RS@ @MAYBE_NETSTD@ @MAYBE_NODETS@
 CROSS_LANGS_COMMA_SEPARATED = $(subst $(space),$(comma),$(CROSS_LANGS))
 
 if WITH_PY3
@@ -142,7 +142,6 @@
 	.gitattributes \
 	.gitignore \
 	.travis.yml \
-	.rustfmt.toml \
 	ApacheThrift.nuspec \
 	appveyor.yml \
 	bootstrap.sh \
@@ -165,5 +164,6 @@
 	package-lock.json \
 	phpcs.xml.dist \
 	README.md \
+	rust-toolchain \
 	sonar-project.properties \
 	Thrift.podspec
diff --git a/README.md b/README.md
index a22f222..66f60d2 100644
--- a/README.md
+++ b/README.md
@@ -36,8 +36,7 @@
 | Branch | Travis | Appveyor | Coverity Scan | codecov.io | Website |
 | :----- | :----- | :------- | :------------ | :--------- | :------ |
 | [`master`](https://github.com/apache/thrift/tree/master) | [![Build Status](https://travis-ci.org/apache/thrift.svg?branch=master)](https://travis-ci.org/apache/thrift/branches) | [![Build status](https://ci.appveyor.com/api/projects/status/github/apache/thrift?branch=master&svg=true)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/thrift/history) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/1345/badge.svg)](https://scan.coverity.com/projects/thrift) | | [![Website](https://img.shields.io/badge/official-website-brightgreen.svg)](https://thrift.apache.org/) |
-| [`0.13.0`](https://github.com/apache/thrift/tree/0.13.0) | [![Build Status](https://travis-ci.org/apache/thrift.svg?branch=0.13.0)](https://travis-ci.org/apache/thrift/branches) | | | | |
-| [`0.12.0`](https://github.com/apache/thrift/tree/0.12.0) | [![Build Status](https://travis-ci.org/apache/thrift.svg?branch=0.12.0)](https://travis-ci.org/apache/thrift/branches) | | | | |
+| [`0.14.0`](https://github.com/apache/thrift/tree/0.14.0) | [![Build Status](https://travis-ci.org/apache/thrift.svg?branch=0.14.0)](https://travis-ci.org/apache/thrift/branches) | | | | |
 
 Releases
 ========
diff --git a/Thrift.podspec b/Thrift.podspec
index 3a01b39..1769105 100644
--- a/Thrift.podspec
+++ b/Thrift.podspec
@@ -1,6 +1,6 @@
 Pod::Spec.new do |s|
   s.name          = 'Thrift'
-  s.version       = '0.14.2'
+  s.version       = '0.15.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.14.2' }
+  s.source        = { :git => 'https://github.com/apache/thrift.git', :tag => 'v0.15.0' }
   s.source_files  = 'lib/swift/Sources/*.swift'
 end
diff --git a/appveyor.yml b/appveyor.yml
index 14b801b..9a91b18 100755
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -19,7 +19,7 @@
 
 # build Apache Thrift on AppVeyor - https://ci.appveyor.com
 
-version: '0.14.2.{build}'
+version: '0.15.0.{build}'
 
 shallow_clone: true
 
diff --git a/bootstrap.sh b/bootstrap.sh
index 1989437..d699909 100755
--- a/bootstrap.sh
+++ b/bootstrap.sh
@@ -61,4 +61,4 @@
 sed '/undef VERSION/d' config.hin > config.hin2
 mv config.hin2 config.hin
 autoconf
-automake --copy --add-missing --foreign
+automake --copy --add-missing
diff --git a/bower.json b/bower.json
index 9121d03..6f66361 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.14.2",
+  "version": "0.15.0",
   "homepage": "https://github.com/apache/thrift.git",
   "authors": [
     "Apache Thrift <dev@thrift.apache.org>"
diff --git a/build/appveyor/CYGW-appveyor-install.bat b/build/appveyor/CYGW-appveyor-install.bat
index 69a159f..4cdc8ea 100644
--- a/build/appveyor/CYGW-appveyor-install.bat
+++ b/build/appveyor/CYGW-appveyor-install.bat
@@ -47,4 +47,4 @@
 ::
 
 %BASH% -lc "apt-cyg remove cmake"
-%BASH% -lc "cd / && wget http://mirror.clarkson.edu/cygwin/x86_64/release/cmake/cmake-3.14.5-1.tar.xz && tar xJf cmake-3.14.5-1.tar.xz && hash -r && cmake --version"
+%BASH% -lc "cd / && wget http://mirror.clarkson.edu/cygwin/x86_64/release/cmake/cmake-3.20.0-1.tar.xz && tar xJf cmake-3.20.0-1.tar.xz && hash -r && cmake --version"
diff --git a/build/appveyor/MSVC-appveyor-install.bat b/build/appveyor/MSVC-appveyor-install.bat
index 09b7cc4..a4c49fe 100644
--- a/build/appveyor/MSVC-appveyor-install.bat
+++ b/build/appveyor/MSVC-appveyor-install.bat
@@ -56,9 +56,6 @@
             tornado ^
             twisted                       || EXIT /B
 
-cinst -y cabal --version 2.4.1.0          || EXIT /B
-cinst -y ghc --version 8.6.5              || EXIT /B
-
 :: Adobe Flex SDK 4.6 for ActionScript
 MKDIR "C:\Adobe\Flex\SDK\4.6"             || EXIT /B
 appveyor DownloadFile http://download.macromedia.com/pub/flex/sdk/flex_sdk_4.6.zip -FileName C:\Adobe\Flex\SDK\4.6\SDK.zip || EXIT /B
diff --git a/build/cmake/DefineOptions.cmake b/build/cmake/DefineOptions.cmake
index e16e564..1fa7a56 100644
--- a/build/cmake/DefineOptions.cmake
+++ b/build/cmake/DefineOptions.cmake
@@ -122,13 +122,6 @@
 CMAKE_DEPENDENT_OPTION(BUILD_PYTHON "Build Python library" ON
                        "BUILD_LIBRARIES;WITH_PYTHON;PYTHONINTERP_FOUND;PYTHONLIBS_FOUND" OFF)
 
-# Haskell
-option(WITH_HASKELL "Build Haskell Thrift library" ON)
-find_package(GHC QUIET)
-find_package(Cabal QUIET)
-CMAKE_DEPENDENT_OPTION(BUILD_HASKELL "Build GHC library" ON
-                       "BUILD_LIBRARIES;WITH_HASKELL;GHC_FOUND;CABAL_FOUND" OFF)
-
 # Common library options
 # https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html
 # Default on Windows is static, shared mode library support needs work...
@@ -215,10 +208,6 @@
 MESSAGE_DEP(WITH_PYTHON "Disabled by WITH_PYTHON=OFF")
 MESSAGE_DEP(PYTHONLIBS_FOUND "Python libraries missing")
 message(STATUS)
-message(STATUS "  Build Haskell library:                      ${BUILD_HASKELL}")
-MESSAGE_DEP(WITH_HASKELL "Disabled by WITH_HASKELL=OFF")
-MESSAGE_DEP(GHC_FOUND "GHC missing")
-MESSAGE_DEP(CABAL_FOUND "Cabal missing")
 message(STATUS)
 message(STATUS "----------------------------------------------------------")
 endmacro(PRINT_CONFIG_SUMMARY)
diff --git a/build/cmake/FindGHC.cmake b/build/cmake/FindGHC.cmake
deleted file mode 100644
index 4873847..0000000
--- a/build/cmake/FindGHC.cmake
+++ /dev/null
@@ -1,36 +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.
-#
-
-
-#  GHC_FOUND - system has GHC
-#  GHC - the GHC executable
-#  RUN_HASKELL_FOUND - system has runhaskell
-#  RUN_HASKELL - the runhaskell executable
-#
-# It will search the environment variable GHC_HOME if it is set
-
-include(FindPackageHandleStandardArgs)
-
-find_program(GHC NAMES ghc PATHS $ENV{GHC_HOME}/bin)
-find_package_handle_standard_args(GHC DEFAULT_MSG GHC)
-mark_as_advanced(GHC)
-
-find_program(RUN_HASKELL NAMES runhaskell PATHS $ENV{GHC_HOME}/bin)
-find_package_handle_standard_args(RUN_HASKELL DEFAULT_MSG RUN_HASKELL)
-mark_as_advanced(RUN_HASKELL)
diff --git a/build/cmake/ThriftConfig.cmake.in b/build/cmake/ThriftConfig.cmake.in
index 6bfb12c..f82c0a5 100644
--- a/build/cmake/ThriftConfig.cmake.in
+++ b/build/cmake/ThriftConfig.cmake.in
@@ -27,17 +27,37 @@
 set(THRIFT_COMPILER "${THRIFT_BIN_DIR}/thrift@CMAKE_EXECUTABLE_SUFFIX@")
 
 if (NOT TARGET thrift::thrift)
-  include("${THRIFT_CMAKE_DIR}/thriftTargets.cmake")
+    include("${THRIFT_CMAKE_DIR}/thriftTargets.cmake")
 endif()
-
 set(THRIFT_LIBRARIES thrift::thrift)
 
-if ("${THRIFT_LIBRARIES}" STREQUAL "")
-	message(FATAL_ERROR "thrift libraries were not found")
+if(@ZLIB_FOUND@ AND @WITH_ZLIB@)
+    if (NOT TARGET thriftz::thriftz)
+        include("${THRIFT_CMAKE_DIR}/thriftzTargets.cmake")
+    endif()
+    set(THRIFT_LIBRARIES thriftz::thriftz)
 endif()
 
+if ("${THRIFT_LIBRARIES}" STREQUAL "")
+    message(FATAL_ERROR "thrift libraries were not found")
+endif()
 if (NOT Thrift_FIND_QUIETLY)
-  message(STATUS "Found thrift: ${PACKAGE_PREFIX_DIR}")
+    message(STATUS "Found thrift: ${PACKAGE_PREFIX_DIR}")
+endif()
+
+
+include(CMakeFindDependencyMacro)
+
+if(@ZLIB_FOUND@ AND @WITH_ZLIB@)
+    find_dependency(ZLIB)
+endif()
+
+if(@OPENSSL_FOUND@ AND @WITH_OPENSSL@)
+    find_dependency(OpenSSL)
+endif()
+
+if(@Libevent_FOUND@ AND @WITH_LIBEVENT@)
+    find_dependency(Libevent)
 endif()
 
 check_required_components(Thrift)
diff --git a/build/cmake/ThriftMacros.cmake b/build/cmake/ThriftMacros.cmake
index 038651e..392b96b 100644
--- a/build/cmake/ThriftMacros.cmake
+++ b/build/cmake/ThriftMacros.cmake
@@ -54,8 +54,8 @@
     target_link_libraries(${name} ${ARGN})
 endmacro()
 
-macro(LINK_AGAINST_THRIFT_LIBRARY target libname)
-    target_link_libraries(${target} ${libname})
+macro(LINK_AGAINST_THRIFT_LIBRARY target)
+    target_link_libraries(${target} ${ARGN})
 endmacro()
 
 macro(TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY target libname)
diff --git a/build/docker/README.md b/build/docker/README.md
index 08023a7..127de8e 100644
--- a/build/docker/README.md
+++ b/build/docker/README.md
@@ -174,17 +174,16 @@
 | C# (mono) | 4.2.1.0       | 4.6.2.7       |       |
 | c_glib    | 2.48.2        | 2.56.4        |       |
 | cl (sbcl) |               | 1.5.3         |       |
-| d         | 2.075.1       | 2.087.0       |       |
+| d         | 2.087.0       | 2.087.0       |       |
 | dart      | 2.0.0         | 2.4.0         |       |
 | delphi    |               |               | Not in CI |
 | erlang    | 18.3          | 22.0          |       |
-| go        | 1.14.14       | 1.15.7        |       |
-| haskell   | 7.10.3        | 8.0.2         |       |
+| 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     | 11.0.3        |       |
 | js        | Node.js 6.17.1, V8 5.1.281.111, npm 3.10.10 | Node.js 10.18.0, V8 6.8.275.32, npm 6.13.4 |     |
 | lua       |               | 5.2.4         | Lua 5.3: see THRIFT-4386 |
-| netstd    | 3.1           | 3.1           | LTS version |
+| netstd    | 5.0           | 5.0           |       |
 | nodejs    | 6.16.0        | 10.16.0       |       |
 | ocaml     |               | 4.05.0        | THRIFT-4517: ocaml 4.02.3 on xenial appears broken |
 | perl      | 5.22.1        | 5.26.1        |       |
diff --git a/build/docker/msvc2017/Dockerfile b/build/docker/msvc2017/Dockerfile
index a2b3cd7..d59c195 100644
--- a/build/docker/msvc2017/Dockerfile
+++ b/build/docker/msvc2017/Dockerfile
@@ -83,9 +83,6 @@
 # Install java
 RUN choco install jdk8 -y
 
-# Install haskell
-RUN choco install ghc -y
-
 # Install python3
 RUN choco install python3 -y
 
diff --git a/build/docker/old/centos-7.3/Dockerfile b/build/docker/old/centos-7.3/Dockerfile
index 096bbaa..ba4c549 100644
--- a/build/docker/old/centos-7.3/Dockerfile
+++ b/build/docker/old/centos-7.3/Dockerfile
@@ -95,9 +95,6 @@
 RUN curl -sSL https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz | tar -C /usr/local/ -xz
 ENV PATH /usr/local/go/bin:$PATH
 
-# Haskell Dependencies
-RUN yum -y install haskell-platform
-
 # Haxe Dependencies
 # Not in debian/stretch
 
diff --git a/build/docker/old/debian-jessie/Dockerfile b/build/docker/old/debian-jessie/Dockerfile
index a49b207..15e02e9 100644
--- a/build/docker/old/debian-jessie/Dockerfile
+++ b/build/docker/old/debian-jessie/Dockerfile
@@ -109,9 +109,6 @@
       rebar
 
 RUN apt-get update && apt-get install -y --no-install-recommends \
-`# Haskell dependencies` \
-      ghc \
-      cabal-install \
 `# Haxe dependencies` \
       neko \
       neko-dev \
diff --git a/build/docker/old/debian-stretch/Dockerfile b/build/docker/old/debian-stretch/Dockerfile
index 48db7e1..ebb5e24 100644
--- a/build/docker/old/debian-stretch/Dockerfile
+++ b/build/docker/old/debian-stretch/Dockerfile
@@ -102,7 +102,7 @@
 # project isn't ready for this quite yet:
 # RUN apt-get install -y --no-install-recommends \
 # `# dotnet core dependencies` \
-#       dotnet-sdk-2.0.0
+#       dotnet-sdk-5.0
 
 RUN apt-get install -y --no-install-recommends \
 `# Erlang dependencies` \
@@ -121,11 +121,6 @@
       golang-go
 
 RUN apt-get install -y --no-install-recommends \
-`# Haskell dependencies` \
-      ghc \
-      cabal-install
-
-RUN apt-get install -y --no-install-recommends \
 `# Haxe dependencies` \
       haxe \
       neko \
diff --git a/build/docker/old/ubuntu-artful/Dockerfile b/build/docker/old/ubuntu-artful/Dockerfile
index 813ef06..cb723a2 100644
--- a/build/docker/old/ubuntu-artful/Dockerfile
+++ b/build/docker/old/ubuntu-artful/Dockerfile
@@ -120,7 +120,7 @@
 
 RUN apt-get install -y --no-install-recommends \
 `# dotnet core dependencies` \
-      dotnet-sdk-2.1.4
+      dotnet-sdk-5.0
 
 RUN apt-get install -y --no-install-recommends \
 `# Erlang dependencies` \
@@ -145,11 +145,6 @@
                         rm golang.tar.gz
 
 RUN apt-get install -y --no-install-recommends \
-`# Haskell dependencies` \
-      ghc \
-      cabal-install
-
-RUN apt-get install -y --no-install-recommends \
 `# Haxe dependencies` \
       haxe \
       neko \
diff --git a/build/docker/old/ubuntu-trusty/Dockerfile b/build/docker/old/ubuntu-trusty/Dockerfile
index 96c1540..89f683e 100644
--- a/build/docker/old/ubuntu-trusty/Dockerfile
+++ b/build/docker/old/ubuntu-trusty/Dockerfile
@@ -119,11 +119,6 @@
       ln -s /usr/local/go/bin/go /usr/local/bin && \
       rm golang.tar.gz
 
-RUN apt-get install -y --no-install-recommends \
-`# Haskell dependencies` \
-      ghc \
-      cabal-install
-
 # disabled because it cores while installing
 # RUN apt-get install -y --no-install-recommends \
 # `# Haxe dependencies` \
diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile
index c8ecd8e..a11e9ba 100644
--- a/build/docker/ubuntu-bionic/Dockerfile
+++ b/build/docker/ubuntu-bionic/Dockerfile
@@ -118,7 +118,7 @@
     mv deimos-openssl-1.1.0h/C/* /usr/include/dmd/druntime/import/C/ && \
     rm -rf deimos-openssl-1.1.0h
 
-ENV DART_VERSION 2.4.0-1
+ENV DART_VERSION 2.7.2-1
 RUN apt-get install -y --no-install-recommends \
       `# Dart dependencies` \
       dart=$DART_VERSION
@@ -126,7 +126,7 @@
 
 RUN apt-get install -y --no-install-recommends \
 `# dotnet core dependencies` \
-      dotnet-sdk-3.1
+      dotnet-sdk-5.0
 
 RUN apt-get install -y --no-install-recommends \
 `# Erlang dependencies` \
@@ -140,9 +140,9 @@
       libglib2.0-dev
 
 # golang
-ENV GOLANG_VERSION 1.15.7
+ENV GOLANG_VERSION 1.16.2
 ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
-ENV GOLANG_DOWNLOAD_SHA256 0d142143794721bb63ce6c8a6180c4062bcf8ef4715e7d6d6609f3a8282629b3
+ENV GOLANG_DOWNLOAD_SHA256 542e936b19542e62679766194364f45141fde55169db2d8d01046555ca9eb4b8
 RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \
       echo "$GOLANG_DOWNLOAD_SHA256  golang.tar.gz" | sha256sum -c - && \
             tar -C /usr/local -xzf golang.tar.gz && \
@@ -150,11 +150,6 @@
                         rm golang.tar.gz
 
 RUN apt-get install -y --no-install-recommends \
-`# Haskell dependencies` \
-      ghc \
-      cabal-install
-
-RUN apt-get install -y --no-install-recommends \
 `# Haxe dependencies` \
       haxe \
       neko \
@@ -184,7 +179,8 @@
 # Test dependencies for running puppeteer
 RUN apt-get install -y --no-install-recommends \
 `# JS dependencies` \
-      libxss1
+      libxss1 \
+      libxtst6
 
 RUN apt-get install -y --no-install-recommends \
 `# OCaml dependencies` \
@@ -257,6 +253,14 @@
     rm swift-5.1.4-RELEASE-ubuntu18.04.tar.gz && \
     swift --version
 
+# Locale(s) for cpp unit tests
+RUN apt-get install -y --no-install-recommends \
+`# Locale dependencies` \
+      locales && \
+    locale-gen en_US.UTF-8 && \
+    locale-gen de_DE.UTF-8 && \
+    update-locale
+
 # cppcheck-1.82 has a nasty cpp parser bug, so we're using something newer
 RUN apt-get install -y --no-install-recommends \
 `# Static Code Analysis dependencies` \
diff --git a/build/docker/ubuntu-disco/Dockerfile b/build/docker/ubuntu-disco/Dockerfile
index 531718c..de99574 100644
--- a/build/docker/ubuntu-disco/Dockerfile
+++ b/build/docker/ubuntu-disco/Dockerfile
@@ -118,7 +118,7 @@
     mv deimos-openssl-1.1.0h/C/* /usr/include/dmd/druntime/import/C/ && \
     rm -rf deimos-openssl-1.1.0h
 
-ENV DART_VERSION 2.4.0-1
+ENV DART_VERSION 2.7.2-1
 RUN apt-get install -y --no-install-recommends \
       `# Dart dependencies` \
       dart=$DART_VERSION
@@ -126,7 +126,7 @@
 
 RUN apt-get install -y --no-install-recommends \
 `# dotnet core dependencies` \
-      dotnet-sdk-3.1
+      dotnet-sdk-5.0
 
 RUN apt-get install -y --no-install-recommends \
 `# Erlang dependencies` \
@@ -140,9 +140,9 @@
       libglib2.0-dev
 
 # golang
-ENV GOLANG_VERSION 1.15.7
+ENV GOLANG_VERSION 1.16.2
 ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
-ENV GOLANG_DOWNLOAD_SHA256 0d142143794721bb63ce6c8a6180c4062bcf8ef4715e7d6d6609f3a8282629b3
+ENV GOLANG_DOWNLOAD_SHA256 542e936b19542e62679766194364f45141fde55169db2d8d01046555ca9eb4b8
 RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \
       echo "$GOLANG_DOWNLOAD_SHA256  golang.tar.gz" | sha256sum -c - && \
             tar -C /usr/local -xzf golang.tar.gz && \
@@ -150,11 +150,6 @@
                         rm golang.tar.gz
 
 RUN apt-get install -y --no-install-recommends \
-`# Haskell dependencies` \
-      ghc \
-      cabal-install
-
-RUN apt-get install -y --no-install-recommends \
 `# Haxe dependencies` \
       haxe \
       neko \
@@ -184,7 +179,8 @@
 # Test dependencies for running puppeteer
 RUN apt-get install -y --no-install-recommends \
 `# JS dependencies` \
-      libxss1
+      libxss1 \
+      libxtst6
 
 # does not work on disco?
 # RUN apt-get install -y --no-install-recommends \
@@ -259,6 +255,14 @@
 #     rm swift-4.2.1-RELEASE-ubuntu18.04.tar.gz && \
 #     swift --version
 
+# Locale(s) for cpp unit tests
+RUN apt-get install -y --no-install-recommends \
+`# Locale dependencies` \
+      locales && \
+    locale-gen en_US.UTF-8 && \
+    locale-gen de_DE.UTF-8 && \
+    update-locale
+
 # cppcheck-1.82 has a nasty cpp parser bug, so we're using something newer
 # don't need this on disco, nobody uses it
 # RUN apt-get install -y --no-install-recommends \
diff --git a/build/docker/ubuntu-xenial/Dockerfile b/build/docker/ubuntu-xenial/Dockerfile
index e554c53..441b692 100644
--- a/build/docker/ubuntu-xenial/Dockerfile
+++ b/build/docker/ubuntu-xenial/Dockerfile
@@ -13,7 +13,7 @@
 #
 # Apache Thrift Docker build environment for Ubuntu Xenial
 # Using all stock Ubuntu Xenial packaging except for:
-# - d: does not come with Ubuntu so we're installing 2.075.1 for coverage
+# - d: does not come with Ubuntu so we're installing 2.087.0 for coverage
 # - dart: does not come with Ubuntu so we're installing 2.0.0-1 for coverage
 # - dotnet: does not come with Ubuntu
 # - go: Xenial comes with 1.6, but we need 1.10 or later
@@ -37,11 +37,6 @@
       software-properties-common \
       wget && \
 
-# D
-    apt-key adv --keyserver keyserver.ubuntu.com --recv-keys EBCF975E5BA24D5E && \
-    wget http://master.dl.sourceforge.net/project/d-apt/files/d-apt.list -O /etc/apt/sources.list.d/d-apt.list && \
-    wget -qO - https://dlang.org/d-keyring.gpg | apt-key add - && \
-
 # Dart
     curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - && \
     curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > \
@@ -93,28 +88,24 @@
       qtbase5-dev \
       qtbase5-dev-tools
 
-ENV D_VERSION 2.075.1-0
-RUN apt-get install -y --allow-unauthenticated --no-install-recommends \
+ENV D_VERSION     2.087.0
+ENV DMD_DEB       dmd_2.087.0-0_amd64.deb
+RUN \
 `# D dependencies` \
-      dmd-bin=$D_VERSION \
-      libphobos2-dev=$D_VERSION \
-      dub=1.6.0-0 \
-      dfmt \
-      dscanner \
-      libevent-dev \
-      libssl-dev \
-      xdg-utils
-RUN mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \
-    curl -sSL https://github.com/D-Programming-Deimos/libevent/archive/master.tar.gz| tar xz && \
-    mv libevent-master/deimos/* /usr/include/dmd/druntime/import/deimos/ && \
-    mv libevent-master/C/* /usr/include/dmd/druntime/import/C/ && \
-    rm -rf libevent-master
-RUN curl -sSL https://github.com/D-Programming-Deimos/openssl/archive/v1.1.6+1.0.1g.tar.gz | tar xz && \
-    mv openssl-1.1.6-1.0.1g/deimos/* /usr/include/dmd/druntime/import/deimos/ && \
-    mv openssl-1.1.6-1.0.1g/C/* /usr/include/dmd/druntime/import/C/ && \
-    rm -rf openssl-1.1.6-1.0.1g
+    wget -q http://downloads.dlang.org/releases/2.x/${D_VERSION}/${DMD_DEB} && \
+    dpkg --install ${DMD_DEB} && \
+    rm -f ${DMD_DEB} && \
+    mkdir -p /usr/include/dmd/druntime/import/deimos /usr/include/dmd/druntime/import/C && \
+    git clone -b 'v2.0.2+2.0.16' https://github.com/D-Programming-Deimos/libevent.git deimos-libevent-2.0 && \
+    mv deimos-libevent-2.0/deimos/* /usr/include/dmd/druntime/import/deimos/ && \
+    mv deimos-libevent-2.0/C/* /usr/include/dmd/druntime/import/C/ && \
+    rm -rf deimos-libevent-2.0 && \
+    git clone -b 'v1.1.6+1.0.1g' https://github.com/D-Programming-Deimos/openssl.git deimos-openssl-1.0.1g && \
+    mv deimos-openssl-1.0.1g/deimos/* /usr/include/dmd/druntime/import/deimos/ && \
+    mv deimos-openssl-1.0.1g/C/* /usr/include/dmd/druntime/import/C/ && \
+    rm -rf deimos-openssl-1.0.1g
 
-ENV DART_VERSION 2.0.0-1
+ENV DART_VERSION 2.7.2-1
 RUN apt-get install -y --no-install-recommends \
 `# Dart dependencies` \
       dart=$DART_VERSION
@@ -122,7 +113,7 @@
 
 RUN apt-get install -y --no-install-recommends \
 `# dotnet core dependencies` \
-      dotnet-sdk-3.1
+      dotnet-sdk-5.0
 
 RUN apt-get install -y --no-install-recommends \
 `# Erlang dependencies` \
@@ -137,27 +128,15 @@
       libglib2.0-dev
 
 # golang
-ENV GOLANG_VERSION 1.14.14
+ENV GOLANG_VERSION 1.15.10
 ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
-ENV GOLANG_DOWNLOAD_SHA256 6f1354c9040d65d1622b451f43c324c1e5197aa9242d00c5a117d0e2625f3e0d
+ENV GOLANG_DOWNLOAD_SHA256 4aa1267517df32f2bf1cc3d55dfc27d0c6b2c2b0989449c96dd19273ccca051d
 RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz && \
       echo "$GOLANG_DOWNLOAD_SHA256  golang.tar.gz" | sha256sum -c - && \
       tar -C /usr/local -xzf golang.tar.gz && \
       ln -s /usr/local/go/bin/go /usr/local/bin && \
       rm golang.tar.gz
 
-# cabal 1.22 in xenial is too old so we grab a pre-built 1.24 binary
-RUN apt-get install -y --no-install-recommends \
-`# Haskell dependencies` \
-      ghc && \
-    cd /tmp && \
-    wget -q https://www.haskell.org/cabal/release/cabal-install-1.24.0.2/cabal-install-1.24.0.2-x86_64-unknown-linux.tar.gz && \
-    tar xzf cabal-install-1.24.0.2-x86_64-unknown-linux.tar.gz && \
-    find dist-newstyle/ -type f -name cabal -exec mv {} /usr/bin \; && \
-    rm -rf /tmp/cabal* && \
-    cabal --version && \
-    cabal update
-
 RUN apt-get install -y --no-install-recommends \
 `# Haxe dependencies` \
       haxe \
@@ -191,6 +170,7 @@
 RUN apt-get install -y --no-install-recommends \
 `# JS dependencies` \
       libxss1 \
+      libxtst6 \
       libatk-bridge2.0-0 \
       libgtk-3-0
 
@@ -255,6 +235,14 @@
 # Rust dependencies
 RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain 1.40.0 -y
 
+# Locale(s) for cpp unit tests
+RUN apt-get install -y --no-install-recommends \
+`# Locale dependencies` \
+      locales && \
+    locale-gen en_US.UTF-8 && \
+    locale-gen de_DE.UTF-8 && \
+    update-locale
+
 # Clean up
 RUN rm -rf /var/cache/apt/* && \
     rm -rf /var/lib/apt/lists/* && \
diff --git a/build/veralign.sh b/build/veralign.sh
index 9f51f22..3823e2d 100755
--- a/build/veralign.sh
+++ b/build/veralign.sh
@@ -65,13 +65,14 @@
 FILES[lib/delphi/src/Thrift.pas]=simpleReplace
 FILES[lib/erl/src/thrift.app.src]=simpleReplace
 FILES[lib/haxe/haxelib.json]=simpleReplace
-FILES[lib/hs/thrift.cabal]=simpleReplace
 FILES[lib/java/gradle.properties]=simpleReplace
 FILES[lib/js/package-lock.json]=jsonReplace
 FILES[lib/js/package.json]=jsonReplace
 FILES[lib/js/src/thrift.js]=simpleReplace
 FILES[lib/lua/Thrift.lua]=simpleReplace
-FILES[lib/netstd/Thrift/Properties/AssemblyInfo.cs]=simpleReplace
+FILES[lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj]=simpleReplace
+FILES[lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj]=simpleReplace
+FILES[lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj]=simpleReplace
 FILES[lib/netstd/Thrift/Properties/AssemblyInfo.cs]=simpleReplace
 FILES[lib/netstd/Thrift/Thrift.csproj]=simpleReplace
 FILES[lib/ocaml/_oasis]=simpleReplace
@@ -89,13 +90,17 @@
 FILES[sonar-project.properties]=simpleReplace
 FILES[test/dart/test_client/pubspec.yaml]=pubspecReplace
 FILES[test/erl/src/thrift_test.app.src]=simpleReplace
+FILES[test/netstd/Client/Client.csproj]=simpleReplace
+FILES[test/netstd/Server/Server.csproj]=simpleReplace
 FILES[Thrift.podspec]=simpleReplace
 FILES[tutorial/dart/client/pubspec.yaml]=pubspecReplace
 FILES[tutorial/dart/console_client/pubspec.yaml]=pubspecReplace
 FILES[tutorial/dart/server/pubspec.yaml]=pubspecReplace
 FILES[tutorial/delphi/DelphiClient/DelphiClient.dproj]=simpleReplace
 FILES[tutorial/delphi/DelphiServer/DelphiServer.dproj]=simpleReplace
-FILES[tutorial/hs/ThriftTutorial.cabal]=simpleReplace
+FILES[tutorial/netstd/Client/Client.csproj]=simpleReplace
+FILES[tutorial/netstd/Interfaces/Interfaces.csproj]=simpleReplace
+FILES[tutorial/netstd/Server/Server.csproj]=simpleReplace
 FILES[tutorial/ocaml/_oasis]=simpleReplace
 
 
diff --git a/compiler/cpp/CMakeLists.txt b/compiler/cpp/CMakeLists.txt
index 0675f0e..df34637 100644
--- a/compiler/cpp/CMakeLists.txt
+++ b/compiler/cpp/CMakeLists.txt
@@ -72,7 +72,6 @@
 endmacro()
 
 # The following compiler can be enabled or disabled
-THRIFT_ADD_COMPILER(as3     "Enable compiler for ActionScript 3" ON)
 THRIFT_ADD_COMPILER(c_glib  "Enable compiler for C with Glib" ON)
 THRIFT_ADD_COMPILER(cl      "Enable compiler for Common LISP" ON)
 THRIFT_ADD_COMPILER(cpp     "Enable compiler for C++" ON)
@@ -83,7 +82,6 @@
 THRIFT_ADD_COMPILER(go      "Enable compiler for Go" ON)
 THRIFT_ADD_COMPILER(gv      "Enable compiler for GraphViz" ON)
 THRIFT_ADD_COMPILER(haxe    "Enable compiler for Haxe" ON)
-THRIFT_ADD_COMPILER(hs      "Enable compiler for Haskell" ON)
 THRIFT_ADD_COMPILER(html    "Enable compiler for HTML Documentation" ON)
 THRIFT_ADD_COMPILER(markdown "Enable compiler for Markdown Documentation" ON)
 THRIFT_ADD_COMPILER(java    "Enable compiler for Java"   ON)
diff --git a/compiler/cpp/Makefile.am b/compiler/cpp/Makefile.am
index 05c9121..74def54 100644
--- a/compiler/cpp/Makefile.am
+++ b/compiler/cpp/Makefile.am
@@ -69,8 +69,7 @@
                  src/thrift/platform.h
 
 # Specific client generator source
-thrift_SOURCES += src/thrift/generate/t_as3_generator.cc \
-                  src/thrift/generate/t_c_glib_generator.cc \
+thrift_SOURCES += src/thrift/generate/t_c_glib_generator.cc \
                   src/thrift/generate/t_cl_generator.cc \
                   src/thrift/generate/t_cpp_generator.cc \
                   src/thrift/generate/t_d_generator.cc \
@@ -80,7 +79,6 @@
                   src/thrift/generate/t_go_generator.cc \
                   src/thrift/generate/t_gv_generator.cc \
                   src/thrift/generate/t_haxe_generator.cc \
-                  src/thrift/generate/t_hs_generator.cc \
                   src/thrift/generate/t_html_generator.cc \
                   src/thrift/generate/t_markdown_generator.cc \
                   src/thrift/generate/t_java_generator.cc \
diff --git a/compiler/cpp/compiler.vcxproj b/compiler/cpp/compiler.vcxproj
index dc9793f..423c55e 100644
--- a/compiler/cpp/compiler.vcxproj
+++ b/compiler/cpp/compiler.vcxproj
@@ -53,7 +53,6 @@
   <ItemGroup>
     <ClCompile Include="src\thrift\audit\t_audit.cpp" />
     <ClCompile Include="src\thrift\common.cc" />
-    <ClCompile Include="src\thrift\generate\t_as3_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_c_glib_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_cl_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_cpp_generator.cc" />
@@ -65,7 +64,6 @@
     <ClCompile Include="src\thrift\generate\t_go_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_gv_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_haxe_generator.cc" />
-    <ClCompile Include="src\thrift\generate\t_hs_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_html_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_markdown_generator.cc" />
     <ClCompile Include="src\thrift\generate\t_java_generator.cc" />
diff --git a/compiler/cpp/compiler.vcxproj.filters b/compiler/cpp/compiler.vcxproj.filters
index 360c446..546d0fd 100644
--- a/compiler/cpp/compiler.vcxproj.filters
+++ b/compiler/cpp/compiler.vcxproj.filters
@@ -92,9 +92,6 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="src\audit\t_audit.cpp"/>
-    <ClCompile Include="src\generate\t_as3_generator.cc">
-      <Filter>generate</Filter>
-    </ClCompile>
     <ClCompile Include="src\generate\t_cocoa_generator.cc">
       <Filter>generate</Filter>
     </ClCompile>
@@ -128,9 +125,6 @@
     <ClCompile Include="src\generate\t_haxe_generator.cc">
       <Filter>generate</Filter>
     </ClCompile>
-    <ClCompile Include="src\generate\t_hs_generator.cc">
-      <Filter>generate</Filter>
-    </ClCompile>
     <ClCompile Include="src\generate\t_html_generator.cc">
       <Filter>generate</Filter>
     </ClCompile>
diff --git a/compiler/cpp/src/thrift/generate/t_as3_generator.cc b/compiler/cpp/src/thrift/generate/t_as3_generator.cc
deleted file mode 100644
index fa2967b..0000000
--- a/compiler/cpp/src/thrift/generate/t_as3_generator.cc
+++ /dev/null
@@ -1,2592 +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.
- */
-
-#include <sstream>
-#include <string>
-#include <fstream>
-#include <iostream>
-#include <vector>
-#include <cctype>
-
-#include <sys/stat.h>
-#include <stdexcept>
-
-#include "thrift/platform.h"
-#include "thrift/generate/t_oop_generator.h"
-
-using std::map;
-using std::ostream;
-using std::ostringstream;
-using std::string;
-using std::stringstream;
-using std::vector;
-
-static const string endl = "\n"; // avoid ostream << std::endl flushes
-
-/**
- * AS3 code generator.
- *
- */
-class t_as3_generator : public t_oop_generator {
-public:
-  t_as3_generator(t_program* program,
-                  const std::map<std::string, std::string>& parsed_options,
-                  const std::string& option_string)
-    : t_oop_generator(program) {
-    (void)option_string;
-    std::map<std::string, std::string>::const_iterator iter;
-
-    bindable_ = false;
-    for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
-      if( iter->first.compare("bindable") == 0) {
-        bindable_ = true;
-      } else {
-        throw "unknown option as3:" + iter->first;
-      }
-    }
-
-    out_dir_base_ = "gen-as3";
-  }
-
-  /**
-   * Init and close methods
-   */
-
-  void init_generator() override;
-  void close_generator() override;
-
-  void generate_consts(std::vector<t_const*> consts) override;
-
-  /**
-   * Program-level generation functions
-   */
-
-  void generate_typedef(t_typedef* ttypedef) override;
-  void generate_enum(t_enum* tenum) override;
-  void generate_struct(t_struct* tstruct) override;
-  void generate_xception(t_struct* txception) override;
-  void generate_service(t_service* tservice) override;
-
-  void print_const_value(std::ostream& out,
-                         std::string name,
-                         t_type* type,
-                         t_const_value* value,
-                         bool in_static,
-                         bool defval = false);
-  std::string render_const_value(ostream& out,
-                                 std::string name,
-                                 t_type* type,
-                                 t_const_value* value);
-
-  /**
-   * Service-level generation functions
-   */
-
-  void generate_as3_struct(t_struct* tstruct, bool is_exception);
-
-  void generate_as3_struct_definition(std::ostream& out,
-                                      t_struct* tstruct,
-                                      bool is_xception = false,
-                                      bool in_class = false,
-                                      bool is_result = false);
-  // removed -- equality,compare_to
-  void generate_as3_struct_reader(std::ostream& out, t_struct* tstruct);
-  void generate_as3_validator(std::ostream& out, t_struct* tstruct);
-  void generate_as3_struct_result_writer(std::ostream& out, t_struct* tstruct);
-  void generate_as3_struct_writer(std::ostream& out, t_struct* tstruct);
-  void generate_as3_struct_tostring(std::ostream& out, t_struct* tstruct, bool bindable);
-  void generate_as3_meta_data_map(std::ostream& out, t_struct* tstruct);
-  void generate_field_value_meta_data(std::ostream& out, t_type* type);
-  std::string get_as3_type_string(t_type* type);
-  void generate_reflection_setters(std::ostringstream& out,
-                                   t_type* type,
-                                   std::string field_name,
-                                   std::string cap_name);
-  void generate_reflection_getters(std::ostringstream& out,
-                                   t_type* type,
-                                   std::string field_name,
-                                   std::string cap_name);
-  void generate_generic_field_getters_setters(std::ostream& out, t_struct* tstruct);
-  void generate_generic_isset_method(std::ostream& out, t_struct* tstruct);
-  void generate_as3_bean_boilerplate(std::ostream& out, t_struct* tstruct, bool bindable);
-
-  void generate_function_helpers(t_function* tfunction);
-  std::string get_cap_name(std::string name);
-  std::string generate_isset_check(t_field* field);
-  std::string generate_isset_check(std::string field);
-  void generate_isset_set(ostream& out, t_field* field);
-  // removed std::string isset_field_id(t_field* field);
-
-  void generate_service_interface(t_service* tservice);
-  void generate_service_helpers(t_service* tservice);
-  void generate_service_client(t_service* tservice);
-  void generate_service_server(t_service* tservice);
-  void generate_process_function(t_service* tservice, t_function* tfunction);
-
-  /**
-   * Serialization constructs
-   */
-
-  void generate_deserialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
-
-  void generate_deserialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
-
-  void generate_deserialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
-
-  void generate_deserialize_set_element(std::ostream& out, t_set* tset, std::string prefix = "");
-
-  void generate_deserialize_map_element(std::ostream& out, t_map* tmap, std::string prefix = "");
-
-  void generate_deserialize_list_element(std::ostream& out,
-                                         t_list* tlist,
-                                         std::string prefix = "");
-
-  void generate_serialize_field(std::ostream& out, t_field* tfield, std::string prefix = "");
-
-  void generate_serialize_struct(std::ostream& out, t_struct* tstruct, std::string prefix = "");
-
-  void generate_serialize_container(std::ostream& out, t_type* ttype, std::string prefix = "");
-
-  void generate_serialize_map_element(std::ostream& out,
-                                      t_map* tmap,
-                                      std::string iter,
-                                      std::string map);
-
-  void generate_serialize_set_element(std::ostream& out, t_set* tmap, std::string iter);
-
-  void generate_serialize_list_element(std::ostream& out, t_list* tlist, std::string iter);
-
-  void generate_as3_doc(std::ostream& out, t_doc* tdoc);
-
-  void generate_as3_doc(std::ostream& out, t_function* tdoc);
-
-  /**
-   * Helper rendering functions
-   */
-
-  std::string as3_package();
-  std::string as3_type_imports();
-  std::string as3_thrift_imports();
-  std::string as3_thrift_gen_imports(t_struct* tstruct, string& imports);
-  std::string as3_thrift_gen_imports(t_service* tservice);
-  std::string type_name(t_type* ttype, bool in_container = false, bool in_init = false);
-  std::string base_type_name(t_base_type* tbase, bool in_container = false);
-  std::string declare_field(t_field* tfield, bool init = false);
-  std::string function_signature(t_function* tfunction, std::string prefix = "");
-  std::string argument_list(t_struct* tstruct);
-  std::string type_to_enum(t_type* ttype);
-  std::string get_enum_class_name(t_type* type) override;
-
-  bool type_can_be_null(t_type* ttype) {
-    ttype = get_true_type(ttype);
-
-    return ttype->is_container() || ttype->is_struct() || ttype->is_xception()
-           || ttype->is_string();
-  }
-
-  std::string constant_name(std::string name);
-
-private:
-  /**
-   * File streams
-   */
-
-  std::string package_name_;
-  ofstream_with_content_based_conditional_update f_service_;
-  std::string package_dir_;
-
-  bool bindable_;
-};
-
-/**
- * Prepares for file generation by opening up the necessary file output
- * streams.
- *
- * @param tprogram The program to generate
- */
-void t_as3_generator::init_generator() {
-  // Make output directory
-  MKDIR(get_out_dir().c_str());
-  package_name_ = program_->get_namespace("as3");
-
-  string dir = package_name_;
-  string subdir = get_out_dir();
-  string::size_type loc;
-  while ((loc = dir.find(".")) != string::npos) {
-    subdir = subdir + "/" + dir.substr(0, loc);
-    MKDIR(subdir.c_str());
-    dir = dir.substr(loc + 1);
-  }
-  if (dir.size() > 0) {
-    subdir = subdir + "/" + dir;
-    MKDIR(subdir.c_str());
-  }
-
-  package_dir_ = subdir;
-}
-
-/**
- * Packages the generated file
- *
- * @return String of the package, i.e. "package org.apache.thriftdemo;"
- */
-string t_as3_generator::as3_package() {
-  if (!package_name_.empty()) {
-    return string("package ") + package_name_ + " ";
-  }
-  return "package ";
-}
-
-/**
- * Prints standard as3 imports
- *
- * @return List of imports for As3 types that are used in here
- */
-string t_as3_generator::as3_type_imports() {
-  return string() + "import org.apache.thrift.Set;\n" + "import flash.utils.ByteArray;\n"
-         + "import flash.utils.Dictionary;\n\n";
-}
-
-/**
- * Prints standard as3 imports
- *
- * @return List of imports necessary for thrift
- */
-string t_as3_generator::as3_thrift_imports() {
-  return string() + "import org.apache.thrift.*;\n" + "import org.apache.thrift.meta_data.*;\n"
-         + "import org.apache.thrift.protocol.*;\n\n";
-}
-
-/**
- * Prints imports needed for a given type
- *
- * @return List of imports necessary for a given t_struct
- */
-string t_as3_generator::as3_thrift_gen_imports(t_struct* tstruct, string& imports) {
-
-  const vector<t_field*>& members = tstruct->get_members();
-  vector<t_field*>::const_iterator m_iter;
-
-  // For each type check if it is from a differnet namespace
-  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-    t_program* program = (*m_iter)->get_type()->get_program();
-    if (program != nullptr && program != program_) {
-      string package = program->get_namespace("as3");
-      if (!package.empty()) {
-        if (imports.find(package + "." + (*m_iter)->get_type()->get_name()) == string::npos) {
-          imports.append("import " + package + "." + (*m_iter)->get_type()->get_name() + ";\n");
-        }
-      }
-    }
-  }
-  return imports;
-}
-
-/**
- * Prints imports needed for a given type
- *
- * @return List of imports necessary for a given t_service
- */
-string t_as3_generator::as3_thrift_gen_imports(t_service* tservice) {
-  string imports;
-  const vector<t_function*>& functions = tservice->get_functions();
-  vector<t_function*>::const_iterator f_iter;
-
-  // For each type check if it is from a differnet namespace
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    t_program* program = (*f_iter)->get_returntype()->get_program();
-    if (program != nullptr && program != program_) {
-      string package = program->get_namespace("as3");
-      if (!package.empty()) {
-        if (imports.find(package + "." + (*f_iter)->get_returntype()->get_name()) == string::npos) {
-          imports.append("import " + package + "." + (*f_iter)->get_returntype()->get_name()
-                         + ";\n");
-        }
-      }
-    }
-
-    as3_thrift_gen_imports((*f_iter)->get_arglist(), imports);
-    as3_thrift_gen_imports((*f_iter)->get_xceptions(), imports);
-  }
-
-  return imports;
-}
-
-/**
- * Nothing in As3
- */
-void t_as3_generator::close_generator() {
-}
-
-/**
- * Generates a typedef. This is not done in As3, since it does
- * not support arbitrary name replacements, and it'd be a wacky waste
- * of overhead to make wrapper classes.
- *
- * @param ttypedef The type definition
- */
-void t_as3_generator::generate_typedef(t_typedef* ttypedef) {
-  (void)ttypedef;
-}
-
-/**
- * Enums are a class with a set of static constants.
- *
- * @param tenum The enumeration
- */
-void t_as3_generator::generate_enum(t_enum* tenum) {
-  // Make output file
-  string f_enum_name = package_dir_ + "/" + (tenum->get_name()) + ".as";
-  ofstream_with_content_based_conditional_update f_enum;
-  f_enum.open(f_enum_name);
-
-  // Comment and package it
-  f_enum << autogen_comment() << as3_package() << endl;
-
-  scope_up(f_enum);
-  // Add as3 imports
-  f_enum << string() + "import org.apache.thrift.Set;" << endl << "import flash.utils.Dictionary;"
-         << endl;
-
-  indent(f_enum) << "public class " << tenum->get_name() << " ";
-  scope_up(f_enum);
-
-  vector<t_enum_value*> constants = tenum->get_constants();
-  vector<t_enum_value*>::iterator c_iter;
-  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-    int value = (*c_iter)->get_value();
-    indent(f_enum) << "public static const " << (*c_iter)->get_name() << ":int = " << value << ";"
-                   << endl;
-  }
-
-  // Create a static Set with all valid values for this enum
-  f_enum << endl;
-
-  indent(f_enum) << "public static const VALID_VALUES:Set = new Set(";
-  indent_up();
-  bool firstValue = true;
-  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-    // populate set
-    f_enum << (firstValue ? "" : ", ") << (*c_iter)->get_name();
-    firstValue = false;
-  }
-  indent_down();
-  f_enum << ");" << endl;
-
-  indent(f_enum) << "public static const VALUES_TO_NAMES:Dictionary = new Dictionary();" << endl;
-
-  scope_up(f_enum);
-  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-    indent(f_enum) << "VALUES_TO_NAMES[" << (*c_iter)->get_name() << "] = \""
-                   << (*c_iter)->get_name() << "\";" << endl;
-  }
-  f_enum << endl;
-
-  scope_down(f_enum);
-
-  scope_down(f_enum); // end class
-
-  scope_down(f_enum); // end package
-
-  f_enum.close();
-}
-
-/**
- * Generates a class that holds all the constants.
- */
-void t_as3_generator::generate_consts(std::vector<t_const*> consts) {
-  if (consts.empty()) {
-    return;
-  }
-
-  string f_consts_name = package_dir_ + "/" + program_name_ + "Constants.as";
-  ofstream_with_content_based_conditional_update f_consts;
-  f_consts.open(f_consts_name);
-
-  // Print header
-  f_consts << autogen_comment() << as3_package();
-
-  scope_up(f_consts);
-  f_consts << endl;
-
-  f_consts << as3_type_imports();
-
-  indent(f_consts) << "public class " << program_name_ << "Constants {" << endl << endl;
-  indent_up();
-  vector<t_const*>::iterator c_iter;
-  for (c_iter = consts.begin(); c_iter != consts.end(); ++c_iter) {
-    print_const_value(f_consts,
-                      (*c_iter)->get_name(),
-                      (*c_iter)->get_type(),
-                      (*c_iter)->get_value(),
-                      false);
-  }
-  indent_down();
-  indent(f_consts) << "}" << endl;
-  scope_down(f_consts);
-  f_consts.close();
-}
-
-void t_as3_generator::print_const_value(std::ostream& out,
-                                        string name,
-                                        t_type* type,
-                                        t_const_value* value,
-                                        bool in_static,
-                                        bool defval) {
-  type = get_true_type(type);
-
-  indent(out);
-  if (!defval) {
-    out << (in_static ? "var " : "public static const ");
-  }
-  if (type->is_base_type()) {
-    string v2 = render_const_value(out, name, type, value);
-    out << name;
-    if (!defval) {
-      out << ":" << type_name(type);
-    }
-    out << " = " << v2 << ";" << endl << endl;
-  } else if (type->is_enum()) {
-    out << name;
-    if (!defval) {
-      out << ":" << type_name(type);
-    }
-    out << " = " << value->get_integer() << ";" << endl << endl;
-  } else if (type->is_struct() || type->is_xception()) {
-    const vector<t_field*>& fields = ((t_struct*)type)->get_members();
-    vector<t_field*>::const_iterator f_iter;
-    const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
-    map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
-    out << name << ":" << type_name(type) << " = new " << type_name(type, false, true) << "();"
-        << endl;
-    if (!in_static) {
-      indent(out) << "{" << endl;
-      indent_up();
-      indent(out) << "new function():void {" << endl;
-      indent_up();
-    }
-    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
-      t_type* field_type = nullptr;
-      for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-        if ((*f_iter)->get_name() == v_iter->first->get_string()) {
-          field_type = (*f_iter)->get_type();
-        }
-      }
-      if (field_type == nullptr) {
-        throw "type error: " + type->get_name() + " has no field " + v_iter->first->get_string();
-      }
-      string val = render_const_value(out, name, field_type, v_iter->second);
-      indent(out) << name << ".";
-      out << v_iter->first->get_string() << " = " << val << ";" << endl;
-    }
-    if (!in_static) {
-      indent_down();
-      indent(out) << "}();" << endl;
-      indent_down();
-      indent(out) << "}" << endl;
-    }
-    out << endl;
-  } else if (type->is_map()) {
-    out << name;
-    if (!defval) {
-      out << ":" << type_name(type);
-    }
-    out << " = new " << type_name(type, false, true) << "();" << endl;
-    if (!in_static) {
-      indent(out) << "{" << endl;
-      indent_up();
-      indent(out) << "new function():void {" << endl;
-      indent_up();
-    }
-    t_type* ktype = ((t_map*)type)->get_key_type();
-    t_type* vtype = ((t_map*)type)->get_val_type();
-    const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
-    map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
-    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
-      string key = render_const_value(out, name, ktype, v_iter->first);
-      string val = render_const_value(out, name, vtype, v_iter->second);
-      indent(out) << name << "[" << key << "] = " << val << ";" << endl;
-    }
-    if (!in_static) {
-      indent_down();
-      indent(out) << "}();" << endl;
-      indent_down();
-      indent(out) << "}" << endl;
-    }
-    out << endl;
-  } else if (type->is_list() || type->is_set()) {
-    out << name;
-    if (!defval) {
-      out << ":" << type_name(type);
-    }
-    out << " = new " << type_name(type, false, true) << "();" << endl;
-    if (!in_static) {
-      indent(out) << "{" << endl;
-      indent_up();
-      indent(out) << "new function():void {" << endl;
-      indent_up();
-    }
-    t_type* etype;
-    if (type->is_list()) {
-      etype = ((t_list*)type)->get_elem_type();
-    } else {
-      etype = ((t_set*)type)->get_elem_type();
-    }
-    const vector<t_const_value*>& val = value->get_list();
-    vector<t_const_value*>::const_iterator v_iter;
-    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
-      string val = render_const_value(out, name, etype, *v_iter);
-      indent(out) << name << "." << (type->is_list() ? "push" : "add") << "(" << val << ");"
-                  << endl;
-    }
-    if (!in_static) {
-      indent_down();
-      indent(out) << "}();" << endl;
-      indent_down();
-      indent(out) << "}" << endl;
-    }
-    out << endl;
-  } else {
-    throw "compiler error: no const of type " + type->get_name();
-  }
-}
-
-string t_as3_generator::render_const_value(ostream& out,
-                                           string name,
-                                           t_type* type,
-                                           t_const_value* value) {
-  (void)name;
-  type = get_true_type(type);
-  std::ostringstream render;
-
-  if (type->is_base_type()) {
-    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-    switch (tbase) {
-    case t_base_type::TYPE_STRING:
-      render << '"' << get_escaped_string(value) << '"';
-      break;
-    case t_base_type::TYPE_BOOL:
-      render << ((value->get_integer() > 0) ? "true" : "false");
-      break;
-    case t_base_type::TYPE_I8:
-      render << "(byte)" << value->get_integer();
-      break;
-    case t_base_type::TYPE_I16:
-      render << "(short)" << value->get_integer();
-      break;
-    case t_base_type::TYPE_I32:
-      render << value->get_integer();
-      break;
-    case t_base_type::TYPE_I64:
-      render << value->get_integer() << "L";
-      break;
-    case t_base_type::TYPE_DOUBLE:
-      if (value->get_type() == t_const_value::CV_INTEGER) {
-        render << "(double)" << value->get_integer();
-      } else {
-        render << value->get_double();
-      }
-      break;
-    default:
-      throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
-    }
-  } else if (type->is_enum()) {
-    render << value->get_integer();
-  } else {
-    string t = tmp("tmp");
-    print_const_value(out, t, type, value, true);
-    render << t;
-  }
-
-  return render.str();
-}
-
-/**
- * Generates a struct definition for a thrift data type. This is a class
- * with data members, read(), write(), and an inner Isset class.
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_struct(t_struct* tstruct) {
-  generate_as3_struct(tstruct, false);
-}
-
-/**
- * Exceptions are structs, but they inherit from Exception
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_xception(t_struct* txception) {
-  generate_as3_struct(txception, true);
-}
-
-/**
- * As3 struct definition.
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_as3_struct(t_struct* tstruct, bool is_exception) {
-  // Make output file
-  string f_struct_name = package_dir_ + "/" + (tstruct->get_name()) + ".as";
-  ofstream_with_content_based_conditional_update f_struct;
-  f_struct.open(f_struct_name.c_str());
-
-  f_struct << autogen_comment() << as3_package();
-
-  scope_up(f_struct);
-  f_struct << endl;
-
-  string imports;
-
-  f_struct << as3_type_imports() << as3_thrift_imports() << as3_thrift_gen_imports(tstruct, imports)
-           << endl;
-
-  if (bindable_ && !is_exception) {
-    f_struct << "import flash.events.Event;" << endl << "import flash.events.EventDispatcher;"
-             << endl << "import mx.events.PropertyChangeEvent;" << endl;
-  }
-
-  generate_as3_struct_definition(f_struct, tstruct, is_exception);
-
-  scope_down(f_struct); // end of package
-  f_struct.close();
-}
-
-/**
- * As3 struct definition. This has various parameters, as it could be
- * generated standalone or inside another class as a helper. If it
- * is a helper than it is a static class.
- *
- * @param tstruct      The struct definition
- * @param is_exception Is this an exception?
- * @param in_class     If inside a class, needs to be static class
- * @param is_result    If this is a result it needs a different writer
- */
-void t_as3_generator::generate_as3_struct_definition(ostream& out,
-                                                     t_struct* tstruct,
-                                                     bool is_exception,
-                                                     bool in_class,
-                                                     bool is_result) {
-  generate_as3_doc(out, tstruct);
-
-  bool is_final = (tstruct->annotations_.find("final") != tstruct->annotations_.end());
-  bool bindable = !is_exception && !in_class && bindable_;
-
-  indent(out) << (in_class ? "" : "public ") << (is_final ? "final " : "") << "class "
-              << tstruct->get_name() << " ";
-
-  if (is_exception) {
-    out << "extends Error ";
-  } else if (bindable) {
-    out << "extends EventDispatcher ";
-  }
-  out << "implements TBase ";
-
-  scope_up(out);
-
-  indent(out) << "private static const STRUCT_DESC:TStruct = new TStruct(\"" << tstruct->get_name()
-              << "\");" << endl;
-
-  // Members are public for -as3, private for -as3bean
-  const vector<t_field*>& members = tstruct->get_members();
-  vector<t_field*>::const_iterator m_iter;
-
-  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-    indent(out) << "private static const " << constant_name((*m_iter)->get_name())
-                << "_FIELD_DESC:TField = new TField(\"" << (*m_iter)->get_name() << "\", "
-                << type_to_enum((*m_iter)->get_type()) << ", " << (*m_iter)->get_key() << ");"
-                << endl;
-  }
-
-  out << endl;
-
-  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-    generate_as3_doc(out, *m_iter);
-    indent(out) << "private var _" << (*m_iter)->get_name() + ":" + type_name((*m_iter)->get_type())
-                << ";" << endl;
-
-    indent(out) << "public static const " << upcase_string((*m_iter)->get_name())
-                << ":int = " << (*m_iter)->get_key() << ";" << endl;
-  }
-
-  out << endl;
-
-  // Inner Isset class
-  if (members.size() > 0) {
-    for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-      if (!type_can_be_null((*m_iter)->get_type())) {
-        indent(out) << "private var __isset_" << (*m_iter)->get_name() << ":Boolean = false;"
-                    << endl;
-      }
-    }
-  }
-
-  out << endl;
-
-  generate_as3_meta_data_map(out, tstruct);
-
-  // Static initializer to populate global class to struct metadata map
-  indent(out) << "{" << endl;
-  indent_up();
-  indent(out) << "FieldMetaData.addStructMetaDataMap(" << type_name(tstruct) << ", metaDataMap);"
-              << endl;
-  indent_down();
-  indent(out) << "}" << endl << endl;
-
-  // Default constructor
-  indent(out) << "public function " << tstruct->get_name() << "() {" << endl;
-  indent_up();
-  for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
-    if ((*m_iter)->get_value() != nullptr) {
-      indent(out) << "this._" << (*m_iter)->get_name() << " = "
-                  << (*m_iter)->get_value()->get_integer() << ";" << endl;
-    }
-  }
-  indent_down();
-  indent(out) << "}" << endl << endl;
-
-  generate_as3_bean_boilerplate(out, tstruct, bindable);
-  generate_generic_field_getters_setters(out, tstruct);
-  generate_generic_isset_method(out, tstruct);
-
-  generate_as3_struct_reader(out, tstruct);
-  if (is_result) {
-    generate_as3_struct_result_writer(out, tstruct);
-  } else {
-    generate_as3_struct_writer(out, tstruct);
-  }
-  generate_as3_struct_tostring(out, tstruct, bindable);
-  generate_as3_validator(out, tstruct);
-  scope_down(out);
-  out << endl;
-}
-
-/**
- * Generates a function to read all the fields of the struct.
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_as3_struct_reader(ostream& out, t_struct* tstruct) {
-  out << indent() << "public function read(iprot:TProtocol):void {" << endl;
-  indent_up();
-
-  const vector<t_field*>& fields = tstruct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-
-  // Declare stack tmp variables and read struct header
-  out << indent() << "var field:TField;" << endl << indent() << "iprot.readStructBegin();" << endl;
-
-  // Loop over reading in fields
-  indent(out) << "while (true)" << endl;
-  scope_up(out);
-
-  // Read beginning field marker
-  indent(out) << "field = iprot.readFieldBegin();" << endl;
-
-  // Check for field STOP marker and break
-  indent(out) << "if (field.type == TType.STOP) { " << endl;
-  indent_up();
-  indent(out) << "break;" << endl;
-  indent_down();
-  indent(out) << "}" << endl;
-
-  // Switch statement on the field we are reading
-  indent(out) << "switch (field.id)" << endl;
-
-  scope_up(out);
-
-  // Generate deserialization code for known cases
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    indent(out) << "case " << upcase_string((*f_iter)->get_name()) << ":" << endl;
-    indent_up();
-    indent(out) << "if (field.type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl;
-    indent_up();
-
-    generate_deserialize_field(out, *f_iter, "this.");
-    generate_isset_set(out, *f_iter);
-    indent_down();
-    out << indent() << "} else { " << endl << indent() << "  TProtocolUtil.skip(iprot, field.type);"
-        << endl << indent() << "}" << endl << indent() << "break;" << endl;
-    indent_down();
-  }
-
-  // In the default case we skip the field
-  out << indent() << "default:" << endl << indent() << "  TProtocolUtil.skip(iprot, field.type);"
-      << endl << indent() << "  break;" << endl;
-
-  scope_down(out);
-
-  // Read field end marker
-  indent(out) << "iprot.readFieldEnd();" << endl;
-
-  scope_down(out);
-
-  out << indent() << "iprot.readStructEnd();" << endl << endl;
-
-  // in non-beans style, check for required fields of primitive type
-  // (which can be checked here but not in the general validate method)
-  out << endl << indent() << "// check for required fields of primitive type, which can't be "
-                             "checked in the validate method" << endl;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    if ((*f_iter)->get_req() == t_field::T_REQUIRED && !type_can_be_null((*f_iter)->get_type())) {
-      out << indent() << "if (!__isset_" << (*f_iter)->get_name() << ") {" << endl << indent()
-          << "  throw new TProtocolError(TProtocolError.UNKNOWN, \"Required field '"
-          << (*f_iter)->get_name()
-          << "' was not found in serialized data! Struct: \" + toString());" << endl << indent()
-          << "}" << endl;
-    }
-  }
-
-  // performs various checks (e.g. check that all required fields are set)
-  indent(out) << "validate();" << endl;
-
-  indent_down();
-  out << indent() << "}" << endl << endl;
-}
-
-// generates as3 method to perform various checks
-// (e.g. check that all required fields are set)
-void t_as3_generator::generate_as3_validator(ostream& out, t_struct* tstruct) {
-  indent(out) << "public function validate():void {" << endl;
-  indent_up();
-
-  const vector<t_field*>& fields = tstruct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-
-  out << indent() << "// check for required fields" << endl;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    if ((*f_iter)->get_req() == t_field::T_REQUIRED) {
-      if (type_can_be_null((*f_iter)->get_type())) {
-        indent(out) << "if (" << (*f_iter)->get_name() << " == null) {" << endl;
-        indent(out) << "  throw new TProtocolError(TProtocolError.UNKNOWN, \"Required field '"
-                    << (*f_iter)->get_name() << "' was not present! Struct: \" + toString());"
-                    << endl;
-        indent(out) << "}" << endl;
-      } else {
-        indent(out) << "// alas, we cannot check '" << (*f_iter)->get_name()
-                    << "' because it's a primitive and you chose the non-beans generator." << endl;
-      }
-    }
-  }
-
-  // check that fields of type enum have valid values
-  out << indent() << "// check that fields of type enum have valid values" << endl;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    t_field* field = (*f_iter);
-    t_type* type = field->get_type();
-    // if field is an enum, check that its value is valid
-    if (type->is_enum()) {
-      indent(out) << "if (" << generate_isset_check(field) << " && !" << get_enum_class_name(type)
-                  << ".VALID_VALUES.contains(" << field->get_name() << ")){" << endl;
-      indent_up();
-      indent(out) << "throw new TProtocolError(TProtocolError.UNKNOWN, \"The field '"
-                  << field->get_name() << "' has been assigned the invalid value \" + "
-                  << field->get_name() << ");" << endl;
-      indent_down();
-      indent(out) << "}" << endl;
-    }
-  }
-
-  indent_down();
-  indent(out) << "}" << endl << endl;
-}
-
-/**
- * Generates a function to write all the fields of the struct
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_as3_struct_writer(ostream& out, t_struct* tstruct) {
-  out << indent() << "public function write(oprot:TProtocol):void {" << endl;
-  indent_up();
-
-  string name = tstruct->get_name();
-  const vector<t_field*>& fields = tstruct->get_sorted_members();
-  vector<t_field*>::const_iterator f_iter;
-
-  // performs various checks (e.g. check that all required fields are set)
-  indent(out) << "validate();" << endl << endl;
-
-  indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl;
-
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL;
-    if (could_be_unset) {
-      indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl;
-      indent_up();
-    }
-    bool null_allowed = type_can_be_null((*f_iter)->get_type());
-    if (null_allowed) {
-      out << indent() << "if (this." << (*f_iter)->get_name() << " != null) {" << endl;
-      indent_up();
-    }
-
-    indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name())
-                << "_FIELD_DESC);" << endl;
-
-    // Write field contents
-    generate_serialize_field(out, *f_iter, "this.");
-
-    // Write field closer
-    indent(out) << "oprot.writeFieldEnd();" << endl;
-
-    if (null_allowed) {
-      indent_down();
-      indent(out) << "}" << endl;
-    }
-    if (could_be_unset) {
-      indent_down();
-      indent(out) << "}" << endl;
-    }
-  }
-  // Write the struct map
-  out << indent() << "oprot.writeFieldStop();" << endl << indent() << "oprot.writeStructEnd();"
-      << endl;
-
-  indent_down();
-  out << indent() << "}" << endl << endl;
-}
-
-/**
- * Generates a function to write all the fields of the struct,
- * which is a function result. These fields are only written
- * if they are set in the Isset array, and only one of them
- * can be set at a time.
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_as3_struct_result_writer(ostream& out, t_struct* tstruct) {
-  out << indent() << "public function write(oprot:TProtocol):void {" << endl;
-  indent_up();
-
-  string name = tstruct->get_name();
-  const vector<t_field*>& fields = tstruct->get_sorted_members();
-  vector<t_field*>::const_iterator f_iter;
-
-  indent(out) << "oprot.writeStructBegin(STRUCT_DESC);" << endl;
-
-  bool first = true;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    if (first) {
-      first = false;
-      out << endl << indent() << "if ";
-    } else {
-      out << " else if ";
-    }
-
-    out << "(this." << generate_isset_check(*f_iter) << ") {" << endl;
-
-    indent_up();
-
-    indent(out) << "oprot.writeFieldBegin(" << constant_name((*f_iter)->get_name())
-                << "_FIELD_DESC);" << endl;
-
-    // Write field contents
-    generate_serialize_field(out, *f_iter, "this.");
-
-    // Write field closer
-    indent(out) << "oprot.writeFieldEnd();" << endl;
-
-    indent_down();
-    indent(out) << "}";
-  }
-  // Write the struct map
-  out << endl << indent() << "oprot.writeFieldStop();" << endl << indent()
-      << "oprot.writeStructEnd();" << endl;
-
-  indent_down();
-  out << indent() << "}" << endl << endl;
-}
-
-void t_as3_generator::generate_reflection_getters(ostringstream& out,
-                                                  t_type* type,
-                                                  string field_name,
-                                                  string cap_name) {
-  (void)type;
-  (void)cap_name;
-  indent(out) << "case " << upcase_string(field_name) << ":" << endl;
-  indent_up();
-  indent(out) << "return this." << field_name << ";" << endl;
-  indent_down();
-}
-
-void t_as3_generator::generate_reflection_setters(ostringstream& out,
-                                                  t_type* type,
-                                                  string field_name,
-                                                  string cap_name) {
-  (void)type;
-  (void)cap_name;
-  indent(out) << "case " << upcase_string(field_name) << ":" << endl;
-  indent_up();
-  indent(out) << "if (value == null) {" << endl;
-  indent(out) << "  unset" << get_cap_name(field_name) << "();" << endl;
-  indent(out) << "} else {" << endl;
-  indent(out) << "  this." << field_name << " = value;" << endl;
-  indent(out) << "}" << endl;
-  indent(out) << "break;" << endl << endl;
-
-  indent_down();
-}
-
-void t_as3_generator::generate_generic_field_getters_setters(std::ostream& out,
-                                                             t_struct* tstruct) {
-
-  std::ostringstream getter_stream;
-  std::ostringstream setter_stream;
-
-  // build up the bodies of both the getter and setter at once
-  const vector<t_field*>& fields = tstruct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    t_field* field = *f_iter;
-    t_type* type = get_true_type(field->get_type());
-    std::string field_name = field->get_name();
-    std::string cap_name = get_cap_name(field_name);
-
-    indent_up();
-    generate_reflection_setters(setter_stream, type, field_name, cap_name);
-    generate_reflection_getters(getter_stream, type, field_name, cap_name);
-    indent_down();
-  }
-
-  // create the setter
-  indent(out) << "public function setFieldValue(fieldID:int, value:*):void {" << endl;
-  indent_up();
-
-  indent(out) << "switch (fieldID) {" << endl;
-
-  out << setter_stream.str();
-
-  indent(out) << "default:" << endl;
-  indent(out) << "  throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl;
-
-  indent(out) << "}" << endl;
-
-  indent_down();
-  indent(out) << "}" << endl << endl;
-
-  // create the getter
-  indent(out) << "public function getFieldValue(fieldID:int):* {" << endl;
-  indent_up();
-
-  indent(out) << "switch (fieldID) {" << endl;
-
-  out << getter_stream.str();
-
-  indent(out) << "default:" << endl;
-  indent(out) << "  throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl;
-
-  indent(out) << "}" << endl;
-
-  indent_down();
-
-  indent(out) << "}" << endl << endl;
-}
-
-// Creates a generic isSet method that takes the field number as argument
-void t_as3_generator::generate_generic_isset_method(std::ostream& out, t_struct* tstruct) {
-  const vector<t_field*>& fields = tstruct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-
-  // create the isSet method
-  indent(out) << "// Returns true if field corresponding to fieldID is set (has been assigned a "
-                 "value) and false otherwise" << endl;
-  indent(out) << "public function isSet(fieldID:int):Boolean {" << endl;
-  indent_up();
-  indent(out) << "switch (fieldID) {" << endl;
-
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    t_field* field = *f_iter;
-    indent(out) << "case " << upcase_string(field->get_name()) << ":" << endl;
-    indent_up();
-    indent(out) << "return " << generate_isset_check(field) << ";" << endl;
-    indent_down();
-  }
-
-  indent(out) << "default:" << endl;
-  indent(out) << "  throw new ArgumentError(\"Field \" + fieldID + \" doesn't exist!\");" << endl;
-
-  indent(out) << "}" << endl;
-
-  indent_down();
-  indent(out) << "}" << endl << endl;
-}
-
-/**
- * Generates a set of As3 Bean boilerplate functions (setters, getters, etc.)
- * for the given struct.
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_as3_bean_boilerplate(ostream& out,
-                                                    t_struct* tstruct,
-                                                    bool bindable) {
-  const vector<t_field*>& fields = tstruct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    t_field* field = *f_iter;
-    t_type* type = get_true_type(field->get_type());
-    std::string field_name = field->get_name();
-    std::string cap_name = get_cap_name(field_name);
-
-    // Simple getter
-    generate_as3_doc(out, field);
-    indent(out) << "public function get " << field_name << "():" << type_name(type) << " {" << endl;
-    indent_up();
-    indent(out) << "return this._" << field_name << ";" << endl;
-    indent_down();
-    indent(out) << "}" << endl << endl;
-
-    // Simple setter
-    generate_as3_doc(out, field);
-    std::string propName = tmp("thriftPropertyChange");
-    if (bindable) {
-      indent(out) << "[Bindable(event=\"" << propName << "\")]" << endl;
-    }
-    indent(out) << "public function set " << field_name << "(" << field_name << ":"
-                << type_name(type) << "):void {" << endl;
-    indent_up();
-    indent(out) << "this._" << field_name << " = " << field_name << ";" << endl;
-    generate_isset_set(out, field);
-
-    if (bindable) {
-      // We have to use a custom event rather than the default, because if you use the default,
-      // the setter only gets called if the value has changed - this means calling
-      // foo.setIntValue(0)
-      // will not cause foo.isIntValueSet() to return true since the value of foo._intValue wasn't
-      // changed
-      // so the setter was never called.
-      indent(out) << "dispatchEvent(new Event(\"" << propName << "\"));" << endl;
-
-      // However, if you just use a custom event, then collections won't be able to detect when
-      // elements
-      // in the collections have changed since they listed for PropertyChangeEvents.  So, we
-      // dispatch both.
-      indent(out) << "dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE));"
-                  << endl;
-    }
-    indent_down();
-    indent(out) << "}" << endl << endl;
-
-    // Unsetter
-    indent(out) << "public function unset" << cap_name << "():void {" << endl;
-    indent_up();
-    if (type_can_be_null(type)) {
-      indent(out) << "this." << field_name << " = null;" << endl;
-    } else {
-      indent(out) << "this.__isset_" << field_name << " = false;" << endl;
-    }
-    indent_down();
-    indent(out) << "}" << endl << endl;
-
-    // isSet method
-    indent(out) << "// Returns true if field " << field_name
-                << " is set (has been assigned a value) and false otherwise" << endl;
-    indent(out) << "public function is" << get_cap_name("set") << cap_name << "():Boolean {"
-                << endl;
-    indent_up();
-    if (type_can_be_null(type)) {
-      indent(out) << "return this." << field_name << " != null;" << endl;
-    } else {
-      indent(out) << "return this.__isset_" << field_name << ";" << endl;
-    }
-    indent_down();
-    indent(out) << "}" << endl << endl;
-  }
-}
-
-/**
- * Generates a toString() method for the given struct
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_as3_struct_tostring(ostream& out,
-                                                   t_struct* tstruct,
-                                                   bool bindable) {
-  // If it's bindable, it extends EventDispatcher so toString is an override.
-  out << indent() << "public " << (bindable ? "override " : "") << "function toString():String {"
-      << endl;
-  indent_up();
-
-  out << indent() << "var ret:String = new String(\"" << tstruct->get_name() << "(\");" << endl;
-  out << indent() << "var first:Boolean = true;" << endl << endl;
-
-  const vector<t_field*>& fields = tstruct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-  bool first = true;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    bool could_be_unset = (*f_iter)->get_req() == t_field::T_OPTIONAL;
-    if (could_be_unset) {
-      indent(out) << "if (" << generate_isset_check(*f_iter) << ") {" << endl;
-      indent_up();
-    }
-
-    t_field* field = (*f_iter);
-
-    if (!first) {
-      indent(out) << "if (!first) ret +=  \", \";" << endl;
-    }
-    indent(out) << "ret += \"" << (*f_iter)->get_name() << ":\";" << endl;
-    bool can_be_null = type_can_be_null(field->get_type());
-    if (can_be_null) {
-      indent(out) << "if (this." << (*f_iter)->get_name() << " == null) {" << endl;
-      indent(out) << "  ret += \"null\";" << endl;
-      indent(out) << "} else {" << endl;
-      indent_up();
-    }
-
-    if (field->get_type()->is_binary()) {
-      indent(out) << "  ret += \"BINARY\";" << endl;
-    } else if (field->get_type()->is_enum()) {
-      indent(out) << "var " << field->get_name()
-                  << "_name:String = " << get_enum_class_name(field->get_type())
-                  << ".VALUES_TO_NAMES[this." << (*f_iter)->get_name() << "];" << endl;
-      indent(out) << "if (" << field->get_name() << "_name != null) {" << endl;
-      indent(out) << "  ret += " << field->get_name() << "_name;" << endl;
-      indent(out) << "  ret += \" (\";" << endl;
-      indent(out) << "}" << endl;
-      indent(out) << "ret += this." << field->get_name() << ";" << endl;
-      indent(out) << "if (" << field->get_name() << "_name != null) {" << endl;
-      indent(out) << "  ret += \")\";" << endl;
-      indent(out) << "}" << endl;
-    } else {
-      indent(out) << "ret += this." << (*f_iter)->get_name() << ";" << endl;
-    }
-
-    if (can_be_null) {
-      indent_down();
-      indent(out) << "}" << endl;
-    }
-    indent(out) << "first = false;" << endl;
-
-    if (could_be_unset) {
-      indent_down();
-      indent(out) << "}" << endl;
-    }
-    first = false;
-  }
-  out << indent() << "ret += \")\";" << endl << indent() << "return ret;" << endl;
-
-  indent_down();
-  indent(out) << "}" << endl << endl;
-}
-
-/**
- * Generates a static map with meta data to store information such as fieldID to
- * fieldName mapping
- *
- * @param tstruct The struct definition
- */
-void t_as3_generator::generate_as3_meta_data_map(ostream& out, t_struct* tstruct) {
-  const vector<t_field*>& fields = tstruct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-
-  // Static Map with fieldID -> FieldMetaData mappings
-  indent(out) << "public static const metaDataMap:Dictionary = new Dictionary();" << endl;
-
-  if (fields.size() > 0) {
-    // Populate map
-    scope_up(out);
-    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-      t_field* field = *f_iter;
-      std::string field_name = field->get_name();
-      indent(out) << "metaDataMap[" << upcase_string(field_name) << "] = new FieldMetaData(\""
-                  << field_name << "\", ";
-
-      // Set field requirement type (required, optional, etc.)
-      if (field->get_req() == t_field::T_REQUIRED) {
-        out << "TFieldRequirementType.REQUIRED, ";
-      } else if (field->get_req() == t_field::T_OPTIONAL) {
-        out << "TFieldRequirementType.OPTIONAL, ";
-      } else {
-        out << "TFieldRequirementType.DEFAULT, ";
-      }
-
-      // Create value meta data
-      generate_field_value_meta_data(out, field->get_type());
-      out << ");" << endl;
-    }
-    scope_down(out);
-  }
-}
-
-/**
- * Returns a string with the as3 representation of the given thrift type
- * (e.g. for the type struct it returns "TType.STRUCT")
- */
-std::string t_as3_generator::get_as3_type_string(t_type* type) {
-  if (type->is_list()) {
-    return "TType.LIST";
-  } else if (type->is_map()) {
-    return "TType.MAP";
-  } else if (type->is_set()) {
-    return "TType.SET";
-  } else if (type->is_struct() || type->is_xception()) {
-    return "TType.STRUCT";
-  } else if (type->is_enum()) {
-    return "TType.I32";
-  } else if (type->is_typedef()) {
-    return get_as3_type_string(((t_typedef*)type)->get_type());
-  } else if (type->is_base_type()) {
-    switch (((t_base_type*)type)->get_base()) {
-    case t_base_type::TYPE_VOID:
-      return "TType.VOID";
-      break;
-    case t_base_type::TYPE_STRING:
-      return "TType.STRING";
-      break;
-    case t_base_type::TYPE_BOOL:
-      return "TType.BOOL";
-      break;
-    case t_base_type::TYPE_I8:
-      return "TType.BYTE";
-      break;
-    case t_base_type::TYPE_I16:
-      return "TType.I16";
-      break;
-    case t_base_type::TYPE_I32:
-      return "TType.I32";
-      break;
-    case t_base_type::TYPE_I64:
-      return "TType.I64";
-      break;
-    case t_base_type::TYPE_DOUBLE:
-      return "TType.DOUBLE";
-      break;
-    default:
-      throw std::runtime_error("Unknown thrift type \"" + type->get_name()
-                               + "\" passed to t_as3_generator::get_as3_type_string!");
-      break; // This should never happen!
-    }
-  } else {
-    throw std::runtime_error(
-        "Unknown thrift type \"" + type->get_name()
-        + "\" passed to t_as3_generator::get_as3_type_string!"); // This should never happen!
-  }
-}
-
-void t_as3_generator::generate_field_value_meta_data(std::ostream& out, t_type* type) {
-  out << endl;
-  indent_up();
-  indent_up();
-  if (type->is_struct() || type->is_xception()) {
-    indent(out) << "new StructMetaData(TType.STRUCT, " << type_name(type);
-  } else if (type->is_container()) {
-    if (type->is_list()) {
-      indent(out) << "new ListMetaData(TType.LIST, ";
-      t_type* elem_type = ((t_list*)type)->get_elem_type();
-      generate_field_value_meta_data(out, elem_type);
-    } else if (type->is_set()) {
-      indent(out) << "new SetMetaData(TType.SET, ";
-      t_type* elem_type = ((t_list*)type)->get_elem_type();
-      generate_field_value_meta_data(out, elem_type);
-    } else { // map
-      indent(out) << "new MapMetaData(TType.MAP, ";
-      t_type* key_type = ((t_map*)type)->get_key_type();
-      t_type* val_type = ((t_map*)type)->get_val_type();
-      generate_field_value_meta_data(out, key_type);
-      out << ", ";
-      generate_field_value_meta_data(out, val_type);
-    }
-  } else {
-    indent(out) << "new FieldValueMetaData(" << get_as3_type_string(type);
-  }
-  out << ")";
-  indent_down();
-  indent_down();
-}
-
-/**
- * Generates a thrift service. In C++, this comprises an entirely separate
- * header and source file. The header file defines the methods and includes
- * the data types defined in the main header file, and the implementation
- * file contains implementations of the basic printer and default interfaces.
- *
- * @param tservice The service definition
- */
-void t_as3_generator::generate_service(t_service* tservice) {
-  // Make interface file
-  string f_service_name = package_dir_ + "/" + service_name_ + ".as";
-  f_service_.open(f_service_name.c_str());
-
-  f_service_ << autogen_comment() << as3_package();
-
-  scope_up(f_service_);
-
-  f_service_ << endl << as3_type_imports() << as3_thrift_imports()
-             << as3_thrift_gen_imports(tservice);
-
-  if (tservice->get_extends() != nullptr) {
-    t_type* parent = tservice->get_extends();
-    string parent_namespace = parent->get_program()->get_namespace("as3");
-    if (!parent_namespace.empty() && parent_namespace != package_name_) {
-      f_service_ << "import " << type_name(parent) << ";" << endl;
-    }
-  }
-
-  f_service_ << endl;
-
-  generate_service_interface(tservice);
-
-  scope_down(f_service_);
-  f_service_.close();
-
-  // Now make the implementation/client file
-  f_service_name = package_dir_ + "/" + service_name_ + "Impl.as";
-  f_service_.open(f_service_name.c_str());
-
-  f_service_ << autogen_comment() << as3_package();
-
-  scope_up(f_service_);
-
-  f_service_ << endl << as3_type_imports() << as3_thrift_imports()
-             << as3_thrift_gen_imports(tservice);
-
-  if (tservice->get_extends() != nullptr) {
-    t_type* parent = tservice->get_extends();
-    string parent_namespace = parent->get_program()->get_namespace("as3");
-    if (!parent_namespace.empty() && parent_namespace != package_name_) {
-      f_service_ << "import " << type_name(parent) << "Impl;" << endl;
-    }
-  }
-
-  f_service_ << endl;
-
-  generate_service_client(tservice);
-  scope_down(f_service_);
-
-  f_service_ << as3_type_imports();
-  f_service_ << as3_thrift_imports();
-  f_service_ << as3_thrift_gen_imports(tservice);
-  if (!package_name_.empty()) {
-    f_service_ << "import " << package_name_ << ".*;" << endl;
-  }
-
-  generate_service_helpers(tservice);
-
-  f_service_.close();
-
-  // Now make the processor/server file
-  f_service_name = package_dir_ + "/" + service_name_ + "Processor.as";
-  f_service_.open(f_service_name.c_str());
-
-  f_service_ << autogen_comment() << as3_package();
-
-  scope_up(f_service_);
-
-  f_service_ << endl << as3_type_imports() << as3_thrift_imports()
-             << as3_thrift_gen_imports(tservice) << endl;
-
-  generate_service_server(tservice);
-  scope_down(f_service_);
-
-  f_service_ << as3_type_imports();
-  f_service_ << as3_thrift_imports();
-  f_service_ << as3_thrift_gen_imports(tservice) << endl;
-  if (!package_name_.empty()) {
-    f_service_ << "import " << package_name_ << ".*;" << endl;
-  }
-
-  generate_service_helpers(tservice);
-
-  f_service_.close();
-}
-
-/**
- * Generates a service interface definition.
- *
- * @param tservice The service to generate a header definition for
- */
-void t_as3_generator::generate_service_interface(t_service* tservice) {
-  string extends_iface = "";
-  if (tservice->get_extends() != nullptr) {
-    extends_iface = " extends " + tservice->get_extends()->get_name();
-  }
-
-  generate_as3_doc(f_service_, tservice);
-  f_service_ << indent() << "public interface " << service_name_ << extends_iface << " {" << endl
-             << endl;
-  indent_up();
-  vector<t_function*> functions = tservice->get_functions();
-  vector<t_function*>::iterator f_iter;
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    generate_as3_doc(f_service_, *f_iter);
-    if (!(*f_iter)->is_oneway()) {
-      if ((*f_iter)->get_returntype()->is_void()) {
-        indent(f_service_) << "//function onError(Error):void;" << endl;
-        indent(f_service_) << "//function onSuccess():void;" << endl;
-      } else {
-        indent(f_service_) << "//function onError(Error):void;" << endl;
-        indent(f_service_) << "//function onSuccess(" << type_name((*f_iter)->get_returntype())
-                           << "):void;" << endl;
-      }
-    }
-    indent(f_service_) << function_signature(*f_iter) << ";" << endl << endl;
-  }
-  indent_down();
-  f_service_ << indent() << "}" << endl << endl;
-}
-
-/**
- * Generates structs for all the service args and return types
- *
- * @param tservice The service
- */
-void t_as3_generator::generate_service_helpers(t_service* tservice) {
-  vector<t_function*> functions = tservice->get_functions();
-  vector<t_function*>::iterator f_iter;
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    t_struct* ts = (*f_iter)->get_arglist();
-    generate_as3_struct_definition(f_service_, ts, false, true);
-    generate_function_helpers(*f_iter);
-  }
-}
-
-/**
- * Generates a service client definition.
- *
- * @param tservice The service to generate a server for.
- */
-void t_as3_generator::generate_service_client(t_service* tservice) {
-  string extends = "";
-  string extends_client = "";
-  if (tservice->get_extends() != nullptr) {
-    extends = tservice->get_extends()->get_name();
-    extends_client = " extends " + extends + "Impl";
-  }
-
-  indent(f_service_) << "public class " << service_name_ << "Impl" << extends_client
-                     << " implements " << service_name_ << " {" << endl;
-  indent_up();
-
-  indent(f_service_) << "public function " << service_name_ << "Impl"
-                     << "(iprot:TProtocol, oprot:TProtocol=null)" << endl;
-  scope_up(f_service_);
-  if (extends.empty()) {
-    f_service_ << indent() << "iprot_ = iprot;" << endl;
-    f_service_ << indent() << "if (oprot == null) {" << endl;
-    indent_up();
-    f_service_ << indent() << "oprot_ = iprot;" << endl;
-    indent_down();
-    f_service_ << indent() << "} else {" << endl;
-    indent_up();
-    f_service_ << indent() << "oprot_ = oprot;" << endl;
-    indent_down();
-    f_service_ << indent() << "}";
-  } else {
-    f_service_ << indent() << "super(iprot, oprot);" << endl;
-  }
-  scope_down(f_service_);
-  f_service_ << endl;
-
-  if (extends.empty()) {
-    f_service_ << indent() << "protected var iprot_:TProtocol;" << endl << indent()
-               << "protected var oprot_:TProtocol;" << endl << endl << indent()
-               << "protected var seqid_:int;" << endl << endl;
-
-    indent(f_service_) << "public function getInputProtocol():TProtocol" << endl;
-    scope_up(f_service_);
-    indent(f_service_) << "return this.iprot_;" << endl;
-    scope_down(f_service_);
-    f_service_ << endl;
-
-    indent(f_service_) << "public function getOutputProtocol():TProtocol" << endl;
-    scope_up(f_service_);
-    indent(f_service_) << "return this.oprot_;" << endl;
-    scope_down(f_service_);
-    f_service_ << endl;
-  }
-
-  // Generate client method implementations
-  vector<t_function*> functions = tservice->get_functions();
-  vector<t_function*>::const_iterator f_iter;
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    string funname = (*f_iter)->get_name();
-
-    // Open function
-    if (!(*f_iter)->is_oneway()) {
-      if ((*f_iter)->get_returntype()->is_void()) {
-        indent(f_service_) << "//function onError(Error):void;" << endl;
-        indent(f_service_) << "//function onSuccess():void;" << endl;
-      } else {
-        indent(f_service_) << "//function onError(Error):void;" << endl;
-        indent(f_service_) << "//function onSuccess(" << type_name((*f_iter)->get_returntype())
-                           << "):void;" << endl;
-      }
-    }
-    indent(f_service_) << "public " << function_signature(*f_iter) << endl;
-    scope_up(f_service_);
-
-    // Get the struct of function call params
-    t_struct* arg_struct = (*f_iter)->get_arglist();
-
-    string argsname = (*f_iter)->get_name() + "_args";
-    vector<t_field*>::const_iterator fld_iter;
-    const vector<t_field*>& fields = arg_struct->get_members();
-
-    // Serialize the request
-    f_service_ << indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname << "\", "
-               << ((*f_iter)->is_oneway() ? "TMessageType.ONEWAY" : "TMessageType.CALL")
-               << ", seqid_));" << endl << indent() << "var args:" << argsname << " = new "
-               << argsname << "();" << endl;
-
-    for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
-      f_service_ << indent() << "args." << (*fld_iter)->get_name() << " = "
-                 << (*fld_iter)->get_name() << ";" << endl;
-    }
-
-    f_service_ << indent() << "args.write(oprot_);" << endl << indent()
-               << "oprot_.writeMessageEnd();" << endl;
-
-    if ((*f_iter)->is_oneway()) {
-      f_service_ << indent() << "oprot_.getTransport().flush();" << endl;
-    } else {
-      f_service_ << indent() << "oprot_.getTransport().flush(function(error:Error):void {" << endl;
-      indent_up();
-      f_service_ << indent() << "try {" << endl;
-      indent_up();
-      string resultname = (*f_iter)->get_name() + "_result";
-      f_service_ << indent() << "if (error != null) {" << endl << indent()
-                 << "  if (onError != null) onError(error);" << endl << indent() << "  return;"
-                 << endl << indent() << "}" << endl << indent()
-                 << "var msg:TMessage = iprot_.readMessageBegin();" << endl << indent()
-                 << "if (msg.type == TMessageType.EXCEPTION) {" << endl << indent()
-                 << "  var x:TApplicationError = TApplicationError.read(iprot_);" << endl
-                 << indent() << "  iprot_.readMessageEnd();" << endl << indent()
-                 << "  if (onError != null) onError(x);" << endl << indent() << "  return;" << endl
-                 << indent() << "}" << endl << indent() << "var result :" << resultname << " = new "
-                 << resultname << "();" << endl << indent() << "result.read(iprot_);" << endl
-                 << indent() << "iprot_.readMessageEnd();" << endl;
-
-      // Careful, only return _result if not a void function
-      if (!(*f_iter)->get_returntype()->is_void()) {
-        f_service_ << indent() << "if (result." << generate_isset_check("success") << ") {" << endl
-                   << indent() << "  if (onSuccess != null) onSuccess(result.success);" << endl
-                   << indent() << "  return;" << endl << indent() << "}" << endl;
-      }
-
-      t_struct* xs = (*f_iter)->get_xceptions();
-      const std::vector<t_field*>& xceptions = xs->get_members();
-      vector<t_field*>::const_iterator x_iter;
-      for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-        f_service_ << indent() << "if (result." << (*x_iter)->get_name() << " != null) {" << endl
-                   << indent() << "  if (onError != null) onError(result." << (*x_iter)->get_name()
-                   << ");" << endl << indent() << "  return;" << endl << indent() << "}" << endl;
-      }
-
-      // If you get here it's an exception, unless a void function
-      if ((*f_iter)->get_returntype()->is_void()) {
-        f_service_ << indent() << "if (onSuccess != null) onSuccess();" << endl << indent()
-                   << "return;" << endl;
-      } else {
-
-        f_service_ << indent() << "if (onError != null) onError(new "
-                                  "TApplicationError(TApplicationError.MISSING_RESULT, \""
-                   << (*f_iter)->get_name() << " failed: unknown result\"));" << endl;
-      }
-      indent_down();
-      f_service_ << indent() << "} catch (e:TError) {" << endl << indent()
-                 << "  if (onError != null) onError(e);" << endl << indent() << "}" << endl;
-
-      indent_down();
-      indent(f_service_) << "});" << endl;
-    }
-    // Close function
-    scope_down(f_service_);
-    f_service_ << endl;
-  }
-
-  indent_down();
-  indent(f_service_) << "}" << endl;
-}
-
-/**
- * Generates a service server definition.
- *
- * @param tservice The service to generate a server for.
- */
-void t_as3_generator::generate_service_server(t_service* tservice) {
-  // Generate the dispatch methods
-  vector<t_function*> functions = tservice->get_functions();
-  vector<t_function*>::iterator f_iter;
-
-  // Extends stuff
-  string extends = "";
-  string extends_processor = "";
-  if (tservice->get_extends() != nullptr) {
-    extends = type_name(tservice->get_extends());
-    extends_processor = " extends " + extends + "Processor";
-  }
-
-  // Generate the header portion
-  indent(f_service_) << "public class " << service_name_ << "Processor" << extends_processor
-                     << " implements TProcessor {" << endl;
-  indent_up();
-
-  indent(f_service_) << "public function " << service_name_ << "Processor(iface:" << service_name_
-                     << ")" << endl;
-  scope_up(f_service_);
-  if (!extends.empty()) {
-    f_service_ << indent() << "super(iface);" << endl;
-  }
-  f_service_ << indent() << "iface_ = iface;" << endl;
-
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    f_service_ << indent() << "PROCESS_MAP[\"" << (*f_iter)->get_name()
-               << "\"] = " << (*f_iter)->get_name() << "();" << endl;
-  }
-
-  scope_down(f_service_);
-  f_service_ << endl;
-
-  f_service_ << indent() << "private var iface_:" << service_name_ << ";" << endl;
-
-  if (extends.empty()) {
-    f_service_ << indent() << "protected const PROCESS_MAP:Dictionary = new Dictionary();" << endl;
-  }
-
-  f_service_ << endl;
-
-  // Generate the server implementation
-  string override = "";
-  if (tservice->get_extends() != nullptr) {
-    override = "override ";
-  }
-  indent(f_service_) << override
-                     << "public function process(iprot:TProtocol, oprot:TProtocol):Boolean" << endl;
-  scope_up(f_service_);
-
-  f_service_ << indent() << "var msg:TMessage = iprot.readMessageBegin();" << endl;
-
-  // TODO(mcslee): validate message, was the seqid etc. legit?
-  // AS- If all method is oneway:
-  // do you have an oprot?
-  // do you you need nullcheck?
-  f_service_
-      << indent() << "var fn:Function = PROCESS_MAP[msg.name];" << endl << indent()
-      << "if (fn == null) {" << endl << indent() << "  TProtocolUtil.skip(iprot, TType.STRUCT);"
-      << endl << indent() << "  iprot.readMessageEnd();" << endl << indent()
-      << "  var x:TApplicationError = new TApplicationError(TApplicationError.UNKNOWN_METHOD, "
-         "\"Invalid method name: '\"+msg.name+\"'\");" << endl << indent()
-      << "  oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));"
-      << endl << indent() << "  x.write(oprot);" << endl << indent() << "  oprot.writeMessageEnd();"
-      << endl << indent() << "  oprot.getTransport().flush();" << endl << indent()
-      << "  return true;" << endl << indent() << "}" << endl << indent()
-      << "fn.call(this,msg.seqid, iprot, oprot);" << endl;
-
-  f_service_ << indent() << "return true;" << endl;
-
-  scope_down(f_service_);
-  f_service_ << endl;
-
-  // Generate the process subfunctions
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    generate_process_function(tservice, *f_iter);
-  }
-
-  indent_down();
-  indent(f_service_) << "}" << endl << endl;
-}
-
-/**
- * Generates a struct and helpers for a function.
- *
- * @param tfunction The function
- */
-void t_as3_generator::generate_function_helpers(t_function* tfunction) {
-  if (tfunction->is_oneway()) {
-    return;
-  }
-
-  t_struct result(program_, tfunction->get_name() + "_result");
-  t_field success(tfunction->get_returntype(), "success", 0);
-  if (!tfunction->get_returntype()->is_void()) {
-    result.append(&success);
-  }
-
-  t_struct* xs = tfunction->get_xceptions();
-  const vector<t_field*>& fields = xs->get_members();
-  vector<t_field*>::const_iterator f_iter;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    result.append(*f_iter);
-  }
-
-  generate_as3_struct_definition(f_service_, &result, false, true, true);
-}
-
-/**
- * Generates a process function definition.
- *
- * @param tfunction The function to write a dispatcher for
- */
-void t_as3_generator::generate_process_function(t_service* tservice, t_function* tfunction) {
-  (void)tservice;
-  // Open class
-  indent(f_service_) << "private function " << tfunction->get_name() << "():Function {" << endl;
-  indent_up();
-
-  // Open function
-  indent(f_service_) << "return function(seqid:int, iprot:TProtocol, oprot:TProtocol):void" << endl;
-  scope_up(f_service_);
-
-  string argsname = tfunction->get_name() + "_args";
-  string resultname = tfunction->get_name() + "_result";
-
-  f_service_ << indent() << "var args:" << argsname << " = new " << argsname << "();" << endl
-             << indent() << "args.read(iprot);" << endl << indent() << "iprot.readMessageEnd();"
-             << endl;
-
-  t_struct* xs = tfunction->get_xceptions();
-  const std::vector<t_field*>& xceptions = xs->get_members();
-  vector<t_field*>::const_iterator x_iter;
-
-  // Declare result for non oneway function
-  if (!tfunction->is_oneway()) {
-    f_service_ << indent() << "var result:" << resultname << " = new " << resultname << "();"
-               << endl;
-  }
-
-  // Try block for a function with exceptions
-  if (xceptions.size() > 0) {
-    f_service_ << indent() << "try {" << endl;
-    indent_up();
-  }
-
-  // Generate the function call
-  t_struct* arg_struct = tfunction->get_arglist();
-  const std::vector<t_field*>& fields = arg_struct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-
-  f_service_ << indent();
-  if (tfunction->is_oneway()) {
-    f_service_ << "iface_." << tfunction->get_name() << "(";
-    bool first = true;
-    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-      if (first) {
-        first = false;
-      } else {
-        f_service_ << ", ";
-      }
-      f_service_ << "args." << (*f_iter)->get_name();
-    }
-    f_service_ << ");" << endl;
-  } else {
-    f_service_ << "// sorry this operation is not supported yet" << endl;
-    f_service_ << indent() << "throw new Error(\"This is not yet supported\");" << endl;
-  }
-
-  // Set isset on success field
-  if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()
-      && !type_can_be_null(tfunction->get_returntype())) {
-    f_service_ << indent() << "result.set" << get_cap_name("success") << get_cap_name("isSet")
-               << "(true);" << endl;
-  }
-
-  if (!tfunction->is_oneway() && xceptions.size() > 0) {
-    indent_down();
-    f_service_ << indent() << "}";
-    for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-      f_service_ << " catch (" << (*x_iter)->get_name() << ":"
-                 << type_name((*x_iter)->get_type(), false, false) << ") {" << endl;
-      if (!tfunction->is_oneway()) {
-        indent_up();
-        f_service_ << indent() << "result." << (*x_iter)->get_name() << " = "
-                   << (*x_iter)->get_name() << ";" << endl;
-        indent_down();
-        f_service_ << indent() << "}";
-      } else {
-        f_service_ << "}";
-      }
-    }
-    f_service_ << " catch (th:Error) {" << endl;
-    indent_up();
-    f_service_ << indent() << "trace(\"Internal error processing " << tfunction->get_name()
-               << "\", th);" << endl << indent()
-               << "var x:TApplicationError = new "
-                  "TApplicationError(TApplicationError.INTERNAL_ERROR, \"Internal error processing "
-               << tfunction->get_name() << "\");" << endl << indent()
-               << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name()
-               << "\", TMessageType.EXCEPTION, seqid));" << endl << indent() << "x.write(oprot);"
-               << endl << indent() << "oprot.writeMessageEnd();" << endl << indent()
-               << "oprot.getTransport().flush();" << endl << indent() << "return;" << endl;
-    indent_down();
-    f_service_ << indent() << "}" << endl;
-  }
-
-  // Shortcut out here for oneway functions
-  if (tfunction->is_oneway()) {
-    f_service_ << indent() << "return;" << endl;
-    scope_down(f_service_);
-
-    // Close class
-    indent_down();
-    f_service_ << indent() << "}" << endl << endl;
-    return;
-  }
-
-  f_service_ << indent() << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name()
-             << "\", TMessageType.REPLY, seqid));" << endl << indent() << "result.write(oprot);"
-             << endl << indent() << "oprot.writeMessageEnd();" << endl << indent()
-             << "oprot.getTransport().flush();" << endl;
-
-  // Close function
-  scope_down(f_service_);
-  f_service_ << endl;
-
-  // Close class
-  indent_down();
-  f_service_ << indent() << "}" << endl << endl;
-}
-
-/**
- * Deserializes a field of any type.
- *
- * @param tfield The field
- * @param prefix The variable name or container for this field
- */
-void t_as3_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
-  t_type* type = get_true_type(tfield->get_type());
-
-  if (type->is_void()) {
-    throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name();
-  }
-
-  string name = prefix + tfield->get_name();
-
-  if (type->is_struct() || type->is_xception()) {
-    generate_deserialize_struct(out, (t_struct*)type, name);
-  } else if (type->is_container()) {
-    generate_deserialize_container(out, type, name);
-  } else if (type->is_base_type() || type->is_enum()) {
-
-    indent(out) << name << " = iprot.";
-
-    if (type->is_base_type()) {
-      t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-      switch (tbase) {
-      case t_base_type::TYPE_VOID:
-        throw "compiler error: cannot serialize void field in a struct: " + name;
-        break;
-      case t_base_type::TYPE_STRING:
-        if (type->is_binary()) {
-          out << "readBinary();";
-        } else {
-          out << "readString();";
-        }
-        break;
-      case t_base_type::TYPE_BOOL:
-        out << "readBool();";
-        break;
-      case t_base_type::TYPE_I8:
-        out << "readByte();";
-        break;
-      case t_base_type::TYPE_I16:
-        out << "readI16();";
-        break;
-      case t_base_type::TYPE_I32:
-        out << "readI32();";
-        break;
-      case t_base_type::TYPE_I64:
-        out << "readI64();";
-        break;
-      case t_base_type::TYPE_DOUBLE:
-        out << "readDouble();";
-        break;
-      default:
-        throw "compiler error: no As3 name for base type " + t_base_type::t_base_name(tbase);
-      }
-    } else if (type->is_enum()) {
-      out << "readI32();";
-    }
-    out << endl;
-  } else {
-    printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
-           tfield->get_name().c_str(),
-           type_name(type).c_str());
-  }
-}
-
-/**
- * Generates an unserializer for a struct, invokes read()
- */
-void t_as3_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string prefix) {
-  out << indent() << prefix << " = new " << type_name(tstruct) << "();" << endl << indent()
-      << prefix << ".read(iprot);" << endl;
-}
-
-/**
- * Deserializes a container by reading its size and then iterating
- */
-void t_as3_generator::generate_deserialize_container(ostream& out, t_type* ttype, string prefix) {
-  scope_up(out);
-
-  string obj;
-
-  if (ttype->is_map()) {
-    obj = tmp("_map");
-  } else if (ttype->is_set()) {
-    obj = tmp("_set");
-  } else if (ttype->is_list()) {
-    obj = tmp("_list");
-  }
-
-  // Declare variables, read header
-  if (ttype->is_map()) {
-    indent(out) << "var " << obj << ":TMap = iprot.readMapBegin();" << endl;
-  } else if (ttype->is_set()) {
-    indent(out) << "var " << obj << ":TSet = iprot.readSetBegin();" << endl;
-  } else if (ttype->is_list()) {
-    indent(out) << "var " << obj << ":TList = iprot.readListBegin();" << endl;
-  }
-
-  indent(out) << prefix << " = new " << type_name(ttype, false, true)
-              // size the collection correctly
-              << "("
-              << ");" << endl;
-
-  // For loop iterates over elements
-  string i = tmp("_i");
-  indent(out) << "for (var " << i << ":int = 0; " << i << " < " << obj << ".size"
-              << "; "
-              << "++" << i << ")" << endl;
-
-  scope_up(out);
-
-  if (ttype->is_map()) {
-    generate_deserialize_map_element(out, (t_map*)ttype, prefix);
-  } else if (ttype->is_set()) {
-    generate_deserialize_set_element(out, (t_set*)ttype, prefix);
-  } else if (ttype->is_list()) {
-    generate_deserialize_list_element(out, (t_list*)ttype, prefix);
-  }
-
-  scope_down(out);
-
-  // Read container end
-  if (ttype->is_map()) {
-    indent(out) << "iprot.readMapEnd();" << endl;
-  } else if (ttype->is_set()) {
-    indent(out) << "iprot.readSetEnd();" << endl;
-  } else if (ttype->is_list()) {
-    indent(out) << "iprot.readListEnd();" << endl;
-  }
-
-  scope_down(out);
-}
-
-/**
- * Generates code to deserialize a map
- */
-void t_as3_generator::generate_deserialize_map_element(ostream& out, t_map* tmap, string prefix) {
-  string key = tmp("_key");
-  string val = tmp("_val");
-  t_field fkey(tmap->get_key_type(), key);
-  t_field fval(tmap->get_val_type(), val);
-
-  indent(out) << declare_field(&fkey) << endl;
-  indent(out) << declare_field(&fval) << endl;
-
-  generate_deserialize_field(out, &fkey);
-  generate_deserialize_field(out, &fval);
-
-  indent(out) << prefix << "[" << key << "] = " << val << ";" << endl;
-}
-
-/**
- * Deserializes a set element
- */
-void t_as3_generator::generate_deserialize_set_element(ostream& out, t_set* tset, string prefix) {
-  string elem = tmp("_elem");
-  t_field felem(tset->get_elem_type(), elem);
-
-  indent(out) << declare_field(&felem) << endl;
-
-  generate_deserialize_field(out, &felem);
-
-  indent(out) << prefix << ".add(" << elem << ");" << endl;
-}
-
-/**
- * Deserializes a list element
- */
-void t_as3_generator::generate_deserialize_list_element(ostream& out,
-                                                        t_list* tlist,
-                                                        string prefix) {
-  string elem = tmp("_elem");
-  t_field felem(tlist->get_elem_type(), elem);
-
-  indent(out) << declare_field(&felem) << endl;
-
-  generate_deserialize_field(out, &felem);
-
-  indent(out) << prefix << ".push(" << elem << ");" << endl;
-}
-
-/**
- * Serializes a field of any type.
- *
- * @param tfield The field to serialize
- * @param prefix Name to prepend to field name
- */
-void t_as3_generator::generate_serialize_field(ostream& out, t_field* tfield, string prefix) {
-  t_type* type = get_true_type(tfield->get_type());
-
-  // Do nothing for void types
-  if (type->is_void()) {
-    throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE: " + prefix + tfield->get_name();
-  }
-
-  if (type->is_struct() || type->is_xception()) {
-    generate_serialize_struct(out, (t_struct*)type, prefix + tfield->get_name());
-  } else if (type->is_container()) {
-    generate_serialize_container(out, type, prefix + tfield->get_name());
-  } else if (type->is_base_type() || type->is_enum()) {
-
-    string name = prefix + tfield->get_name();
-    indent(out) << "oprot.";
-
-    if (type->is_base_type()) {
-      t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-      switch (tbase) {
-      case t_base_type::TYPE_VOID:
-        throw "compiler error: cannot serialize void field in a struct: " + name;
-        break;
-      case t_base_type::TYPE_STRING:
-        if (type->is_binary()) {
-          out << "writeBinary(" << name << ");";
-        } else {
-          out << "writeString(" << name << ");";
-        }
-        break;
-      case t_base_type::TYPE_BOOL:
-        out << "writeBool(" << name << ");";
-        break;
-      case t_base_type::TYPE_I8:
-        out << "writeByte(" << name << ");";
-        break;
-      case t_base_type::TYPE_I16:
-        out << "writeI16(" << name << ");";
-        break;
-      case t_base_type::TYPE_I32:
-        out << "writeI32(" << name << ");";
-        break;
-      case t_base_type::TYPE_I64:
-        out << "writeI64(" << name << ");";
-        break;
-      case t_base_type::TYPE_DOUBLE:
-        out << "writeDouble(" << name << ");";
-        break;
-      default:
-        throw "compiler error: no As3 name for base type " + t_base_type::t_base_name(tbase);
-      }
-    } else if (type->is_enum()) {
-      out << "writeI32(" << name << ");";
-    }
-    out << endl;
-  } else {
-    printf("DO NOT KNOW HOW TO SERIALIZE FIELD '%s%s' TYPE '%s'\n",
-           prefix.c_str(),
-           tfield->get_name().c_str(),
-           type_name(type).c_str());
-  }
-}
-
-/**
- * Serializes all the members of a struct.
- *
- * @param tstruct The struct to serialize
- * @param prefix  String prefix to attach to all fields
- */
-void t_as3_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
-  (void)tstruct;
-  out << indent() << prefix << ".write(oprot);" << endl;
-}
-
-/**
- * Serializes a container by writing its size then the elements.
- *
- * @param ttype  The type of container
- * @param prefix String prefix for fields
- */
-void t_as3_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
-  scope_up(out);
-
-  if (ttype->is_map()) {
-    string iter = tmp("_key");
-    string counter = tmp("_sizeCounter");
-    indent(out) << "var " << counter << ":int = 0;" << endl;
-    indent(out) << "for (var " << iter << ":* in " << prefix << ") {" << endl;
-    indent(out) << "  " << counter << +"++;" << endl;
-    indent(out) << "}" << endl;
-
-    indent(out) << "oprot.writeMapBegin(new TMap(" << type_to_enum(((t_map*)ttype)->get_key_type())
-                << ", " << type_to_enum(((t_map*)ttype)->get_val_type()) << ", " << counter << "));"
-                << endl;
-  } else if (ttype->is_set()) {
-    indent(out) << "oprot.writeSetBegin(new TSet(" << type_to_enum(((t_set*)ttype)->get_elem_type())
-                << ", " << prefix << ".size));" << endl;
-  } else if (ttype->is_list()) {
-    indent(out) << "oprot.writeListBegin(new TList("
-                << type_to_enum(((t_list*)ttype)->get_elem_type()) << ", " << prefix << ".length));"
-                << endl;
-  }
-
-  string iter = tmp("elem");
-  if (ttype->is_map()) {
-    indent(out) << "for (var " << iter << ":* in " << prefix << ")";
-  } else if (ttype->is_set()) {
-    indent(out) << "for each (var " << iter << ":* in " << prefix << ".toArray())";
-  } else if (ttype->is_list()) {
-    indent(out) << "for each (var " << iter << ":* in " << prefix << ")";
-  }
-
-  scope_up(out);
-
-  if (ttype->is_map()) {
-    generate_serialize_map_element(out, (t_map*)ttype, iter, prefix);
-  } else if (ttype->is_set()) {
-    generate_serialize_set_element(out, (t_set*)ttype, iter);
-  } else if (ttype->is_list()) {
-    generate_serialize_list_element(out, (t_list*)ttype, iter);
-  }
-
-  scope_down(out);
-
-  if (ttype->is_map()) {
-    indent(out) << "oprot.writeMapEnd();" << endl;
-  } else if (ttype->is_set()) {
-    indent(out) << "oprot.writeSetEnd();" << endl;
-  } else if (ttype->is_list()) {
-    indent(out) << "oprot.writeListEnd();" << endl;
-  }
-
-  scope_down(out);
-}
-
-/**
- * Serializes the members of a map.
- */
-void t_as3_generator::generate_serialize_map_element(ostream& out,
-                                                     t_map* tmap,
-                                                     string iter,
-                                                     string map) {
-  t_field kfield(tmap->get_key_type(), iter);
-  generate_serialize_field(out, &kfield, "");
-  t_field vfield(tmap->get_val_type(), map + "[" + iter + "]");
-  generate_serialize_field(out, &vfield, "");
-}
-
-/**
- * Serializes the members of a set.
- */
-void t_as3_generator::generate_serialize_set_element(ostream& out, t_set* tset, string iter) {
-  t_field efield(tset->get_elem_type(), iter);
-  generate_serialize_field(out, &efield, "");
-}
-
-/**
- * Serializes the members of a list.
- */
-void t_as3_generator::generate_serialize_list_element(ostream& out, t_list* tlist, string iter) {
-  t_field efield(tlist->get_elem_type(), iter);
-  generate_serialize_field(out, &efield, "");
-}
-
-/**
- * Returns a As3 type name
- *
- * @param ttype The type
- * @param container Is the type going inside a container?
- * @return As3 type name, i.e. HashMap<Key,Value>
- */
-string t_as3_generator::type_name(t_type* ttype, bool in_container, bool in_init) {
-  (void)in_init;
-  // In As3 typedefs are just resolved to their real type
-  ttype = get_true_type(ttype);
-  string prefix;
-
-  if (ttype->is_base_type()) {
-    return base_type_name((t_base_type*)ttype, in_container);
-  } else if (ttype->is_enum()) {
-    return "int";
-  } else if (ttype->is_map()) {
-    return "Dictionary";
-  } else if (ttype->is_set()) {
-    return "Set";
-  } else if (ttype->is_list()) {
-    return "Array";
-  }
-
-  // Check for namespacing
-  t_program* program = ttype->get_program();
-  if (program != nullptr && program != program_) {
-    string package = program->get_namespace("as3");
-    if (!package.empty()) {
-      return package + "." + ttype->get_name();
-    }
-  }
-
-  return ttype->get_name();
-}
-
-/**
- * Returns the AS3 type that corresponds to the thrift type.
- *
- * @param tbase The base type
- * @param container Is it going in a As3 container?
- */
-string t_as3_generator::base_type_name(t_base_type* type, bool in_container) {
-  (void)in_container;
-  t_base_type::t_base tbase = type->get_base();
-
-  switch (tbase) {
-  case t_base_type::TYPE_VOID:
-    return "void";
-  case t_base_type::TYPE_STRING:
-    if (type->is_binary()) {
-      return "ByteArray";
-    } else {
-      return "String";
-    }
-  case t_base_type::TYPE_BOOL:
-    return "Boolean";
-  case t_base_type::TYPE_I8:
-  case t_base_type::TYPE_I16:
-  case t_base_type::TYPE_I32:
-    return "int";
-  case t_base_type::TYPE_I64:
-    throw "i64 is not yet supported in as3";
-  case t_base_type::TYPE_DOUBLE:
-    return "Number";
-  default:
-    throw "compiler error: no As3 name for base type " + t_base_type::t_base_name(tbase);
-  }
-}
-
-/**
- * Declares a field, which may include initialization as necessary.
- *
- * @param ttype The type
- */
-string t_as3_generator::declare_field(t_field* tfield, bool init) {
-  // TODO(mcslee): do we ever need to initialize the field?
-  string result = "var " + tfield->get_name() + ":" + type_name(tfield->get_type());
-  if (init) {
-    t_type* ttype = get_true_type(tfield->get_type());
-    if (ttype->is_base_type() && tfield->get_value() != nullptr) {
-      std::ofstream dummy;
-      result += " = " + render_const_value(dummy, tfield->get_name(), ttype, tfield->get_value());
-    } else if (ttype->is_base_type()) {
-      t_base_type::t_base tbase = ((t_base_type*)ttype)->get_base();
-      switch (tbase) {
-      case t_base_type::TYPE_VOID:
-        throw "NO T_VOID CONSTRUCT";
-      case t_base_type::TYPE_STRING:
-        result += " = null";
-        break;
-      case t_base_type::TYPE_BOOL:
-        result += " = false";
-        break;
-      case t_base_type::TYPE_I8:
-      case t_base_type::TYPE_I16:
-      case t_base_type::TYPE_I32:
-      case t_base_type::TYPE_I64:
-        result += " = 0";
-        break;
-      case t_base_type::TYPE_DOUBLE:
-        result += " = (double)0";
-        break;
-      }
-
-    } else if (ttype->is_enum()) {
-      result += " = 0";
-    } else if (ttype->is_container()) {
-      result += " = new " + type_name(ttype, false, true) + "()";
-    } else {
-      result += " = new " + type_name(ttype, false, true) + "()";
-      ;
-    }
-  }
-  return result + ";";
-}
-
-/**
- * Renders a function signature of the form 'type name(args)'
- *
- * @param tfunction Function definition
- * @return String of rendered function definition
- */
-string t_as3_generator::function_signature(t_function* tfunction, string prefix) {
-  std::string arguments = argument_list(tfunction->get_arglist());
-  if (!tfunction->is_oneway()) {
-    if (arguments != "") {
-      arguments += ", ";
-    }
-    arguments += "onError:Function, onSuccess:Function";
-  }
-
-  std::string result = "function " + prefix + tfunction->get_name() + "(" + arguments + "):void";
-  return result;
-}
-
-/**
- * Renders a comma separated field list, with type names
- */
-string t_as3_generator::argument_list(t_struct* tstruct) {
-  string result = "";
-
-  const vector<t_field*>& fields = tstruct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-  bool first = true;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-    if (first) {
-      first = false;
-    } else {
-      result += ", ";
-    }
-    result += (*f_iter)->get_name() + ":" + type_name((*f_iter)->get_type());
-  }
-  return result;
-}
-
-/**
- * Converts the parse type to a C++ enum string for the given type.
- */
-string t_as3_generator::type_to_enum(t_type* type) {
-  type = get_true_type(type);
-
-  if (type->is_base_type()) {
-    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-    switch (tbase) {
-    case t_base_type::TYPE_VOID:
-      throw "NO T_VOID CONSTRUCT";
-    case t_base_type::TYPE_STRING:
-      return "TType.STRING";
-    case t_base_type::TYPE_BOOL:
-      return "TType.BOOL";
-    case t_base_type::TYPE_I8:
-      return "TType.BYTE";
-    case t_base_type::TYPE_I16:
-      return "TType.I16";
-    case t_base_type::TYPE_I32:
-      return "TType.I32";
-    case t_base_type::TYPE_I64:
-      return "TType.I64";
-    case t_base_type::TYPE_DOUBLE:
-      return "TType.DOUBLE";
-    }
-  } else if (type->is_enum()) {
-    return "TType.I32";
-  } else if (type->is_struct() || type->is_xception()) {
-    return "TType.STRUCT";
-  } else if (type->is_map()) {
-    return "TType.MAP";
-  } else if (type->is_set()) {
-    return "TType.SET";
-  } else if (type->is_list()) {
-    return "TType.LIST";
-  }
-
-  throw "INVALID TYPE IN type_to_enum: " + type->get_name();
-}
-
-/**
- * Applies the correct style to a string based on the value of nocamel_style_
- */
-std::string t_as3_generator::get_cap_name(std::string name) {
-  name[0] = toupper(name[0]);
-  return name;
-}
-
-string t_as3_generator::constant_name(string name) {
-  string constant_name;
-
-  bool is_first = true;
-  bool was_previous_char_upper = false;
-  for (char character : name) {
-    bool is_upper = isupper(character);
-
-    if (is_upper && !is_first && !was_previous_char_upper) {
-      constant_name += '_';
-    }
-    constant_name += toupper(character);
-
-    is_first = false;
-    was_previous_char_upper = is_upper;
-  }
-
-  return constant_name;
-}
-
-/**
- * Emits a As3Doc comment if the provided object has a doc in Thrift
- */
-void t_as3_generator::generate_as3_doc(ostream& out, t_doc* tdoc) {
-  if (tdoc->has_doc()) {
-    generate_docstring_comment(out, "/**\n", " * ", tdoc->get_doc(), " */\n");
-  }
-}
-
-/**
- * Emits a As3Doc comment if the provided function object has a doc in Thrift
- */
-void t_as3_generator::generate_as3_doc(ostream& out, t_function* tfunction) {
-  if (tfunction->has_doc()) {
-    stringstream ss;
-    ss << tfunction->get_doc();
-    const vector<t_field*>& fields = tfunction->get_arglist()->get_members();
-    vector<t_field*>::const_iterator p_iter;
-    for (p_iter = fields.begin(); p_iter != fields.end(); ++p_iter) {
-      t_field* p = *p_iter;
-      ss << "\n@param " << p->get_name();
-      if (p->has_doc()) {
-        ss << " " << p->get_doc();
-      }
-    }
-    generate_docstring_comment(out, "/**\n", " * ", ss.str(), " */\n");
-  }
-}
-
-std::string t_as3_generator::generate_isset_check(t_field* field) {
-  return generate_isset_check(field->get_name());
-}
-
-std::string t_as3_generator::generate_isset_check(std::string field_name) {
-  return "is" + get_cap_name("set") + get_cap_name(field_name) + "()";
-}
-
-void t_as3_generator::generate_isset_set(ostream& out, t_field* field) {
-  if (!type_can_be_null(field->get_type())) {
-    indent(out) << "this.__isset_" << field->get_name() << " = true;" << endl;
-  }
-}
-
-std::string t_as3_generator::get_enum_class_name(t_type* type) {
-  string package = "";
-  t_program* program = type->get_program();
-  if (program != nullptr && program != program_) {
-    package = program->get_namespace("as3") + ".";
-  }
-  return package + type->get_name();
-}
-
-THRIFT_REGISTER_GENERATOR(
-    as3,
-    "AS3",
-    "    bindable:        Add [bindable] metadata to all the struct classes.\n")
diff --git a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
index ceaa11f..4ef6acf 100644
--- a/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_cpp_generator.cc
@@ -292,6 +292,13 @@
            (ttype->annotations_.find("cpp.customostream") != ttype->annotations_.end());
   }
 
+  /** 
+   * Determine if all fields of t_struct's storage do not throw
+   * Move/Copy Constructors and Assignments applicable for 'noexcept'
+   * Move defaults to 'noexcept'
+   */
+  bool is_struct_storage_not_throwing(t_struct* tstruct) const;
+
 private:
   /**
    * Returns the include prefix to use for a file generated by program, or the
@@ -954,11 +961,13 @@
   indent(out) << tstruct->get_name() << "::" << tstruct->get_name();
 
   if (is_move) {
-    out << "( " << tstruct->get_name() << "&& ";
+    out << "(" << tstruct->get_name() << "&& ";
   } else {
     out << "(const " << tstruct->get_name() << "& ";
   }
   out << tmp_name << ") ";
+  if(is_move || is_struct_storage_not_throwing(tstruct))
+    out << "noexcept ";
   if (is_exception)
     out << ": TException() ";
   out << "{" << endl;
@@ -976,11 +985,14 @@
     if ((*f_iter)->get_req() != t_field::T_REQUIRED)
       has_nonrequired_fields = true;
     indent(out) << (*f_iter)->get_name() << " = "
-                << maybeMove(tmp_name + "." + (*f_iter)->get_name(), is_move) << ";" << endl;
+                << maybeMove(
+                    tmp_name + "." + (*f_iter)->get_name(), 
+                    is_move && is_complex_type((*f_iter)->get_type()))
+                << ";" << endl;
   }
 
   if (has_nonrequired_fields) {
-    indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", is_move) << ";" << endl;
+    indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << endl;
   }
 
   indent_down();
@@ -1005,8 +1017,10 @@
   } else {
     out << "const " << tstruct->get_name() << "& ";
   }
-  out << tmp_name << ") {" << endl;
-
+  out << tmp_name << ") ";
+  if(is_move || is_struct_storage_not_throwing(tstruct))
+    out << "noexcept ";
+  out << "{" << endl;
   indent_up();
 
   const vector<t_field*>& members = tstruct->get_members();
@@ -1021,10 +1035,13 @@
     if ((*f_iter)->get_req() != t_field::T_REQUIRED)
       has_nonrequired_fields = true;
     indent(out) << (*f_iter)->get_name() << " = "
-                << maybeMove(tmp_name + "." + (*f_iter)->get_name(), is_move) << ";" << endl;
+                << maybeMove(
+                    tmp_name + "." + (*f_iter)->get_name(), 
+                    is_move && is_complex_type((*f_iter)->get_type()))
+                << ";" << endl;
   }
   if (has_nonrequired_fields) {
-    indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", is_move) << ";" << endl;
+    indent(out) << "__isset = " << maybeMove(tmp_name + ".__isset", false) << ";" << endl;
   }
 
   indent(out) << "return *this;" << endl;
@@ -1111,47 +1128,71 @@
   indent_up();
 
   if (!pointers) {
+    bool ok_noexcept = is_struct_storage_not_throwing(tstruct);
     // Copy constructor
-    indent(out) << tstruct->get_name() << "(const " << tstruct->get_name() << "&);" << endl;
+    indent(out) << tstruct->get_name() << "(const " << tstruct->get_name() << "&)"
+                << (ok_noexcept? " noexcept" : "") << ';' << endl;
 
     // Move constructor
     if (gen_moveable_) {
-      indent(out) << tstruct->get_name() << "(" << tstruct->get_name() << "&&);" << endl;
+      indent(out) << tstruct->get_name() << "(" << tstruct->get_name() << "&&) noexcept;" 
+                  << endl;
     }
 
     // Assignment Operator
-    indent(out) << tstruct->get_name() << "& operator=(const " << tstruct->get_name() << "&);"
-                << endl;
+    indent(out) << tstruct->get_name() << "& operator=(const " << tstruct->get_name() << "&)"
+                << (ok_noexcept? " noexcept" : "") << ';' << endl;
 
     // Move assignment operator
     if (gen_moveable_) {
-      indent(out) << tstruct->get_name() << "& operator=(" << tstruct->get_name() << "&&);" << endl;
+      indent(out) << tstruct->get_name() << "& operator=(" << tstruct->get_name() << "&&) noexcept;" 
+                  << endl;
+    }
+
+    bool has_default_value = false;
+    for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
+      t_type* t = get_true_type((*m_iter)->get_type());
+      if (is_reference(*m_iter) || t->is_string()) {
+        t_const_value* cv = (*m_iter)->get_value();
+        if (cv != nullptr) {
+          has_default_value = true;
+          break;
+        }
+      }
     }
 
     // Default constructor
-    indent(out) << tstruct->get_name() << "()";
+    std::string clsname_ctor = tstruct->get_name() + "()";
+    indent(out) << clsname_ctor << (has_default_value ? "" : " noexcept");
 
     bool init_ctor = false;
+    std::string args_indent(
+      indent().size() + clsname_ctor.size() + (has_default_value ? 3 : -1), ' ');
 
     for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
       t_type* t = get_true_type((*m_iter)->get_type());
       if (t->is_base_type() || t->is_enum() || is_reference(*m_iter)) {
         string dval;
-        if (t->is_enum()) {
-          dval += "(" + type_name(t) + ")";
-        }
-        dval += (t->is_string() || is_reference(*m_iter)) ? "" : "0";
         t_const_value* cv = (*m_iter)->get_value();
         if (cv != nullptr) {
-          dval = render_const_value(out, (*m_iter)->get_name(), t, cv);
+          dval += render_const_value(out, (*m_iter)->get_name(), t, cv);
+        } else if (t->is_enum()) {
+          dval += "static_cast<" + type_name(t) + ">(0)";
+        } else {
+          dval += (t->is_string() || is_reference(*m_iter)) ? "" : "0";
         }
         if (!init_ctor) {
           init_ctor = true;
-          out << " : ";
-          out << (*m_iter)->get_name() << "(" << dval << ")";
+          if(has_default_value) {
+            out << " : ";
+          } else {
+            out << '\n' << args_indent << ": ";
+            args_indent.append("  ");
+          }
         } else {
-          out << ", " << (*m_iter)->get_name() << "(" << dval << ")";
+          out << ",\n" << args_indent;
         }
+        out << (*m_iter)->get_name() << "(" << dval << ")";
       }
     }
     out << " {" << endl;
@@ -1248,7 +1289,10 @@
           << "uint32_t read(Protocol_* iprot);" << endl;
     } else {
       out << indent() << "uint32_t read("
-          << "::apache::thrift::protocol::TProtocol* iprot);" << endl;
+          << "::apache::thrift::protocol::TProtocol* iprot)";
+      if(!is_exception && !extends.empty())
+        out << " override";
+      out << ';' << endl;
     }
   }
   if (write) {
@@ -1257,7 +1301,10 @@
           << "uint32_t write(Protocol_* oprot) const;" << endl;
     } else {
       out << indent() << "uint32_t write("
-          << "::apache::thrift::protocol::TProtocol* oprot) const;" << endl;
+          << "::apache::thrift::protocol::TProtocol* oprot) const";
+      if(!is_exception && !extends.empty())
+        out << " override";
+      out << ';' << endl;
     }
   }
   out << endl;
@@ -1697,6 +1744,8 @@
     out << tstruct->get_name() << "::";
   }
   out << "what() const noexcept";
+  if(!external)
+    out << " override";
 }
 
 namespace struct_ostream_operator_generator {
@@ -2059,8 +2108,10 @@
   f_header_ << indent() << "typedef " << service_if_name << " Handler;" << endl << endl << indent()
             << "virtual ~" << factory_name << "() {}" << endl << endl << indent() << "virtual "
             << service_if_name << "* getHandler("
-            << "const ::apache::thrift::TConnectionInfo& connInfo) = 0;" << endl << indent()
-            << "virtual void releaseHandler(" << base_if_name << "* /* handler */) = 0;" << endl;
+            << "const ::apache::thrift::TConnectionInfo& connInfo)"
+            << (extends.empty() ? "" : " override") << " = 0;" << endl << indent()
+            << "virtual void releaseHandler(" << base_if_name << "* /* handler */)"
+            << (extends.empty() ? "" : " override") << " = 0;" << endl << indent();
 
   indent_down();
   f_header_ << "};" << endl << endl;
@@ -2074,9 +2125,9 @@
             << ">& iface) : iface_(iface) {}" << endl << indent() << "virtual ~"
             << singleton_factory_name << "() {}" << endl << endl << indent() << "virtual "
             << service_if_name << "* getHandler("
-            << "const ::apache::thrift::TConnectionInfo&) {" << endl << indent()
+            << "const ::apache::thrift::TConnectionInfo&) override {" << endl << indent()
             << "  return iface_.get();" << endl << indent() << "}" << endl << indent()
-            << "virtual void releaseHandler(" << base_if_name << "* /* handler */) {}" << endl;
+            << "virtual void releaseHandler(" << base_if_name << "* /* handler */) override {}" << endl;
 
   f_header_ << endl << " protected:" << endl << indent() << "::std::shared_ptr<" << service_if_name
             << "> iface_;" << endl;
@@ -2102,7 +2153,8 @@
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::iterator f_iter;
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    f_header_ << indent() << function_signature(*f_iter, style, "", false) << " {" << endl;
+    f_header_ << indent() << function_signature(*f_iter, style, "", false)
+              << " override {" << endl;
     indent_up();
 
     t_type* returntype = (*f_iter)->get_returntype();
@@ -2340,7 +2392,7 @@
     }
     call += ")";
 
-    f_header_ << indent() << function_signature(*f_iter, "") << " {" << endl;
+    f_header_ << indent() << function_signature(*f_iter, "") << " override {" << endl;
     indent_up();
     f_header_ << indent() << "size_t sz = ifaces_.size();" << endl << indent() << "size_t i = 0;"
               << endl << indent() << "for (; i < (sz - 1); ++i) {" << endl;
@@ -2547,7 +2599,8 @@
   vector<t_function*>::const_iterator f_iter;
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
     generate_java_doc(f_header_, *f_iter);
-    indent(f_header_) << function_signature(*f_iter, ifstyle) << ";" << endl;
+    indent(f_header_) << function_signature(*f_iter, ifstyle) 
+                      << " override;" << endl;
     // TODO(dreiss): Use private inheritance to avoid generating thise in cob-style.
     if (style == "Concurrent" && !(*f_iter)->is_oneway()) {
       // concurrent clients need to move the seqid from the send function to the
@@ -3096,7 +3149,8 @@
   f_header_ << indent() << "virtual " << ret_type_ << "dispatchCall(" << finish_cob_
             << "::apache::thrift::protocol::TProtocol* iprot, "
             << "::apache::thrift::protocol::TProtocol* oprot, "
-            << "const std::string& fname, int32_t seqid" << call_context_ << ");" << endl;
+            << "const std::string& fname, int32_t seqid" << call_context_ 
+            << ") override;" << endl;
   if (generator_->gen_templates_) {
     f_header_ << indent() << "virtual " << ret_type_ << "dispatchCallTemplated(" << finish_cob_
               << "Protocol_* iprot, Protocol_* oprot, "
@@ -3309,11 +3363,12 @@
   indent_up();
 
   f_header_ << indent() << factory_class_name_ << "(const ::std::shared_ptr< " << if_factory_name
-            << " >& handlerFactory) :" << endl << indent()
+            << " >& handlerFactory) noexcept :" << endl << indent()
             << "    handlerFactory_(handlerFactory) {}" << endl << endl << indent()
             << "::std::shared_ptr< ::apache::thrift::"
             << (style_ == "Cob" ? "async::TAsyncProcessor" : "TProcessor") << " > "
-            << "getProcessor(const ::apache::thrift::TConnectionInfo& connInfo);" << endl;
+            << "getProcessor(const ::apache::thrift::TConnectionInfo& connInfo) override;"
+            << endl;
 
   f_header_ << endl << " protected:" << endl << indent() << "::std::shared_ptr< "
             << if_factory_name << " > handlerFactory_;" << endl;
@@ -3506,9 +3561,9 @@
             << ") {" << endl;
         if (!tfunction->is_oneway()) {
           indent_up();
-          out << indent() << "result." << (*x_iter)->get_name() << " = " << (*x_iter)->get_name()
-              << ";" << endl << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;"
-              << endl;
+          out << indent() << "result." << (*x_iter)->get_name()
+                          << " = std::move(" << (*x_iter)->get_name() << ");" << endl
+              << indent() << "result.__isset." << (*x_iter)->get_name() << " = true;" << endl;
           indent_down();
           out << indent() << "}";
         } else {
@@ -3945,7 +4000,8 @@
   } else if (type->is_enum()) {
     string t = tmp("ecast");
     out << indent() << "int32_t " << t << ";" << endl << indent() << "xfer += iprot->readI32(" << t
-        << ");" << endl << indent() << name << " = (" << type_name(type) << ")" << t << ";" << endl;
+        << ");" << endl << indent() << name << " = static_cast<" 
+        << type_name(type) << ">(" << t << ");" << endl;
   } else {
     printf("DO NOT KNOW HOW TO DESERIALIZE FIELD '%s' TYPE '%s'\n",
            tfield->get_name().c_str(),
@@ -4150,7 +4206,7 @@
             + name;
       }
     } else if (type->is_enum()) {
-      out << "writeI32((int32_t)" << name << ");";
+      out << "writeI32(static_cast<int32_t>(" << name << "));";
     }
     out << endl;
   } else {
@@ -4485,13 +4541,13 @@
         result += " = 0";
         break;
       case t_base_type::TYPE_DOUBLE:
-        result += " = (double)0";
+        result += " = 0.0";
         break;
       default:
         throw "compiler error: no C++ initializer for base type " + t_base_type::t_base_name(tbase);
       }
     } else if (type->is_enum()) {
-      result += " = (" + type_name(type) + ")0";
+      result += " = static_cast<" + type_name(type) + ">(0)";
     }
   }
   if (!reference) {
@@ -4619,6 +4675,44 @@
   throw "INVALID TYPE IN type_to_enum: " + type->get_name();
 }
 
+
+bool t_cpp_generator::is_struct_storage_not_throwing(t_struct* tstruct) const {
+  vector<t_field*> members = tstruct->get_members();
+
+  for(size_t i=0; i < members.size(); ++i)  {
+    t_type* type = get_true_type(members[i]->get_type());
+
+    if(type->is_enum())
+      continue;
+    if(type->is_xception())
+      return false;
+    if(type->is_base_type()) switch(((t_base_type*)type)->get_base()) {
+      case t_base_type::TYPE_BOOL:
+      case t_base_type::TYPE_I8:
+      case t_base_type::TYPE_I16:
+      case t_base_type::TYPE_I32:
+      case t_base_type::TYPE_I64:
+      case t_base_type::TYPE_DOUBLE:
+        continue;
+      case t_base_type::TYPE_VOID:
+      case t_base_type::TYPE_STRING:
+      default:
+        return false;
+    }
+    if(type->is_struct()) {
+      const vector<t_field*>& more = ((t_struct*)type)->get_members();
+      for(auto it = more.begin(); it < more.end(); ++it) {
+        if(std::find(members.begin(), members.end(), *it) == members.end())
+          members.push_back(*it);
+      }
+      continue;
+    }
+    return false; // rest-as-throwing(require-alloc)
+  }
+  return true;
+}
+
+
 string t_cpp_generator::get_include_prefix(const t_program& program) const {
   string include_prefix = program.get_include_prefix();
   if (!use_include_prefix_ || (include_prefix.size() > 0 && include_prefix[0] == '/')) {
diff --git a/compiler/cpp/src/thrift/generate/t_erl_generator.cc b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
index c96c1b2..af3492a 100644
--- a/compiler/cpp/src/thrift/generate/t_erl_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_erl_generator.cc
@@ -56,7 +56,6 @@
 
     legacy_names_ = false;
     maps_ = false;
-    otp16_ = false;
     export_lines_first_ = true;
     export_types_lines_first_ = true;
 
@@ -65,17 +64,11 @@
         legacy_names_ = true;
       } else if( iter->first.compare("maps") == 0) {
         maps_ = true;
-      } else if( iter->first.compare("otp16") == 0) {
-        otp16_ = true;
       } else {
         throw "unknown option erl:" + iter->first;
       }
     }
 
-    if (maps_ && otp16_) {
-      throw "argument error: Cannot specify both maps and otp16; maps are not available for Erlang/OTP R16 or older";
-    }
-
     out_dir_base_ = "gen-erl";
   }
 
@@ -184,9 +177,6 @@
   /* if true use maps instead of dicts in generated code */
   bool maps_;
 
-  /* if true use non-namespaced dict and set instead of dict:dict and sets:set */
-  bool otp16_;
-
   /**
    * add function to export list
    */
@@ -748,17 +738,11 @@
   } else if (type->is_map()) {
     if (maps_) {
       return "map()";
-    } else if (otp16_) {
-      return "dict()";
     } else {
       return "dict:dict()";
     }
   } else if (type->is_set()) {
-    if (otp16_) {
-      return "set()";
-    } else {
       return "sets:set()";
-    }
   } else if (type->is_list()) {
     return "list()";
   } else {
@@ -1278,5 +1262,4 @@
     erl,
     "Erlang",
     "    legacynames:     Output files retain naming conventions of Thrift 0.9.1 and earlier.\n"
-    "    maps:            Generate maps instead of dicts.\n"
-    "    otp16:           Generate non-namespaced dict and set instead of dict:dict and sets:set.\n")
+    "    maps:            Generate maps instead of dicts.\n")
diff --git a/compiler/cpp/src/thrift/generate/t_generator.cc b/compiler/cpp/src/thrift/generate/t_generator.cc
index d87af89..f26690b 100644
--- a/compiler/cpp/src/thrift/generate/t_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_generator.cc
@@ -237,12 +237,6 @@
   if ((language == "csharp") || (language == "netcore")) {
     failure("The '%s' target is no longer available. Use 'netstd' instead.", language.c_str());
   }
-  else if (language == "as3") {
-    pwarning(1, "The '%s' target is deprecated and will be removed in future Thrift versions.", language.c_str());
-  }
-  else if (language == "hs") {
-    pwarning(1, "The '%s' target is deprecated and will be removed in future Thrift versions.", language.c_str());
-  }
 
   if (iter == the_map.end()) {
     return nullptr;
diff --git a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
index 7f1bb6f..111e0f6 100644
--- a/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_haxe_generator.cc
@@ -52,12 +52,11 @@
     (void)option_string;
     std::map<std::string, std::string>::const_iterator iter;
 
-    callbacks_ = false;
     rtti_ = false;
     buildmacro_ = "";
     for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
       if( iter->first.compare("callbacks") == 0) {
-        callbacks_ = true;
+        printf("Hint: The 'callbacks' option is no longer necessary.\n");
       } else if( iter->first.compare("rtti") == 0) {
         rtti_ = true;
       } else if( iter->first.compare("buildmacro") == 0) {
@@ -115,7 +114,7 @@
   void generate_haxe_validator(std::ostream& out, t_struct* tstruct);
   void generate_haxe_struct_result_writer(std::ostream& out, t_struct* tstruct);
   void generate_haxe_struct_writer(std::ostream& out, t_struct* tstruct);
-  void generate_haxe_struct_tostring(std::ostream& out, t_struct* tstruct);
+  void generate_haxe_struct_tostring(std::ostream& out, t_struct* tstruct, bool is_override);
   void generate_haxe_meta_data_map(std::ostream& out, t_struct* tstruct);
   void generate_field_value_meta_data(std::ostream& out, t_type* type);
   std::string get_haxe_type_string(t_type* type);
@@ -138,12 +137,12 @@
   void generate_isset_set(ostream& out, t_field* field);
   // removed std::string isset_field_id(t_field* field);
 
-  void generate_service_interface(t_service* tservice);
+  void generate_service_interface(t_service* tservice, bool combined);
   void generate_service_helpers(t_service* tservice);
   void generate_service_client(t_service* tservice);
   void generate_service_server(t_service* tservice);
   void generate_process_function(t_service* tservice, t_function* tfunction);
-  void generate_service_method_signature(t_function* tfunction, bool is_interface);
+  void generate_service_method_signature(t_function* tfunction, bool is_interface, bool combined);
 
   /**
    * Serialization constructs
@@ -186,13 +185,13 @@
   std::string type_name(t_type* ttype, bool in_container = false, bool in_init = false);
   std::string base_type_name(t_base_type* tbase, bool in_container = false);
   std::string declare_field(t_field* tfield, bool init = false);
-  std::string function_signature_callback(t_function* tfunction);
+  std::string function_signature_combined(t_function* tfunction);
   std::string function_signature_normal(t_function* tfunction);
   std::string argument_list(t_struct* tstruct);
   std::string type_to_enum(t_type* ttype);
   std::string get_enum_class_name(t_type* type) override;
   string generate_service_method_onsuccess(t_function* tfunction, bool as_type, bool omit_name);
-  void generate_service_method_signature_callback(t_function* tfunction, bool is_interface);
+  void generate_service_method_signature_combined(t_function* tfunction, bool is_interface);
   void generate_service_method_signature_normal(t_function* tfunction, bool is_interface);
 
   bool type_can_be_null(t_type* ttype) {
@@ -218,9 +217,9 @@
   }
 
   std::string constant_name(std::string name);
+  std::string make_package_name(std::string value);
 
 private:
-  bool callbacks_;
   bool rtti_;
   string buildmacro_;
 
@@ -242,19 +241,7 @@
 void t_haxe_generator::init_generator() {
   // Make output directory
   MKDIR(get_out_dir().c_str());
-  package_name_ = program_->get_namespace("haxe");
-
-  // Haxe package names are lowercase
-  if (package_name_.length() > 0) {
-    package_name_[0] = tolower(package_name_[0]);
-    size_t index = package_name_.find('.');
-    while (index != std::string::npos) {
-      if (++index < package_name_.length()) {
-        package_name_[index] = tolower(package_name_[index]);
-      }
-      index = package_name_.find('.', index);
-    }
-  }
+  package_name_ = make_package_name( program_->get_namespace("haxe"));
 
   string dir = package_name_;
   string subdir = get_out_dir();
@@ -272,6 +259,24 @@
   package_dir_ = subdir;
 }
 
+// Haxe package names start with lowercase letters
+std::string t_haxe_generator::make_package_name(std::string value) {
+  std::string retval(value);
+
+  if (retval.length() > 0) {
+    retval[0] = tolower(retval[0]);
+    size_t index = retval.find('.');
+    while (index != std::string::npos) {
+      if (++index < retval.length()) {
+        retval[index] = tolower(retval[index]);
+      }
+      index = retval.find('.', index);
+    }
+  }
+
+  return retval;
+}
+
 /**
  * Packages the generated file
  *
@@ -290,10 +295,17 @@
  * @return List of imports for haxe types that are used in here
  */
 string t_haxe_generator::haxe_type_imports() {
-  return string() + "import org.apache.thrift.helper.*;\n" + "import haxe.io.Bytes;\n"
-         + "import haxe.ds.IntMap;\n" + "import haxe.ds.StringMap;\n"
-         + "import haxe.ds.ObjectMap;\n" + "\n" + "#if flash\n"
-         + "import flash.errors.ArgumentError;\n" + "#end\n" + "\n";
+  return string()
+       + "import org.apache.thrift.helper.*;\n"
+       + "import haxe.io.Bytes;\n"
+       + "import haxe.ds.IntMap;\n"
+       + "import haxe.ds.StringMap;\n"
+       + "import haxe.ds.ObjectMap;\n"
+       + "\n"
+       + "#if flash\n"
+       + "import flash.errors.ArgumentError;\n"
+       + "#end\n"
+       + "\n";
 }
 
 /**
@@ -302,8 +314,11 @@
  * @return List of imports necessary for thrift
  */
 string t_haxe_generator::haxe_thrift_imports() {
-  return string() + "import org.apache.thrift.*;\n" + "import org.apache.thrift.meta_data.*;\n"
-         + "import org.apache.thrift.protocol.*;\n" + "\n";
+  return string()
+       + "import org.apache.thrift.*;\n"
+       + "import org.apache.thrift.meta_data.*;\n"
+       + "import org.apache.thrift.protocol.*;\n"
+       + "\n";
 }
 
 /**
@@ -320,7 +335,7 @@
   for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
     t_program* program = (*m_iter)->get_type()->get_program();
     if (program != nullptr && program != program_) {
-      string package = program->get_namespace("haxe");
+      string package = make_package_name( program->get_namespace("haxe"));
       if (!package.empty()) {
         if (imports.find(package + "." + (*m_iter)->get_type()->get_name()) == string::npos) {
           imports.append("import " + package + "." + (*m_iter)->get_type()->get_name() + ";\n");
@@ -345,11 +360,10 @@
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
     t_program* program = (*f_iter)->get_returntype()->get_program();
     if (program != nullptr && program != program_) {
-      string package = program->get_namespace("haxe");
+      string package = make_package_name( program->get_namespace("haxe"));
       if (!package.empty()) {
         if (imports.find(package + "." + (*f_iter)->get_returntype()->get_name()) == string::npos) {
-          imports.append("import " + package + "." + (*f_iter)->get_returntype()->get_name()
-                         + ";\n");
+          imports.append("import " + package + "." + (*f_iter)->get_returntype()->get_name()+ ";\n");
         }
       }
     }
@@ -718,10 +732,8 @@
   if (is_exception) {
     out << "extends TException ";
   }
-  out << "implements TBase ";
-
-  scope_up(out);
-  indent(out) << endl;
+  out << "implements TBase {" << endl << endl;
+  indent_up();
 
   indent(out) << "static var STRUCT_DESC = { new TStruct(\"" << tstruct->get_name() << "\"); };"
               << endl;
@@ -806,7 +818,7 @@
   } else {
     generate_haxe_struct_writer(out, tstruct);
   }
-  generate_haxe_struct_tostring(out, tstruct);
+  generate_haxe_struct_tostring(out, tstruct, is_exception);
   generate_haxe_validator(out, tstruct);
   scope_down(out);
   out << endl;
@@ -1272,9 +1284,12 @@
  *
  * @param tstruct The struct definition
  */
-void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tstruct) {
-  out << indent() << "public "
-      << "function toString() : String {" << endl;
+void t_haxe_generator::generate_haxe_struct_tostring(ostream& out, t_struct* tstruct, bool is_override) {
+  out << indent() << "public ";
+  if( is_override) {
+    out << "override ";
+  }
+  out << "function toString() : String {" << endl;
   indent_up();
 
   out << indent() << "var ret : String = \"" << tstruct->get_name() << "(\";" << endl;
@@ -1399,7 +1414,7 @@
   } else if (type->is_base_type()) {
     switch (((t_base_type*)type)->get_base()) {
     case t_base_type::TYPE_VOID:
-      return "TType.VOID";
+      return "TType.VOID_";
       break;
     case t_base_type::TYPE_STRING:
       return "TType.STRING";
@@ -1474,8 +1489,8 @@
  * @param tservice The service definition
  */
 void t_haxe_generator::generate_service(t_service* tservice) {
-  // Make interface file
-  string f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + ".hx";
+  // Make service interface file with only "normal" calls
+  string f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "_service.hx";
   f_service_.open(f_service_name.c_str());
 
   f_service_ << autogen_comment() << haxe_package() << ";" << endl;
@@ -1485,7 +1500,29 @@
 
   if (tservice->get_extends() != nullptr) {
     t_type* parent = tservice->get_extends();
-    string parent_namespace = parent->get_program()->get_namespace("haxe");
+    string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe"));
+    if (!parent_namespace.empty() && parent_namespace != package_name_) {
+      f_service_ << "import " << type_name(parent) << "_service;" << endl;
+    }
+  }
+
+  f_service_ << endl;
+
+  generate_service_interface(tservice,false);
+  f_service_.close();
+
+  // Client interface file with dual suppport ("normal" and "callback" style)
+  f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + ".hx";
+  f_service_.open(f_service_name.c_str());
+
+  f_service_ << autogen_comment() << haxe_package() << ";" << endl;
+
+  f_service_ << endl << haxe_type_imports() << haxe_thrift_imports()
+             << haxe_thrift_gen_imports(tservice);
+
+  if (tservice->get_extends() != nullptr) {
+    t_type* parent = tservice->get_extends();
+    string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe"));
     if (!parent_namespace.empty() && parent_namespace != package_name_) {
       f_service_ << "import " << type_name(parent) << ";" << endl;
     }
@@ -1493,8 +1530,7 @@
 
   f_service_ << endl;
 
-  generate_service_interface(tservice);
-
+  generate_service_interface(tservice,true);
   f_service_.close();
 
   // Now make the implementation/client file
@@ -1506,7 +1542,7 @@
 
   if (tservice->get_extends() != nullptr) {
     t_type* parent = tservice->get_extends();
-    string parent_namespace = parent->get_program()->get_namespace("haxe");
+    string parent_namespace = make_package_name( parent->get_program()->get_namespace("haxe"));
     if (!parent_namespace.empty() && parent_namespace != package_name_) {
       f_service_ << "import " << type_name(parent) << "Impl;" << endl;
     }
@@ -1515,7 +1551,6 @@
   f_service_ << endl;
 
   generate_service_client(tservice);
-
   f_service_.close();
 
   // Now make the helper class files
@@ -1525,18 +1560,20 @@
   f_service_name = package_dir_ + "/" + get_cap_name(service_name_) + "Processor.hx";
   f_service_.open(f_service_name.c_str());
 
-  f_service_ << autogen_comment() << haxe_package() << ";" << endl << endl << haxe_type_imports()
-             << haxe_thrift_imports() << haxe_thrift_gen_imports(tservice) << endl;
+  f_service_ << autogen_comment() << haxe_package() << ";" << endl 
+             << endl 
+             << haxe_type_imports()
+             << haxe_thrift_imports() 
+             << haxe_thrift_gen_imports(tservice) 
+             << endl;
 
   if (!package_name_.empty()) {
     f_service_ << "import " << package_name_ << ".*;" << endl;
-    f_service_ << "import " << package_name_ << "." << get_cap_name(service_name_).c_str()
-               << "Impl;" << endl;
+    f_service_ << "import " << package_name_ << "." << get_cap_name(service_name_).c_str() << "Impl;" << endl;
     f_service_ << endl;
   }
 
   generate_service_server(tservice);
-
   f_service_.close();
 }
 
@@ -1580,9 +1617,9 @@
  *
  * @param tfunction The service function to generate code for.
  */
-void t_haxe_generator::generate_service_method_signature(t_function* tfunction, bool is_interface) {
-  if (callbacks_) {
-    generate_service_method_signature_callback(tfunction, is_interface);
+void t_haxe_generator::generate_service_method_signature(t_function* tfunction, bool is_interface, bool combined) {
+  if( combined) {
+    generate_service_method_signature_combined(tfunction, is_interface);
   } else {
     generate_service_method_signature_normal(tfunction, is_interface);
   }
@@ -1607,7 +1644,7 @@
  *
  * @param tfunction The service function to generate code for.
  */
-void t_haxe_generator::generate_service_method_signature_callback(t_function* tfunction,
+void t_haxe_generator::generate_service_method_signature_combined(t_function* tfunction,
                                                                   bool is_interface) {
   if (!tfunction->is_oneway()) {
     std::string on_success_impl = generate_service_method_onsuccess(tfunction, false, false);
@@ -1616,9 +1653,9 @@
   }
 
   if (is_interface) {
-    indent(f_service_) << function_signature_callback(tfunction) << ";" << endl << endl;
+    indent(f_service_) << function_signature_combined(tfunction) << ";" << endl << endl;
   } else {
-    indent(f_service_) << "public " << function_signature_callback(tfunction) << " {" << endl;
+    indent(f_service_) << "public " << function_signature_combined(tfunction) << " {" << endl;
   }
 }
 
@@ -1627,24 +1664,26 @@
  *
  * @param tservice The service to generate a header definition for
  */
-void t_haxe_generator::generate_service_interface(t_service* tservice) {
+void t_haxe_generator::generate_service_interface(t_service* tservice, bool combined) {
+  string cbk_postfix = combined ? "" : "_service";
+
   string extends_iface = "";
   if (tservice->get_extends() != nullptr) {
-    extends_iface = " extends " + tservice->get_extends()->get_name();
+    extends_iface = " extends " + tservice->get_extends()->get_name() + cbk_postfix;
   }
 
-  generate_haxe_doc(f_service_, tservice);
-  // generate_rtti_decoration(f_service_); - not yet, because of
-  // https://github.com/HaxeFoundation/haxe/issues/3626
-  generate_macro_decoration(f_service_);
-  f_service_ << indent() << "interface " << get_cap_name(service_name_) << extends_iface << " {"
-             << endl << endl;
-  indent_up();
   vector<t_function*> functions = tservice->get_functions();
   vector<t_function*>::iterator f_iter;
+
+  generate_haxe_doc(f_service_, tservice);
+  generate_rtti_decoration(f_service_);
+  generate_macro_decoration(f_service_);
+  f_service_ << indent() << "interface " << get_cap_name(service_name_) << cbk_postfix << extends_iface << " {"
+             << endl << endl;
+  indent_up();
   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
     generate_haxe_doc(f_service_, *f_iter);
-    generate_service_method_signature(*f_iter, true);
+    generate_service_method_signature(*f_iter, true, combined);
   }
   indent_down();
   f_service_ << indent() << "}" << endl << endl;
@@ -1729,7 +1768,7 @@
     string funname = (*f_iter)->get_name();
 
     // Open function
-    generate_service_method_signature(*f_iter, false);
+    generate_service_method_signature(*f_iter, false, true);
 
     indent_up();
 
@@ -1741,21 +1780,23 @@
     const vector<t_field*>& fields = arg_struct->get_members();
 
     // Serialize the request
+    string args = tmp("args");
     string calltype = (*f_iter)->is_oneway() ? "ONEWAY" : "CALL";
     f_service_ << indent() << "oprot_.writeMessageBegin(new TMessage(\"" << funname
                << "\", TMessageType." << calltype << ", seqid_));" << endl << indent()
-               << "var args : " << argsname << " = new " << argsname << "();" << endl;
+               << "var " << args << " : " << argsname << " = new " << argsname << "();" << endl;
 
     for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter) {
-      f_service_ << indent() << "args." << (*fld_iter)->get_name() << " = "
+      f_service_ << indent() << args << "." << (*fld_iter)->get_name() << " = "
                  << (*fld_iter)->get_name() << ";" << endl;
     }
 
-    f_service_ << indent() << "args.write(oprot_);" << endl << indent()
+    f_service_ << indent() << args << ".write(oprot_);" << endl << indent()
                << "oprot_.writeMessageEnd();" << endl;
 
+    string retval = tmp("retval");
     if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) {
-      f_service_ << indent() << "var retval : " << type_name((*f_iter)->get_returntype()) << ";"
+      f_service_ << indent() << "var " << retval << " : " << type_name((*f_iter)->get_returntype()) << ";"
                  << endl;
     }
 
@@ -1764,109 +1805,108 @@
     } else {
       indent(f_service_) << "oprot_.getTransport().flush(function(error:Dynamic) : Void {" << endl;
       indent_up();
-      if (callbacks_) {
-        indent(f_service_) << "try {" << endl;
-        indent_up();
-      }
+      indent(f_service_) << "try {" << endl;
+      indent_up();
+      string appex = tmp("appex");
+      indent(f_service_) << "var " << appex << " : TApplicationException;" << endl;
       string resultname = get_cap_name((*f_iter)->get_name() + "_result");
       indent(f_service_) << "if (error != null) {" << endl;
       indent_up();
-      if (callbacks_) {
-        indent(f_service_) << "if (onError != null) onError(error);" << endl;
-        indent(f_service_) << "return;" << endl;
-      } else {
-        indent(f_service_) << "throw error;" << endl;
-      }
-      indent_down();
-      indent(f_service_) << "}" << endl;
-      indent(f_service_) << "var msg : TMessage = iprot_.readMessageBegin();" << endl;
-      indent(f_service_) << "if (msg.type == TMessageType.EXCEPTION) {" << endl;
+      indent(f_service_) << "if (onError == null)" << endl;
       indent_up();
-      indent(f_service_) << "var x = TApplicationException.read(iprot_);" << endl;
-      indent(f_service_) << "iprot_.readMessageEnd();" << endl;
-      if (callbacks_) {
-        indent(f_service_) << "if (onError != null) onError(x);" << endl;
-        indent(f_service_) << "return;" << endl;
-      } else {
-        indent(f_service_) << "throw x;" << endl;
-      }
+      indent(f_service_) << "throw error;" << endl;
       indent_down();
-      indent(f_service_) << "}" << endl;
-      indent(f_service_) << "var result : " << resultname << " = new " << resultname << "();"
-                         << endl;
-      indent(f_service_) << "result.read(iprot_);" << endl;
+      indent(f_service_) << "onError(error);" << endl;
+      indent(f_service_) << "return;" << endl;
+      indent_down();
+      indent(f_service_) << "}" << endl << endl;
+      string msg = tmp("msg");
+      indent(f_service_) << "var " << msg << " : TMessage = iprot_.readMessageBegin();" << endl;
+      indent(f_service_) << "if (" << msg << ".type == TMessageType.EXCEPTION) {" << endl;
+      indent_up();
+      indent(f_service_) << appex << " = TApplicationException.read(iprot_);" << endl;
+      indent(f_service_) << "iprot_.readMessageEnd();" << endl;
+      indent(f_service_) << "if (onError == null)" << endl;
+      indent_up();
+      indent(f_service_) << "throw " << appex << ";" << endl;
+      indent_down();
+      indent(f_service_) << "onError(" << appex << ");" << endl;
+      indent(f_service_) << "return;" << endl;
+      indent_down();
+      indent(f_service_) << "}" << endl << endl;
+      string result = tmp("result");
+      indent(f_service_) << "var " << result << " : " << resultname << " = new " << resultname << "();" << endl;
+      indent(f_service_) << "" << result << ".read(iprot_);" << endl;
       indent(f_service_) << "iprot_.readMessageEnd();" << endl;
 
       // Careful, only return _result if not a void function
       if (!(*f_iter)->get_returntype()->is_void()) {
-        indent(f_service_) << "if (result." << generate_isset_check("success") << ") {" << endl;
+        indent(f_service_) << "if (" << result << "." << generate_isset_check("success") << ") {" << endl;
         indent_up();
-        if (callbacks_) {
-          indent(f_service_) << "if (onSuccess != null) onSuccess(result.success);" << endl;
-          indent(f_service_) << "return;" << endl;
-        } else {
-          indent(f_service_) << "retval = result.success;" << endl;
-          indent(f_service_) << "return;" << endl;
-        }
+        indent(f_service_) << "if (onSuccess != null)" << endl;
+        indent_up();
+        indent(f_service_) << "onSuccess(" << result << ".success);" << endl;
         indent_down();
-        indent(f_service_) << "}" << endl;
+        indent(f_service_) << retval << " = " << result << ".success;" << endl;
+        indent(f_service_) << "return;" << endl;
+        indent_down();
+        indent(f_service_) << "}" << endl << endl;
       }
 
       t_struct* xs = (*f_iter)->get_xceptions();
       const std::vector<t_field*>& xceptions = xs->get_members();
       vector<t_field*>::const_iterator x_iter;
       for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-        indent(f_service_) << "if (result." << (*x_iter)->get_name() << " != null) {" << endl;
+        indent(f_service_) << "if (" << result << "." << (*x_iter)->get_name() << " != null) {" << endl;
         indent_up();
-        if (callbacks_) {
-          indent(f_service_) << "if (onError != null) onError(result." << (*x_iter)->get_name()
-                             << ");" << endl;
-          indent(f_service_) << "return;" << endl;
-        } else {
-          indent(f_service_) << "throw result." << (*x_iter)->get_name() << ";" << endl;
-        }
+        indent(f_service_) << "if (onError == null)" << endl;
+        indent_up();
+        indent(f_service_) << "throw " << result << "." << (*x_iter)->get_name() << ";" << endl;
         indent_down();
-        indent(f_service_) << "}" << endl;
+        indent(f_service_) << "onError(" << result << "." << (*x_iter)->get_name() << ");" << endl;
+        indent(f_service_) << "return;" << endl;
+        indent_down();
+        indent(f_service_) << "}" << endl << endl;
       }
 
       // If you get here it's an exception, unless a void function
       if ((*f_iter)->get_returntype()->is_void()) {
-        if (callbacks_) {
-          indent(f_service_) << "if (onSuccess != null) onSuccess();" << endl;
-        }
+        indent(f_service_) << "if (onSuccess != null)" << endl;
+        indent_up();
+        indent(f_service_) << "onSuccess();" << endl;
+        indent_down();
         indent(f_service_) << "return;" << endl;
       } else {
-        if (callbacks_) {
-          indent(f_service_) << "if (onError != null)" << endl;
-          indent_up();
-          indent(f_service_)
-              << "onError( new TApplicationException(TApplicationException.MISSING_RESULT," << endl;
-          indent(f_service_) << "                               \"" << (*f_iter)->get_name()
-                             << " failed: unknown result\"));" << endl;
-          indent_down();
-        } else {
-          indent(f_service_)
-              << "throw new TApplicationException(TApplicationException.MISSING_RESULT," << endl;
-          indent(f_service_) << "                            \"" << (*f_iter)->get_name()
-                             << " failed: unknown result\");" << endl;
-        }
-      }
-
-      if (callbacks_) {
-        indent_down();
-        indent(f_service_) << "} catch( e : TException) {" << endl;
+        indent(f_service_) << appex << " = new TApplicationException("
+                           << "TApplicationException.MISSING_RESULT,"
+                           << "\"" << (*f_iter)->get_name() << " failed: unknown result\");" << endl;
+        indent(f_service_) << "if (onError == null)" << endl;
         indent_up();
-        indent(f_service_) << "if (onError != null) onError(e);" << endl;
+        indent(f_service_) << "throw " << appex << ";" << endl;
         indent_down();
-        indent(f_service_) << "}" << endl;
+        indent(f_service_) << "onError(" << appex << ");" << endl;
+        indent(f_service_) << "return;" << endl;
       }
 
       indent_down();
-      indent(f_service_) << "});" << endl;
+      indent(f_service_) << endl;
+      indent(f_service_) << "} catch( e : TException) {" << endl;
+      indent_up();
+      indent(f_service_) << "if (onError == null)" << endl;
+      indent_up();
+      indent(f_service_) << "throw e;" << endl;
+      indent_down();
+      indent(f_service_) << "onError(e);" << endl;
+      indent(f_service_) << "return;" << endl;
+      indent_down();
+      indent(f_service_) << "}" << endl;
+
+      indent_down();
+      indent(f_service_) << "});" << endl << endl;
     }
 
     if (!((*f_iter)->is_oneway() || (*f_iter)->get_returntype()->is_void())) {
-      f_service_ << indent() << "return retval;" << endl;
+      f_service_ << indent() << "return " << retval << ";" << endl;
     }
 
     // Close function
@@ -1904,7 +1944,7 @@
   indent_up();
 
   f_service_ << indent() << "private var " << get_cap_name(service_name_)
-             << "_iface_ : " << get_cap_name(service_name_) << ";" << endl;
+             << "_iface_ : " << get_cap_name(service_name_) << "_service;" << endl;
 
   if (extends.empty()) {
     f_service_ << indent()
@@ -1914,7 +1954,7 @@
 
   f_service_ << endl;
 
-  indent(f_service_) << "public function new( iface : " << get_cap_name(service_name_) << ")"
+  indent(f_service_) << "public function new( iface : " << get_cap_name(service_name_) << "_service)"
                      << endl;
   scope_up(f_service_);
   if (!extends.empty()) {
@@ -1943,20 +1983,20 @@
   f_service_ << indent() << "var msg : TMessage = iprot.readMessageBegin();" << endl;
 
   // TODO(mcslee): validate message, was the seqid etc. legit?
-  // AS- If all method is oneway:
-  // do you have an oprot?
-  // do you you need nullcheck?
+
   f_service_
-      << indent() << "var fn  = PROCESS_MAP.get(msg.name);" << endl << indent()
-      << "if (fn == null) {" << endl << indent() << "  TProtocolUtil.skip(iprot, TType.STRUCT);"
-      << endl << indent() << "  iprot.readMessageEnd();" << endl << indent()
-      << "  var x = new TApplicationException(TApplicationException.UNKNOWN_METHOD, \"Invalid "
-         "method name: '\"+msg.name+\"'\");" << endl << indent()
-      << "  oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));"
-      << endl << indent() << "  x.write(oprot);" << endl << indent() << "  oprot.writeMessageEnd();"
-      << endl << indent() << "  oprot.getTransport().flush();" << endl << indent()
-      << "  return true;" << endl << indent() << "}" << endl << indent()
-      << "fn( msg.seqid, iprot, oprot);" << endl;
+      << indent() << "var fn  = PROCESS_MAP.get(msg.name);" << endl
+      << indent() << "if (fn == null) {" << endl
+      << indent() << "  TProtocolUtil.skip(iprot, TType.STRUCT);" << endl
+      << indent() << "  iprot.readMessageEnd();" << endl
+      << indent() << "  var appex = new TApplicationException(TApplicationException.UNKNOWN_METHOD, "
+                  << "\"Invalid method name: '\"+msg.name+\"'\");" << endl
+      << indent() << "  oprot.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid));" << endl
+      << indent() << "  appex.write(oprot);" << endl << indent() << "  oprot.writeMessageEnd();" << endl
+      << indent() << "  oprot.getTransport().flush();" << endl
+      << indent() << "  return true;" << endl << indent() << "}" << endl
+      << indent() << "fn( msg.seqid, iprot, oprot);" << endl
+      ;
 
   f_service_ << indent() << "return true;" << endl;
 
@@ -2029,84 +2069,36 @@
 
   // Declare result for non oneway function
   if (!tfunction->is_oneway()) {
-    f_service_ << indent() << "var result : " << resultname << " = new " << resultname << "();"
-               << endl;
+    f_service_ << indent() << "var result : " << resultname << " = new " << resultname << "();" << endl;
   }
 
   // Try block for any  function to catch (defined or undefined) exceptions
   f_service_ << indent() << "try {" << endl;
   indent_up();
 
-  if (callbacks_) {
-    // callback function style onError/onSuccess
 
-    // Generate the function call
-    t_struct* arg_struct = tfunction->get_arglist();
-    const std::vector<t_field*>& fields = arg_struct->get_members();
-    vector<t_field*>::const_iterator f_iter;
+  // normal function():result style
 
-    f_service_ << indent();
-    f_service_ << get_cap_name(service_name_) << "_iface_." << tfunction->get_name() << "(";
-    bool first = true;
-    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-      if (first) {
-        first = false;
-      } else {
-        f_service_ << ", ";
-      }
-      f_service_ << "args." << (*f_iter)->get_name();
-    }
+  // Generate the function call
+  t_struct* arg_struct = tfunction->get_arglist();
+  const std::vector<t_field*>& fields = arg_struct->get_members();
+  vector<t_field*>::const_iterator f_iter;
 
-    if (tfunction->is_oneway()) {
-      f_service_ << ");" << endl;
-    } else {
-      if (first) {
-        first = false;
-      } else {
-        f_service_ << ", ";
-      }
-      string on_success = generate_service_method_onsuccess(tfunction, false, true);
-      indent_up();
-      f_service_ << endl;
-      indent(f_service_) << "null,  // errors are thrown by the handler" << endl;
-      if (tfunction->get_returntype()->is_void()) {
-        indent(f_service_) << "null); // no retval" << endl;
-      } else {
-        indent(f_service_) << "function" << on_success.c_str() << " {" << endl;
-        if (!tfunction->get_returntype()->is_void()) {
-          indent_up();
-          indent(f_service_) << "result.success = retval;" << endl;
-          indent_down();
-        }
-        indent(f_service_) << "});" << endl;
-      }
-      indent_down();
-    }
-
-  } else {
-    // normal function():result style
-
-    // Generate the function call
-    t_struct* arg_struct = tfunction->get_arglist();
-    const std::vector<t_field*>& fields = arg_struct->get_members();
-    vector<t_field*>::const_iterator f_iter;
-
-    f_service_ << indent();
-    if (!(tfunction->is_oneway() || tfunction->get_returntype()->is_void())) {
-      f_service_ << "result.success = ";
-    }
-    f_service_ << get_cap_name(service_name_) << "_iface_." << tfunction->get_name() << "(";
-    bool first = true;
-    for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
-      if (first) {
-        first = false;
-      } else {
-        f_service_ << ", ";
-      }
-      f_service_ << "args." << (*f_iter)->get_name();
-    }
-    f_service_ << ");" << endl;
+  f_service_ << indent();
+  if (!(tfunction->is_oneway() || tfunction->get_returntype()->is_void())) {
+    f_service_ << "result.success = ";
   }
+  f_service_ << get_cap_name(service_name_) << "_iface_." << tfunction->get_name() << "(";
+  bool first = true;
+  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+    if (first) {
+      first = false;
+    } else {
+      f_service_ << ", ";
+    }
+    f_service_ << "args." << (*f_iter)->get_name();
+  }
+  f_service_ << ");" << endl;
 
   indent_down();
   f_service_ << indent() << "}";
@@ -2128,16 +2120,16 @@
   }
 
   // always catch all exceptions to prevent from service denial
+  string appex = tmp("appex");
   f_service_ << " catch (th : Dynamic) {" << endl;
   indent_up();
-  indent(f_service_) << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);"
-                     << endl;
+  indent(f_service_) << "trace(\"Internal error processing " << tfunction->get_name() << "\", th);" << endl;
   if (!tfunction->is_oneway()) {
-    indent(f_service_) << "var x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "
+    indent(f_service_) << "var appex = new TApplicationException(TApplicationException.INTERNAL_ERROR, "
                           "\"Internal error processing " << tfunction->get_name() << "\");" << endl;
     indent(f_service_) << "oprot.writeMessageBegin(new TMessage(\"" << tfunction->get_name()
                        << "\", TMessageType.EXCEPTION, seqid));" << endl;
-    indent(f_service_) << "x.write(oprot);" << endl;
+    indent(f_service_) << "appex.write(oprot);" << endl;
     indent(f_service_) << "oprot.writeMessageEnd();" << endl;
     indent(f_service_) << "oprot.getTransport().flush();" << endl;
   }
@@ -2607,7 +2599,7 @@
   // Check for namespacing
   t_program* program = ttype->get_program();
   if (program != nullptr && program != program_) {
-    string package = program->get_namespace("haxe");
+    string package = make_package_name( program->get_namespace("haxe"));
     if (!package.empty()) {
       return package + "." + ttype->get_name();
     }
@@ -2702,7 +2694,7 @@
  * @param tfunction Function definition
  * @return String of rendered function definition
  */
-string t_haxe_generator::function_signature_callback(t_function* tfunction) {
+string t_haxe_generator::function_signature_combined(t_function* tfunction) {
   std::string on_error_success = "onError : Dynamic->Void = null, "
                                  + generate_service_method_onsuccess(tfunction, true, false);
 
@@ -2714,7 +2706,14 @@
     arguments += on_error_success; //"onError : Function, onSuccess : Function";
   }
 
-  std::string result = "function " + tfunction->get_name() + "(" + arguments + ") : Void";
+  std::string resulttype;
+  if (tfunction->is_oneway() || tfunction->get_returntype()->is_void()) {
+    resulttype = "Void";
+  } else {
+    resulttype = type_name(tfunction->get_returntype());
+  }
+
+  std::string result = "function " + tfunction->get_name() + "(" + arguments + ") : "+resulttype;
   return result;
 }
 
@@ -2967,7 +2966,7 @@
   string package = "";
   t_program* program = type->get_program();
   if (program != nullptr /*&& program != program_*/) {
-    package = program->get_namespace("haxe") + ".";
+    package = make_package_name( program->get_namespace("haxe")) + ".";
   }
   return package + type->get_name();
 }
@@ -2975,7 +2974,6 @@
 THRIFT_REGISTER_GENERATOR(
     haxe,
     "Haxe",
-    "    callbacks        Use onError()/onSuccess() callbacks for service methods (like AS3)\n"
     "    rtti             Enable @:rtti for generated classes and interfaces\n"
     "    buildmacro=my.macros.Class.method(args)\n"
     "                     Add @:build macro calls to generated classes and interfaces\n")
diff --git a/compiler/cpp/src/thrift/generate/t_hs_generator.cc b/compiler/cpp/src/thrift/generate/t_hs_generator.cc
deleted file mode 100644
index d314b8f..0000000
--- a/compiler/cpp/src/thrift/generate/t_hs_generator.cc
+++ /dev/null
@@ -1,1717 +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.
- */
-
-#include <string>
-#include <fstream>
-#include <iostream>
-#include <vector>
-
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sstream>
-
-#include "thrift/platform.h"
-#include "thrift/version.h"
-
-#include "thrift/generate/t_oop_generator.h"
-
-using std::map;
-using std::ostream;
-using std::ostringstream;
-using std::string;
-using std::stringstream;
-using std::vector;
-
-static const string endl = "\n"; // avoid ostream << std::endl flushes
-
-/**
- * Haskell code generator.
- *
- */
-class t_hs_generator : public t_oop_generator {
-public:
-  t_hs_generator(t_program* program,
-                 const map<string, string>& parsed_options,
-                 const string& option_string)
-    : t_oop_generator(program) {
-    (void)option_string;
-    std::map<std::string, std::string>::const_iterator iter;
-
-    /* no options yet */
-    for( iter = parsed_options.begin(); iter != parsed_options.end(); ++iter) {
-      throw "unknown option hs:" + iter->first;
-    }
-
-    out_dir_base_ = "gen-hs";
-  }
-
-  /**
-   * Init and close methods
-   */
-
-  void init_generator() override;
-  void close_generator() override;
-
-  /**
-   * Program-level generation functions
-   */
-  void generate_typedef(t_typedef* ttypedef) override;
-  void generate_enum(t_enum* tenum) override;
-  void generate_const(t_const* tconst) override;
-  void generate_struct(t_struct* tstruct) override;
-  void generate_xception(t_struct* txception) override;
-  void generate_service(t_service* tservice) override;
-
-  string render_const_value(t_type* type, t_const_value* value);
-
-  /**
-   * Struct generation code
-   */
-
-  void generate_hs_struct(t_struct* tstruct, bool is_exception);
-
-  void generate_hs_struct_definition(ostream& out,
-                                     t_struct* tstruct,
-                                     bool is_xception = false,
-                                     bool helper = false);
-
-  void generate_hs_struct_reader(ostream& out, t_struct* tstruct);
-
-  void generate_hs_struct_writer(ostream& out, t_struct* tstruct);
-
-  void generate_hs_struct_arbitrary(ostream& out, t_struct* tstruct);
-
-  void generate_hs_function_helpers(t_function* tfunction);
-
-  void generate_hs_typemap(ostream& out, t_struct* tstruct);
-
-  void generate_hs_default(ostream& out, t_struct* tstruct);
-
-  /**
-   * Service-level generation functions
-   */
-
-  void generate_service_helpers(t_service* tservice);
-  void generate_service_interface(t_service* tservice);
-  void generate_service_client(t_service* tservice);
-  void generate_service_server(t_service* tservice);
-  void generate_process_function(t_service* tservice, t_function* tfunction);
-
-  /**
-   * Serialization constructs
-   */
-
-  void generate_deserialize_field(ostream& out, t_field* tfield, string prefix);
-
-  void generate_deserialize_struct(ostream& out, t_struct* tstruct, string name = "");
-
-  void generate_deserialize_container(ostream& out, t_type* ttype, string arg = "");
-
-  void generate_deserialize_set_element(ostream& out, t_set* tset);
-
-  void generate_deserialize_list_element(ostream& out, t_list* tlist, string prefix = "");
-
-  void generate_deserialize_type(ostream& out, t_type* type, string arg = "");
-
-  void generate_serialize_type(ostream& out, t_type* type, string name = "");
-
-  void generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix = "");
-
-  void generate_serialize_container(ostream& out, t_type* ttype, string prefix = "");
-
-  void generate_serialize_map_element(ostream& out, t_map* tmap, string kiter, string viter);
-
-  void generate_serialize_set_element(ostream& out, t_set* tmap, string iter);
-
-  void generate_serialize_list_element(ostream& out, t_list* tlist, string iter);
-
-  /**
-   * Helper rendering functions
-   */
-
-  string hs_autogen_comment();
-  string hs_language_pragma();
-  string hs_imports();
-
-  string type_name(t_type* ttype, string function_prefix = "");
-
-  string field_name(string tname, string fname);
-
-  string function_type(t_function* tfunc,
-                       bool options = false,
-                       bool io = false,
-                       bool method = false);
-
-  string type_to_enum(t_type* ttype);
-
-  string type_to_default(t_type* ttype);
-
-  string render_hs_type(t_type* type, bool needs_parens);
-
-  string type_to_constructor(t_type* ttype);
-
-  string render_hs_type_for_function_name(t_type* type);
-
-private:
-  ofstream_with_content_based_conditional_update f_types_;
-  ofstream_with_content_based_conditional_update f_consts_;
-  ofstream_with_content_based_conditional_update f_service_;
-  ofstream_with_content_based_conditional_update f_iface_;
-  ofstream_with_content_based_conditional_update f_client_;
-};
-
-/**
- * Prepares for file generation by opening up the necessary file output
- * streams.
- *
- * @param tprogram The program to generate
- */
-void t_hs_generator::init_generator() {
-  // Make output directory
-  MKDIR(get_out_dir().c_str());
-
-  // Make output file
-  string pname = capitalize(program_name_);
-  string f_types_name = get_out_dir() + pname + "_Types.hs";
-  f_types_.open(f_types_name.c_str());
-
-  string f_consts_name = get_out_dir() + pname + "_Consts.hs";
-  f_consts_.open(f_consts_name.c_str());
-
-  // Print header
-  f_types_ << hs_language_pragma() << endl;
-  f_types_ << hs_autogen_comment() << endl;
-  f_types_ << "module " << pname << "_Types where" << endl;
-  f_types_ << hs_imports() << endl;
-
-  f_consts_ << hs_language_pragma() << endl;
-  f_consts_ << hs_autogen_comment() << endl;
-  f_consts_ << "module " << pname << "_Consts where" << endl;
-  f_consts_ << hs_imports() << endl;
-  f_consts_ << "import " << pname << "_Types" << endl;
-}
-
-string t_hs_generator::hs_language_pragma() {
-  return string(
-      "{-# LANGUAGE DeriveDataTypeable #-}\n"
-      "{-# LANGUAGE DeriveGeneric #-}\n"
-      "{-# LANGUAGE OverloadedStrings #-}\n"
-      "{-# OPTIONS_GHC -fno-warn-missing-fields #-}\n"
-      "{-# OPTIONS_GHC -fno-warn-missing-signatures #-}\n"
-      "{-# OPTIONS_GHC -fno-warn-name-shadowing #-}\n"
-      "{-# OPTIONS_GHC -fno-warn-unused-imports #-}\n"
-      "{-# OPTIONS_GHC -fno-warn-unused-matches #-}\n");
-}
-
-/**
- * Autogen'd comment
- */
-string t_hs_generator::hs_autogen_comment() {
-  return string("-----------------------------------------------------------------\n")
-         + "-- Autogenerated by Thrift Compiler (" + THRIFT_VERSION + ")                      --\n"
-         + "--                                                             --\n"
-         + "-- DO NOT EDIT UNLESS YOU ARE SURE YOU KNOW WHAT YOU ARE DOING --\n"
-         + "-----------------------------------------------------------------\n";
-}
-
-/**
- * Prints standard thrift imports
- */
-string t_hs_generator::hs_imports() {
-  const vector<t_program*>& includes = program_->get_includes();
-  string result = string(
-      "import Prelude (($), (.), (>>=), (==), (++))\n"
-      "import qualified Prelude as P\n"
-      "import qualified Control.Exception as X\n"
-      "import qualified Control.Monad as M ( liftM, ap, when )\n"
-      "import Data.Functor ( (<$>) )\n"
-      "import qualified Data.ByteString.Lazy as LBS\n"
-      "import qualified Data.Hashable as H\n"
-      "import qualified Data.Int as I\n"
-      "import qualified Data.Maybe as M (catMaybes)\n"
-      "import qualified Data.Text.Lazy.Encoding as E ( decodeUtf8, encodeUtf8 )\n"
-      "import qualified Data.Text.Lazy as LT\n"
-      "import qualified GHC.Generics as G (Generic)\n"
-      "import qualified Data.Typeable as TY ( Typeable )\n"
-      "import qualified Data.HashMap.Strict as Map\n"
-      "import qualified Data.HashSet as Set\n"
-      "import qualified Data.Vector as Vector\n"
-      "import qualified Test.QuickCheck.Arbitrary as QC ( Arbitrary(..) )\n"
-      "import qualified Test.QuickCheck as QC ( elements )\n"
-      "\n"
-      "import qualified Thrift as T\n"
-      "import qualified Thrift.Types as T\n"
-      "import qualified Thrift.Arbitraries as T\n"
-      "\n");
-
-  for (auto include : includes)
-    result += "import qualified " + capitalize(include->get_name()) + "_Types\n";
-
-  if (includes.size() > 0)
-    result += "\n";
-
-  return result;
-}
-
-/**
- * Closes the type files
- */
-void t_hs_generator::close_generator() {
-  // Close types file
-  f_types_.close();
-  f_consts_.close();
-}
-
-/**
- * Generates a typedef. Ez.
- *
- * @param ttypedef The type definition
- */
-void t_hs_generator::generate_typedef(t_typedef* ttypedef) {
-  string tname = capitalize(ttypedef->get_symbolic());
-  string tdef = render_hs_type(ttypedef->get_type(), false);
-  indent(f_types_) << "type " << tname << " = " << tdef << endl;
-  f_types_ << endl;
-}
-
-/**
- * Generates code for an enumerated type.
- * the values.
- *
- * @param tenum The enumeration
- */
-void t_hs_generator::generate_enum(t_enum* tenum) {
-  indent(f_types_) << "data " << capitalize(tenum->get_name()) << " = ";
-  indent_up();
-  vector<t_enum_value*> constants = tenum->get_constants();
-  vector<t_enum_value*>::iterator c_iter;
-
-  bool first = true;
-  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-    string name = capitalize(tenum->get_name()) + "_" + capitalize((*c_iter)->get_name());
-    f_types_ << (first ? "" : "|");
-    f_types_ << name;
-    first = false;
-  }
-  indent(f_types_) << "deriving (P.Show, P.Eq, G.Generic, TY.Typeable, P.Ord, P.Bounded)" << endl;
-  indent_down();
-
-  string ename = capitalize(tenum->get_name());
-
-  indent(f_types_) << "instance P.Enum " << ename << " where" << endl;
-  indent_up();
-  indent(f_types_) << "fromEnum t = case t of" << endl;
-  indent_up();
-  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-    int value = (*c_iter)->get_value();
-    string name = capitalize(tenum->get_name()) + "_" + capitalize((*c_iter)->get_name());
-    indent(f_types_) << name << " -> " << value << endl;
-  }
-  indent_down();
-  indent(f_types_) << "toEnum t = case t of" << endl;
-  indent_up();
-  for (c_iter = constants.begin(); c_iter != constants.end(); ++c_iter) {
-    int value = (*c_iter)->get_value();
-    string name = capitalize(tenum->get_name()) + "_" + capitalize((*c_iter)->get_name());
-    indent(f_types_) << value << " -> " << name << endl;
-  }
-  indent(f_types_) << "_ -> X.throw T.ThriftException" << endl;
-  indent_down();
-  indent_down();
-
-  indent(f_types_) << "instance H.Hashable " << ename << " where" << endl;
-  indent_up();
-  indent(f_types_) << "hashWithSalt salt = H.hashWithSalt salt P.. P.fromEnum" << endl;
-  indent_down();
-
-  indent(f_types_) << "instance QC.Arbitrary " << ename << " where" << endl;
-  indent_up();
-  indent(f_types_) << "arbitrary = QC.elements (P.enumFromTo P.minBound P.maxBound)" << endl;
-  indent_down();
-}
-
-/**
- * Generate a constant value
- */
-void t_hs_generator::generate_const(t_const* tconst) {
-  t_type* type = tconst->get_type();
-  string name = decapitalize(tconst->get_name());
-
-  t_const_value* value = tconst->get_value();
-
-  indent(f_consts_) << name << " :: " << render_hs_type(type, false) << endl;
-  indent(f_consts_) << name << " = " << render_const_value(type, value) << endl;
-  f_consts_ << endl;
-}
-
-/**
- * Prints the value of a constant with the given type. Note that type checking
- * is NOT performed in this function as it is always run beforehand using the
- * validate_types method in main.cc
- */
-string t_hs_generator::render_const_value(t_type* type, t_const_value* value) {
-  if (value == nullptr)
-    return type_to_default(type);
-
-  type = get_true_type(type);
-  ostringstream out;
-
-  if (type->is_base_type()) {
-    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-    switch (tbase) {
-
-    case t_base_type::TYPE_STRING:
-      out << '"' << get_escaped_string(value) << '"';
-      break;
-
-    case t_base_type::TYPE_BOOL:
-      out << (value->get_integer() > 0 ? "P.True" : "P.False");
-      break;
-
-    case t_base_type::TYPE_I8:
-    case t_base_type::TYPE_I16:
-    case t_base_type::TYPE_I32:
-    case t_base_type::TYPE_I64:
-      out << "(" << value->get_integer() << ")";
-      break;
-
-    case t_base_type::TYPE_DOUBLE:
-      if (value->get_type() == t_const_value::CV_INTEGER) {
-        out << "(" << value->get_integer() << ")";
-      } else {
-        out << "(" << value->get_double() << ")";
-      }
-      break;
-
-    default:
-      throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase);
-    }
-
-  } else if (type->is_enum()) {
-    t_enum* tenum = (t_enum*)type;
-    vector<t_enum_value*> constants = tenum->get_constants();
-    for (auto & constant : constants) {
-      int val = constant->get_value();
-      if (val == value->get_integer()) {
-        t_program* prog = type->get_program();
-        if (prog != nullptr && prog != program_)
-          out << capitalize(prog->get_name()) << "_Types.";
-        out << capitalize(constant->get_name());
-        break;
-      }
-    }
-
-  } else if (type->is_struct() || type->is_xception()) {
-    string cname = type_name(type);
-    out << "default_" << cname << "{";
-
-    const vector<t_field*>& fields = ((t_struct*)type)->get_members();
-    const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
-
-    bool first = true;
-    for (auto v_iter : val) {
-      t_field* field = nullptr;
-
-      for (auto f_iter : fields)
-        if (f_iter->get_name() == v_iter.first->get_string())
-          field = f_iter;
-
-      if (field == nullptr)
-        throw "type error: " + cname + " has no field " + v_iter.first->get_string();
-
-      string fname = v_iter.first->get_string();
-      string const_value = render_const_value(field->get_type(), v_iter.second);
-
-      out << (first ? "" : ", ");
-      out << field_name(cname, fname) << " = ";
-      if (field->get_req() == t_field::T_OPTIONAL || ((t_type*)field->get_type())->is_xception()) {
-        out << "P.Just ";
-      }
-      out << const_value;
-      first = false;
-    }
-
-    out << "}";
-
-  } else if (type->is_map()) {
-    t_type* ktype = ((t_map*)type)->get_key_type();
-    t_type* vtype = ((t_map*)type)->get_val_type();
-
-    const map<t_const_value*, t_const_value*, t_const_value::value_compare>& val = value->get_map();
-    map<t_const_value*, t_const_value*, t_const_value::value_compare>::const_iterator v_iter;
-
-    out << "(Map.fromList [";
-
-    bool first = true;
-    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
-      string key = render_const_value(ktype, v_iter->first);
-      string val = render_const_value(vtype, v_iter->second);
-      out << (first ? "" : ",");
-      out << "(" << key << "," << val << ")";
-      first = false;
-    }
-    out << "])";
-
-  } else if (type->is_list() || type->is_set()) {
-    t_type* etype = type->is_list() ? ((t_list*)type)->get_elem_type()
-                                    : ((t_set*)type)->get_elem_type();
-
-    const vector<t_const_value*>& val = value->get_list();
-    vector<t_const_value*>::const_iterator v_iter;
-
-    if (type->is_set())
-      out << "(Set.fromList [";
-    else
-      out << "(Vector.fromList [";
-
-    bool first = true;
-    for (v_iter = val.begin(); v_iter != val.end(); ++v_iter) {
-      out << (first ? "" : ",");
-      out << render_const_value(etype, *v_iter);
-      first = false;
-    }
-
-    out << "])";
-
-  } else {
-    throw "CANNOT GENERATE CONSTANT FOR TYPE: " + type->get_name();
-  }
-
-  return out.str();
-}
-
-/**
- * Generates a "struct"
- */
-void t_hs_generator::generate_struct(t_struct* tstruct) {
-  generate_hs_struct(tstruct, false);
-}
-
-/**
- * Generates a struct definition for a thrift exception. Basically the same
- * as a struct, but also has an exception declaration.
- *
- * @param txception The struct definition
- */
-void t_hs_generator::generate_xception(t_struct* txception) {
-  generate_hs_struct(txception, true);
-}
-
-/**
- * Generates a Haskell struct
- */
-void t_hs_generator::generate_hs_struct(t_struct* tstruct, bool is_exception) {
-  generate_hs_struct_definition(f_types_, tstruct, is_exception, false);
-}
-
-/**
- * Generates a struct definition for a thrift data type.
- *
- * @param tstruct The struct definition
- */
-void t_hs_generator::generate_hs_struct_definition(ostream& out,
-                                                   t_struct* tstruct,
-                                                   bool is_exception,
-                                                   bool helper) {
-  (void)helper;
-  string tname = type_name(tstruct);
-  string name = tstruct->get_name();
-  const vector<t_field*>& members = tstruct->get_members();
-
-  indent(out) << "data " << tname << " = " << tname;
-  if (members.size() > 0) {
-    indent_up();
-    bool first = true;
-    for (auto member : members) {
-      if (first) {
-        indent(out) << "{ ";
-        first = false;
-      } else {
-        indent(out) << ", ";
-      }
-      string mname = member->get_name();
-      out << field_name(tname, mname) << " :: ";
-      if (member->get_req() == t_field::T_OPTIONAL
-          || ((t_type*)member->get_type())->is_xception()) {
-        out << "P.Maybe ";
-      }
-      out << render_hs_type(member->get_type(), true) << endl;
-    }
-    indent(out) << "}";
-    indent_down();
-  }
-
-  out << " deriving (P.Show,P.Eq,G.Generic,TY.Typeable)" << endl;
-
-  if (is_exception)
-    out << "instance X.Exception " << tname << endl;
-
-  indent(out) << "instance H.Hashable " << tname << " where" << endl;
-  indent_up();
-  indent(out) << "hashWithSalt salt record = salt";
-  for (auto member : members) {
-    string mname = member->get_name();
-    indent(out) << " `H.hashWithSalt` " << field_name(tname, mname) << " record";
-  }
-  indent(out) << endl;
-  indent_down();
-
-  generate_hs_struct_arbitrary(out, tstruct);
-  generate_hs_struct_writer(out, tstruct);
-  generate_hs_struct_reader(out, tstruct);
-  generate_hs_typemap(out, tstruct);
-  generate_hs_default(out, tstruct);
-}
-
-void t_hs_generator::generate_hs_struct_arbitrary(ostream& out, t_struct* tstruct) {
-  string tname = type_name(tstruct);
-  string name = tstruct->get_name();
-  const vector<t_field*>& members = tstruct->get_members();
-
-  indent(out) << "instance QC.Arbitrary " << tname << " where " << endl;
-  indent_up();
-  if (members.size() > 0) {
-    indent(out) << "arbitrary = M.liftM " << tname;
-    indent_up();
-    indent_up();
-    indent_up();
-    indent_up();
-    bool first = true;
-    for (auto member : members) {
-      if (first) {
-        first = false;
-        out << " ";
-      } else {
-        indent(out) << "`M.ap`";
-      }
-      out << "(";
-      if (member->get_req() == t_field::T_OPTIONAL
-          || ((t_type*)member->get_type())->is_xception()) {
-        out << "M.liftM P.Just ";
-      }
-      out << "QC.arbitrary)" << endl;
-    }
-    indent_down();
-    indent_down();
-    indent_down();
-    indent_down();
-
-    // Shrink
-    indent(out) << "shrink obj | obj == default_" << tname << " = []" << endl;
-    indent(out) << "           | P.otherwise = M.catMaybes" << endl;
-    indent_up();
-    first = true;
-    for (auto member : members) {
-      if (first) {
-        first = false;
-        indent(out) << "[ ";
-      } else {
-        indent(out) << ", ";
-      }
-      string fname = field_name(tname, member->get_name());
-      out << "if obj == default_" << tname;
-      out << "{" << fname << " = " << fname << " obj} ";
-      out << "then P.Nothing ";
-      out << "else P.Just $ default_" << tname;
-      out << "{" << fname << " = " << fname << " obj}" << endl;
-    }
-    indent(out) << "]" << endl;
-    indent_down();
-  } else { /* 0 == members.size() */
-    indent(out) << "arbitrary = QC.elements [" << tname << "]" << endl;
-  }
-  indent_down();
-}
-
-/**
- * Generates the read method for a struct
- */
-void t_hs_generator::generate_hs_struct_reader(ostream& out, t_struct* tstruct) {
-  const vector<t_field*>& fields = tstruct->get_members();
-
-  string sname = type_name(tstruct);
-  string id = tmp("_id");
-  string val = tmp("_val");
-
-  indent(out) << "to_" << sname << " :: T.ThriftVal -> " << sname << endl;
-  indent(out) << "to_" << sname << " (T.TStruct fields) = " << sname << "{" << endl;
-  indent_up();
-
-  bool first = true;
-
-  // Generate deserialization code for known cases
-  for (auto field : fields) {
-    int32_t key = field->get_key();
-    string etype = type_to_enum(field->get_type());
-    string fname = field->get_name();
-
-    if (first) {
-      first = false;
-    } else {
-      out << "," << endl;
-    }
-
-    // Fill in Field
-    indent(out) << field_name(sname, fname) << " = ";
-
-    out << "P.maybe (";
-    if (field->get_req() == t_field::T_REQUIRED) {
-      out << "P.error \"Missing required field: " << fname << "\"";
-    } else {
-      if ((field->get_req() == t_field::T_OPTIONAL
-           || ((t_type*)field->get_type())->is_xception()) && field->get_value() == nullptr) {
-        out << "P.Nothing";
-      } else {
-        out << field_name(sname, fname) << " default_" << sname;
-      }
-    }
-    out << ") ";
-
-    out << "(\\(_," << val << ") -> ";
-    if (field->get_req() == t_field::T_OPTIONAL
-        || ((t_type*)field->get_type())->is_xception())
-      out << "P.Just ";
-    generate_deserialize_field(out, field, val);
-    out << ")";
-    out << " (Map.lookup (" << key << ") fields)";
-  }
-
-  out << endl;
-  indent(out) << "}" << endl;
-  indent_down();
-
-  // read
-  string tmap = type_name(tstruct, "typemap_");
-  indent(out) << "to_" << sname << " _ = P.error \"not a struct\"" << endl;
-
-  indent(out) << "read_" << sname << " :: T.Protocol p => p -> P.IO " << sname
-              << endl;
-  indent(out) << "read_" << sname << " iprot = to_" << sname;
-  out << " <$> T.readVal iprot (T.T_STRUCT " << tmap << ")" << endl;
-
-  indent(out) << "decode_" << sname
-              << " :: T.StatelessProtocol p => p -> LBS.ByteString -> " << sname << endl;
-  indent(out) << "decode_" << sname << " iprot bs = to_" << sname << " $ ";
-  out << "T.deserializeVal iprot (T.T_STRUCT " << tmap << ") bs" << endl;
-}
-
-void t_hs_generator::generate_hs_struct_writer(ostream& out, t_struct* tstruct) {
-  string name = type_name(tstruct);
-  const vector<t_field*>& fields = tstruct->get_sorted_members();
-  string str = tmp("_str");
-  string f = tmp("_f");
-  string v = tmp("_v");
-
-  indent(out) << "from_" << name << " :: " << name << " -> T.ThriftVal" << endl;
-  indent(out) << "from_" << name << " record = T.TStruct $ Map.fromList ";
-  indent_up();
-
-  // Get Exceptions
-  bool hasExn = false;
-  for (auto field : fields) {
-    if (((t_type*)field->get_type())->is_xception()) {
-      hasExn = true;
-      break;
-    }
-  }
-
-  bool isfirst = true;
-  if (hasExn) {
-    out << endl;
-    indent(out) << "(let exns = M.catMaybes ";
-    indent_up();
-    for (auto field : fields) {
-      if (((t_type*)field->get_type())->is_xception()) {
-        if (isfirst) {
-          out << "[ ";
-          isfirst = false;
-        } else {
-          out << ", ";
-        }
-        string mname = field->get_name();
-        int32_t key = field->get_key();
-        out << "(\\" << v << " -> (" << key << ", (\"" << mname << "\",";
-        generate_serialize_type(out, field->get_type(), v);
-        out << "))) <$> " << field_name(name, mname) << " record";
-      }
-    }
-    if (!isfirst) {
-      out << "]" << endl;
-    }
-    indent_down();
-    indent(out) << "in if P.not (P.null exns) then exns else ";
-    indent_up();
-  } else {
-    out << "$ ";
-  }
-
-  out << "M.catMaybes" << endl;
-  // Get the Rest
-  isfirst = true;
-  for (auto field : fields) {
-    // Write field header
-    if (isfirst) {
-      indent(out) << "[ ";
-      isfirst = false;
-    } else {
-      indent(out) << ", ";
-    }
-    string mname = field->get_name();
-    int32_t key = field->get_key();
-    out << "(\\";
-    out << v << " -> ";
-    if (field->get_req() != t_field::T_OPTIONAL
-        && !((t_type*)field->get_type())->is_xception()) {
-      out << "P.Just ";
-    }
-    out << "(" << key << ", (\"" << mname << "\",";
-    generate_serialize_type(out, field->get_type(), v);
-    out << "))) ";
-    if (field->get_req() != t_field::T_OPTIONAL
-        && !((t_type*)field->get_type())->is_xception()) {
-      out << "$";
-    } else {
-      out << "<$>";
-    }
-    out << " " << field_name(name, mname) << " record" << endl;
-  }
-
-  // Write the struct map
-  if (isfirst) {
-    indent(out) << "[]" << endl;
-  } else {
-    indent(out) << "]" << endl;
-  }
-  if (hasExn) {
-    indent(out) << ")" << endl;
-    indent_down();
-  }
-  indent_down();
-
-  // write
-  indent(out) << "write_" << name << " :: T.Protocol p => p -> " << name
-              << " -> P.IO ()" << endl;
-  indent(out) << "write_" << name << " oprot record = T.writeVal oprot $ from_";
-  out << name << " record" << endl;
-
-  // encode
-  indent(out) << "encode_" << name << " :: T.StatelessProtocol p => p -> " << name
-              << " -> LBS.ByteString" << endl;
-  indent(out) << "encode_" << name << " oprot record = T.serializeVal oprot $ ";
-  out << "from_" << name << " record" << endl;
-}
-
-/**
- * Generates a thrift service.
- *
- * @param tservice The service definition
- */
-void t_hs_generator::generate_service(t_service* tservice) {
-  string f_service_name = get_out_dir() + capitalize(service_name_) + ".hs";
-  f_service_.open(f_service_name.c_str());
-
-  f_service_ << hs_language_pragma() << endl;
-  f_service_ << hs_autogen_comment() << endl;
-  f_service_ << "module " << capitalize(service_name_) << " where" << endl;
-  f_service_ << hs_imports() << endl;
-
-  if (tservice->get_extends()) {
-    f_service_ << "import qualified " << capitalize(tservice->get_extends()->get_name()) << endl;
-  }
-
-  f_service_ << "import " << capitalize(program_name_) << "_Types" << endl;
-  f_service_ << "import qualified " << capitalize(service_name_) << "_Iface as Iface" << endl;
-
-  // Generate the three main parts of the service
-  generate_service_helpers(tservice);
-  generate_service_interface(tservice);
-  generate_service_client(tservice);
-  generate_service_server(tservice);
-
-  // Close service file
-  f_service_.close();
-}
-
-/**
- * Generates helper functions for a service.
- *
- * @param tservice The service to generate a header definition for
- */
-void t_hs_generator::generate_service_helpers(t_service* tservice) {
-  vector<t_function*> functions = tservice->get_functions();
-  vector<t_function*>::iterator f_iter;
-
-  indent(f_service_) << "-- HELPER FUNCTIONS AND STRUCTURES --" << endl;
-  indent(f_service_) << endl;
-
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    t_struct* ts = (*f_iter)->get_arglist();
-    generate_hs_struct_definition(f_service_, ts, false);
-    generate_hs_function_helpers(*f_iter);
-  }
-}
-
-/**
- * Generates a struct and helpers for a function.
- *
- * @param tfunction The function
- */
-void t_hs_generator::generate_hs_function_helpers(t_function* tfunction) {
-  t_struct result(program_, field_name(tfunction->get_name(), "result"));
-  t_field success(tfunction->get_returntype(), "success", 0);
-
-  if (!tfunction->get_returntype()->is_void())
-    result.append(&success);
-
-  t_struct* xs = tfunction->get_xceptions();
-  const vector<t_field*>& fields = xs->get_members();
-
-  vector<t_field*>::const_iterator f_iter;
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
-    result.append(*f_iter);
-
-  generate_hs_struct_definition(f_service_, &result, false);
-}
-
-/**
- * Generate the map from field names to (type, id)
- * @param tstruct the Struct
- */
-void t_hs_generator::generate_hs_typemap(ostream& out, t_struct* tstruct) {
-  string name = type_name(tstruct);
-  const vector<t_field*>& fields = tstruct->get_sorted_members();
-
-  indent(out) << "typemap_" << name << " :: T.TypeMap" << endl;
-  indent(out) << "typemap_" << name << " = Map.fromList [";
-  bool first = true;
-  for (auto field : fields) {
-    string mname = field->get_name();
-    if (!first) {
-      out << ",";
-    }
-
-    t_type* type = get_true_type(field->get_type());
-    int32_t key = field->get_key();
-    out << "(" << key << ",(\"" << mname << "\"," << type_to_enum(type) << "))";
-    first = false;
-  }
-  out << "]" << endl;
-}
-
-/**
- * generate the struct with default values filled in
- * @param tstruct the Struct
- */
-void t_hs_generator::generate_hs_default(ostream& out, t_struct* tstruct) {
-  string name = type_name(tstruct);
-  string fname = type_name(tstruct, "default_");
-  const vector<t_field*>& fields = tstruct->get_sorted_members();
-
-  indent(out) << fname << " :: " << name << endl;
-  indent(out) << fname << " = " << name << "{" << endl;
-  indent_up();
-  bool first = true;
-  for (auto field : fields) {
-    string mname = field->get_name();
-    if (first) {
-      first = false;
-    } else {
-      out << "," << endl;
-    }
-
-    t_type* type = get_true_type(field->get_type());
-    t_const_value* value = field->get_value();
-    indent(out) << field_name(name, mname) << " = ";
-    if (field->get_req() == t_field::T_OPTIONAL
-        || ((t_type*)field->get_type())->is_xception()) {
-      if (value == nullptr) {
-        out << "P.Nothing";
-      } else {
-        out << "P.Just " << render_const_value(type, value);
-      }
-    } else {
-      out << render_const_value(type, value);
-    }
-  }
-  out << "}" << endl;
-  indent_down();
-}
-
-/**
- * Generates a service interface definition.
- *
- * @param tservice The service to generate a header definition for
- */
-void t_hs_generator::generate_service_interface(t_service* tservice) {
-  string f_iface_name = get_out_dir() + capitalize(service_name_) + "_Iface.hs";
-  f_iface_.open(f_iface_name.c_str());
-
-  f_iface_ << hs_language_pragma() << endl;
-  f_iface_ << hs_autogen_comment() << endl;
-
-  f_iface_ << "module " << capitalize(service_name_) << "_Iface where" << endl;
-
-  f_iface_ << hs_imports() << endl;
-  f_iface_ << "import " << capitalize(program_name_) << "_Types" << endl;
-  f_iface_ << endl;
-
-  string sname = capitalize(service_name_);
-  if (tservice->get_extends() != nullptr) {
-    string extends = type_name(tservice->get_extends());
-
-    indent(f_iface_) << "import " << extends << "_Iface" << endl;
-    indent(f_iface_) << "class " << extends << "_Iface a => " << sname << "_Iface a where" << endl;
-
-  } else {
-    indent(f_iface_) << "class " << sname << "_Iface a where" << endl;
-  }
-
-  indent_up();
-
-  vector<t_function*> functions = tservice->get_functions();
-  vector<t_function*>::iterator f_iter;
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    string ft = function_type(*f_iter, true, true, true);
-    indent(f_iface_) << decapitalize((*f_iter)->get_name()) << " :: a -> " << ft << endl;
-  }
-
-  indent_down();
-  f_iface_.close();
-}
-
-/**
- * Generates a service client definition. Note that in Haskell, the client doesn't implement iface.
- *This is because
- * The client does not (and should not have to) deal with arguments being Nothing.
- *
- * @param tservice The service to generate a server for.
- */
-void t_hs_generator::generate_service_client(t_service* tservice) {
-  string f_client_name = get_out_dir() + capitalize(service_name_) + "_Client.hs";
-  f_client_.open(f_client_name.c_str());
-  f_client_ << hs_language_pragma() << endl;
-  f_client_ << hs_autogen_comment() << endl;
-
-  vector<t_function*> functions = tservice->get_functions();
-  vector<t_function*>::const_iterator f_iter;
-
-  string extends = "";
-  string exports = "";
-
-  bool first = true;
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    exports += (first ? "" : ",");
-    string funname = (*f_iter)->get_name();
-    exports += decapitalize(funname);
-    first = false;
-  }
-
-  string sname = capitalize(service_name_);
-  indent(f_client_) << "module " << sname << "_Client(" << exports << ") where" << endl;
-
-  if (tservice->get_extends() != nullptr) {
-    extends = type_name(tservice->get_extends());
-    indent(f_client_) << "import " << extends << "_Client" << endl;
-  }
-
-  indent(f_client_) << "import qualified Data.IORef as R" << endl;
-  indent(f_client_) << hs_imports() << endl;
-  indent(f_client_) << "import " << capitalize(program_name_) << "_Types" << endl;
-  indent(f_client_) << "import " << capitalize(service_name_) << endl;
-
-  // DATS RITE A GLOBAL VAR
-  indent(f_client_) << "seqid = R.newIORef 0" << endl;
-
-  // Generate client method implementations
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    t_struct* arg_struct = (*f_iter)->get_arglist();
-    const vector<t_field*>& fields = arg_struct->get_members();
-    vector<t_field*>::const_iterator fld_iter;
-    string funname = (*f_iter)->get_name();
-
-    string fargs = "";
-    for (fld_iter = fields.begin(); fld_iter != fields.end(); ++fld_iter)
-      fargs += " arg_" + (*fld_iter)->get_name();
-
-    // Open function
-    indent(f_client_) << decapitalize(funname) << " (ip,op)" << fargs << " = do" << endl;
-    indent_up();
-    indent(f_client_) << "send_" << funname << " op" << fargs;
-
-    f_client_ << endl;
-
-    if (!(*f_iter)->is_oneway())
-      indent(f_client_) << "recv_" << funname << " ip" << endl;
-
-    indent_down();
-
-    indent(f_client_) << "send_" << funname << " op" << fargs << " = do" << endl;
-    indent_up();
-
-    indent(f_client_) << "seq <- seqid" << endl;
-    indent(f_client_) << "seqn <- R.readIORef seq" << endl;
-    string argsname = capitalize((*f_iter)->get_name() + "_args");
-
-    // Serialize the request header
-    string fname = (*f_iter)->get_name();
-    string msgType = (*f_iter)->is_oneway() ? "T.M_ONEWAY" : "T.M_CALL";
-    indent(f_client_) << "T.writeMessage op (\"" << fname << "\", " << msgType << ", seqn) $"
-                      << endl;
-    indent_up();
-    indent(f_client_) << "write_" << argsname << " op (" << argsname << "{";
-
-    bool first = true;
-    for (auto field : fields) {
-      string fieldname = field->get_name();
-      f_client_ << (first ? "" : ",");
-      f_client_ << field_name(argsname, fieldname) << "=";
-      if (field->get_req() == t_field::T_OPTIONAL
-          || ((t_type*)field->get_type())->is_xception())
-        f_client_ << "P.Just ";
-      f_client_ << "arg_" << fieldname;
-      first = false;
-    }
-    f_client_ << "})" << endl;
-    indent_down();
-    indent_down();
-
-    if (!(*f_iter)->is_oneway()) {
-      string resultname = capitalize((*f_iter)->get_name() + "_result");
-      t_struct noargs(program_);
-
-      string funname = string("recv_") + (*f_iter)->get_name();
-      t_function recv_function((*f_iter)->get_returntype(), funname, &noargs);
-
-      // Open function
-      indent(f_client_) << funname << " ip = do" << endl;
-      indent_up();
-
-      indent(f_client_) << "T.readMessage ip $ \\(fname, mtype, rseqid) -> do" << endl;
-      indent_up();
-      indent(f_client_) << "M.when (mtype == T.M_EXCEPTION) $ do { exn <- T.readAppExn ip ; "
-                           "X.throw exn }" << endl;
-
-      indent(f_client_) << "res <- read_" << resultname << " ip" << endl;
-
-      t_struct* xs = (*f_iter)->get_xceptions();
-      const vector<t_field*>& xceptions = xs->get_members();
-
-      for (auto xception : xceptions) {
-        indent(f_client_) << "P.maybe (P.return ()) X.throw ("
-                          << field_name(resultname, xception->get_name()) << " res)" << endl;
-      }
-
-      if (!(*f_iter)->get_returntype()->is_void())
-        indent(f_client_) << "P.return $ " << field_name(resultname, "success") << " res" << endl;
-      else
-        indent(f_client_) << "P.return ()" << endl;
-
-      // Close function
-      indent_down();
-      indent_down();
-    }
-  }
-
-  f_client_.close();
-}
-
-/**
- * Generates a service server definition.
- *
- * @param tservice The service to generate a server for.
- */
-void t_hs_generator::generate_service_server(t_service* tservice) {
-  // Generate the dispatch methods
-  vector<t_function*> functions = tservice->get_functions();
-  vector<t_function*>::iterator f_iter;
-
-  // Generate the process subfunctions
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
-    generate_process_function(tservice, *f_iter);
-
-  indent(f_service_) << "proc_ handler (iprot,oprot) (name,typ,seqid) = case name of" << endl;
-  indent_up();
-
-  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
-    string fname = (*f_iter)->get_name();
-    indent(f_service_) << "\"" << fname << "\" -> process_" << decapitalize(fname)
-                       << " (seqid,iprot,oprot,handler)" << endl;
-  }
-
-  indent(f_service_) << "_ -> ";
-  if (tservice->get_extends() != nullptr) {
-    f_service_ << type_name(tservice->get_extends())
-               << ".proc_ handler (iprot,oprot) (name,typ,seqid)" << endl;
-
-  } else {
-    f_service_ << "do" << endl;
-    indent_up();
-    indent(f_service_) << "_ <- T.readVal iprot (T.T_STRUCT Map.empty)" << endl;
-    indent(f_service_) << "T.writeMessage oprot (name,T.M_EXCEPTION,seqid) $" << endl;
-    indent_up();
-    indent(f_service_) << "T.writeAppExn oprot (T.AppExn T.AE_UNKNOWN_METHOD (\"Unknown function "
-                          "\" ++ LT.unpack name))" << endl;
-    indent_down();
-    indent_down();
-  }
-
-  indent_down();
-
-  // Generate the server implementation
-  indent(f_service_) << "process handler (iprot, oprot) = do" << endl;
-  indent_up();
-
-  indent(f_service_) << "T.readMessage iprot (" << endl;
-  indent(f_service_) << "  proc_ handler (iprot,oprot))" << endl;
-  indent(f_service_) << "P.return P.True" << endl;
-  indent_down();
-}
-
-bool hasNoArguments(t_function* func) {
-  return (func->get_arglist()->get_members().empty());
-}
-
-string t_hs_generator::render_hs_type_for_function_name(t_type* type) {
-  string type_str = render_hs_type(type, false);
-  std::string::size_type found = -1;
-
-  while (true) {
-    found = type_str.find_first_of("[]. ", found + 1);
-    if (string::npos == size_t(found)) {
-      break;
-    }
-
-    if (type_str[found] == '.')
-      type_str[found] = '_';
-    else
-      type_str[found] = 'Z';
-  }
-  return type_str;
-}
-
-/**
- * Generates a process function definition.
- *
- * @param tfunction The function to write a dispatcher for
- */
-void t_hs_generator::generate_process_function(t_service* tservice, t_function* tfunction) {
-  (void)tservice;
-  // Open function
-  string funname = decapitalize(tfunction->get_name());
-  indent(f_service_) << "process_" << funname << " (seqid, iprot, oprot, handler) = do" << endl;
-  indent_up();
-
-  string argsname = capitalize(tfunction->get_name()) + "_args";
-  string resultname = capitalize(tfunction->get_name()) + "_result";
-
-  // Generate the function call
-  t_struct* arg_struct = tfunction->get_arglist();
-  const vector<t_field*>& fields = arg_struct->get_members();
-  vector<t_field*>::const_iterator f_iter;
-
-  indent(f_service_) << "args <- read_" << argsname << " iprot" << endl;
-
-  t_struct* xs = tfunction->get_xceptions();
-  const vector<t_field*>& xceptions = xs->get_members();
-  vector<t_field*>::const_iterator x_iter;
-
-  size_t n = xceptions.size() + 1;
-  // Try block for a function with exceptions
-  if (n > 0) {
-    for (size_t i = 0; i < n; i++) {
-      indent(f_service_) << "(X.catch" << endl;
-      indent_up();
-    }
-  }
-
-  if (n > 0) {
-    indent(f_service_) << "(do" << endl;
-    indent_up();
-  }
-  indent(f_service_);
-
-  if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void())
-    f_service_ << "val <- ";
-
-  f_service_ << "Iface." << decapitalize(tfunction->get_name()) << " handler";
-  for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
-    f_service_ << " (" << field_name(argsname, (*f_iter)->get_name()) << " args)";
-
-  if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void()) {
-    f_service_ << endl;
-    indent(f_service_) << "let res = default_" << resultname << "{"
-                       << field_name(resultname, "success") << " = val}";
-
-  } else if (!tfunction->is_oneway()) {
-    f_service_ << endl;
-    indent(f_service_) << "let res = default_" << resultname;
-  }
-  f_service_ << endl;
-
-  // Shortcut out here for oneway functions
-  if (tfunction->is_oneway()) {
-    indent(f_service_) << "P.return ()";
-  } else {
-    indent(f_service_) << "T.writeMessage oprot (\"" << tfunction->get_name()
-                       << "\", T.M_REPLY, seqid) $" << endl;
-    indent_up();
-    indent(f_service_) << "write_" << resultname << " oprot res";
-    indent_down();
-  }
-  if (n > 0) {
-    f_service_ << ")";
-    indent_down();
-  }
-  f_service_ << endl;
-
-  if (n > 0) {
-    for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter) {
-      indent(f_service_) << "(\\e  -> do" << endl;
-      indent_up();
-
-      if (!tfunction->is_oneway()) {
-        indent(f_service_) << "let res = default_" << resultname << "{"
-                           << field_name(resultname, (*x_iter)->get_name()) << " = P.Just e}"
-                           << endl;
-        indent(f_service_) << "T.writeMessage oprot (\"" << tfunction->get_name()
-                           << "\", T.M_REPLY, seqid) $" << endl;
-        indent_up();
-        indent(f_service_) << "write_" << resultname << " oprot res";
-        indent_down();
-      } else {
-        indent(f_service_) << "P.return ()";
-      }
-
-      f_service_ << "))" << endl;
-      indent_down();
-      indent_down();
-    }
-    indent(f_service_) << "((\\_ -> do" << endl;
-    indent_up();
-
-    if (!tfunction->is_oneway()) {
-      indent(f_service_) << "T.writeMessage oprot (\"" << tfunction->get_name()
-                         << "\", T.M_EXCEPTION, seqid) $" << endl;
-      indent_up();
-      indent(f_service_) << "T.writeAppExn oprot (T.AppExn T.AE_UNKNOWN \"\")";
-      indent_down();
-    } else {
-      indent(f_service_) << "P.return ()";
-    }
-
-    f_service_ << ") :: X.SomeException -> P.IO ()))" << endl;
-    indent_down();
-    indent_down();
-  }
-  // Close function
-  indent_down();
-}
-
-/**
- * Deserializes a field of any type.
- */
-void t_hs_generator::generate_deserialize_field(ostream& out, t_field* tfield, string prefix) {
-  (void)prefix;
-  t_type* type = tfield->get_type();
-  generate_deserialize_type(out, type, prefix);
-}
-
-/**
- * Deserializes a field of any type.
- */
-void t_hs_generator::generate_deserialize_type(ostream& out, t_type* type, string arg) {
-  type = get_true_type(type);
-  string val = tmp("_val");
-  out << "(case " << arg << " of {" << type_to_constructor(type) << " " << val << " -> ";
-
-  if (type->is_void())
-    throw "CANNOT GENERATE DESERIALIZE CODE FOR void TYPE";
-
-  if (type->is_struct() || type->is_xception()) {
-    generate_deserialize_struct(out, (t_struct*)type, val);
-
-  } else if (type->is_container()) {
-    generate_deserialize_container(out, type, val);
-
-  } else if (type->is_base_type()) {
-    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-    if (tbase == t_base_type::TYPE_STRING && !type->is_binary()) {
-      out << "E.decodeUtf8 ";
-    }
-    out << val;
-    if (type->is_binary()) {
-      // Since wire type of binary is the same as string, we actually receive T.TString not
-      // T.TBinary
-      out << "; T.TString " << val << " -> " << val;
-    }
-  } else if (type->is_enum()) {
-    out << "P.toEnum $ P.fromIntegral " << val;
-
-  } else {
-    throw "DO NOT KNOW HOW TO DESERIALIZE TYPE " + type->get_name();
-  }
-  out << "; _ -> P.error \"wrong type\"})";
-}
-
-/**
- * Generates an unserializer for a struct, calling read()
- */
-void t_hs_generator::generate_deserialize_struct(ostream& out, t_struct* tstruct, string name) {
-
-  out << "(" << type_name(tstruct, "to_") << " (T.TStruct " << name << "))";
-}
-
-/**
- * Serialize a container by writing out the header followed by
- * data and then a footer.
- */
-void t_hs_generator::generate_deserialize_container(ostream& out, t_type* ttype, string arg) {
-
-  string val = tmp("_v");
-  // Declare variables, read header
-  if (ttype->is_map()) {
-    string key = tmp("_k");
-    out << "(Map.fromList $ P.map (\\(" << key << "," << val << ") -> (";
-    generate_deserialize_type(out, ((t_map*)ttype)->get_key_type(), key);
-
-    out << ",";
-    generate_deserialize_type(out, ((t_map*)ttype)->get_val_type(), val);
-
-    out << ")) " << arg << ")";
-
-  } else if (ttype->is_set()) {
-    out << "(Set.fromList $ P.map (\\" << val << " -> ";
-    generate_deserialize_type(out, ((t_set*)ttype)->get_elem_type(), val);
-    out << ") " << arg << ")";
-
-  } else if (ttype->is_list()) {
-    out << "(Vector.fromList $ P.map (\\" << val << " -> ";
-    generate_deserialize_type(out, ((t_list*)ttype)->get_elem_type(), val);
-    out << ") " << arg << ")";
-  }
-}
-
-/**
- * Serializes a field of any type.
- *
- * @param tfield The field to serialize
- * @param prefix Name to prepend to field name
- */
-void t_hs_generator::generate_serialize_type(ostream& out, t_type* type, string name) {
-
-  type = get_true_type(type);
-  // Do nothing for void types
-  if (type->is_void())
-    throw "CANNOT GENERATE SERIALIZE CODE FOR void TYPE";
-
-  if (type->is_struct() || type->is_xception()) {
-    generate_serialize_struct(out, (t_struct*)type, name);
-
-  } else if (type->is_container()) {
-    generate_serialize_container(out, type, name);
-
-  } else if (type->is_base_type() || type->is_enum()) {
-    if (type->is_base_type()) {
-      t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-      out << type_to_constructor(type) << " ";
-      if (tbase == t_base_type::TYPE_STRING && !type->is_binary()) {
-        out << "$ E.encodeUtf8 ";
-      }
-      out << name;
-
-    } else if (type->is_enum()) {
-      string ename = capitalize(type->get_name());
-      out << "T.TI32 $ P.fromIntegral $ P.fromEnum " << name;
-    }
-
-  } else {
-    throw "DO NOT KNOW HOW TO SERIALIZE FIELD OF TYPE " + type->get_name();
-  }
-}
-
-/**
- * Serializes all the members of a struct.
- *
- * @param tstruct The struct to serialize
- * @param prefix  String prefix to attach to all fields
- */
-void t_hs_generator::generate_serialize_struct(ostream& out, t_struct* tstruct, string prefix) {
-  out << type_name(tstruct, "from_") << " " << prefix;
-}
-
-void t_hs_generator::generate_serialize_container(ostream& out, t_type* ttype, string prefix) {
-  string k = tmp("_k");
-  string v = tmp("_v");
-
-  if (ttype->is_map()) {
-    t_type* ktype = ((t_map*)ttype)->get_key_type();
-    t_type* vtype = ((t_map*)ttype)->get_val_type();
-    out << "T.TMap " << type_to_enum(ktype) << " " << type_to_enum(vtype);
-    out << " $ P.map (\\(" << k << "," << v << ") -> (";
-    generate_serialize_type(out, ktype, k);
-    out << ", ";
-    generate_serialize_type(out, vtype, v);
-    out << ")) $ Map.toList " << prefix;
-
-  } else if (ttype->is_set()) {
-    out << "T.TSet " << type_to_enum(((t_set*)ttype)->get_elem_type());
-    out << " $ P.map (\\" << v << " -> ";
-    generate_serialize_type(out, ((t_set*)ttype)->get_elem_type(), v);
-    out << ") $ Set.toList " << prefix;
-
-  } else if (ttype->is_list()) {
-    out << "T.TList " << type_to_enum(((t_list*)ttype)->get_elem_type());
-    out << " $ P.map (\\" << v << " -> ";
-    generate_serialize_type(out, ((t_list*)ttype)->get_elem_type(), v);
-    out << ") $ Vector.toList " << prefix;
-  }
-}
-
-string t_hs_generator::function_type(t_function* tfunc, bool options, bool io, bool method) {
-  string result = "";
-
-  const vector<t_field*>& fields = tfunc->get_arglist()->get_members();
-  for (auto field : fields) {
-    if (field->get_req() == t_field::T_OPTIONAL
-        || ((t_type*)field->get_type())->is_xception())
-      result += "P.Maybe ";
-    result += render_hs_type(field->get_type(), options);
-    result += " -> ";
-  }
-
-  if (fields.empty() && !method)
-    result += "() -> ";
-
-  if (io)
-    result += "P.IO ";
-
-  result += render_hs_type(tfunc->get_returntype(), io);
-  return result;
-}
-
-string t_hs_generator::type_name(t_type* ttype, string function_prefix) {
-  string prefix = "";
-  t_program* program = ttype->get_program();
-
-  if (program != nullptr && program != program_)
-    if (!ttype->is_service())
-      prefix = capitalize(program->get_name()) + "_Types.";
-
-  return prefix + function_prefix + capitalize(ttype->get_name());
-}
-
-string t_hs_generator::field_name(string tname, string fname) {
-  return decapitalize(tname) + "_" + fname;
-}
-
-/**
- * Converts the parse type to a Protocol.t_type enum
- */
-string t_hs_generator::type_to_enum(t_type* type) {
-  type = get_true_type(type);
-
-  if (type->is_base_type()) {
-    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-    switch (tbase) {
-    case t_base_type::TYPE_VOID:
-      return "T.T_VOID";
-    case t_base_type::TYPE_STRING:
-      return type->is_binary() ? "T.T_BINARY" : "T.T_STRING";
-    case t_base_type::TYPE_BOOL:
-      return "T.T_BOOL";
-    case t_base_type::TYPE_I8:
-      return "T.T_BYTE";
-    case t_base_type::TYPE_I16:
-      return "T.T_I16";
-    case t_base_type::TYPE_I32:
-      return "T.T_I32";
-    case t_base_type::TYPE_I64:
-      return "T.T_I64";
-    case t_base_type::TYPE_DOUBLE:
-      return "T.T_DOUBLE";
-    }
-
-  } else if (type->is_enum()) {
-    return "T.T_I32";
-
-  } else if (type->is_struct() || type->is_xception()) {
-    return "(T.T_STRUCT " + type_name((t_struct*)type, "typemap_") + ")";
-
-  } else if (type->is_map()) {
-    string ktype = type_to_enum(((t_map*)type)->get_key_type());
-    string vtype = type_to_enum(((t_map*)type)->get_val_type());
-    return "(T.T_MAP " + ktype + " " + vtype + ")";
-
-  } else if (type->is_set()) {
-    return "(T.T_SET " + type_to_enum(((t_set*)type)->get_elem_type()) + ")";
-
-  } else if (type->is_list()) {
-    return "(T.T_LIST " + type_to_enum(((t_list*)type)->get_elem_type()) + ")";
-  }
-
-  throw "INVALID TYPE IN type_to_enum: " + type->get_name();
-}
-
-/**
- * Converts the parse type to a default value
- */
-string t_hs_generator::type_to_default(t_type* type) {
-  type = get_true_type(type);
-
-  if (type->is_base_type()) {
-    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-    switch (tbase) {
-    case t_base_type::TYPE_VOID:
-      return "P.error \"No default value for type T_VOID\"";
-    case t_base_type::TYPE_STRING:
-      return "\"\"";
-    case t_base_type::TYPE_BOOL:
-      return "P.False";
-    case t_base_type::TYPE_I8:
-      return "0";
-    case t_base_type::TYPE_I16:
-      return "0";
-    case t_base_type::TYPE_I32:
-      return "0";
-    case t_base_type::TYPE_I64:
-      return "0";
-    case t_base_type::TYPE_DOUBLE:
-      return "0";
-    }
-
-  } else if (type->is_enum()) {
-    return "(P.toEnum 0)";
-
-  } else if (type->is_struct() || type->is_xception()) {
-    return type_name((t_struct*)type, "default_");
-
-  } else if (type->is_map()) {
-    return "Map.empty";
-
-  } else if (type->is_set()) {
-    return "Set.empty";
-
-  } else if (type->is_list()) {
-    return "Vector.empty";
-  }
-
-  throw "INVALID TYPE IN type_to_default: " + type->get_name();
-}
-
-/**
- * Converts the parse type to an haskell type
- */
-string t_hs_generator::render_hs_type(t_type* type, bool needs_parens) {
-  type = get_true_type(type);
-  string type_repr;
-
-  if (type->is_base_type()) {
-    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-    switch (tbase) {
-    case t_base_type::TYPE_VOID:
-      return "()";
-    case t_base_type::TYPE_STRING:
-      return (type->is_binary() ? "LBS.ByteString" : "LT.Text");
-    case t_base_type::TYPE_BOOL:
-      return "P.Bool";
-    case t_base_type::TYPE_I8:
-      return "I.Int8";
-    case t_base_type::TYPE_I16:
-      return "I.Int16";
-    case t_base_type::TYPE_I32:
-      return "I.Int32";
-    case t_base_type::TYPE_I64:
-      return "I.Int64";
-    case t_base_type::TYPE_DOUBLE:
-      return "P.Double";
-    }
-
-  } else if (type->is_enum()) {
-    return type_name((t_enum*)type);
-
-  } else if (type->is_struct() || type->is_xception()) {
-    return type_name((t_struct*)type);
-
-  } else if (type->is_map()) {
-    t_type* ktype = ((t_map*)type)->get_key_type();
-    t_type* vtype = ((t_map*)type)->get_val_type();
-    type_repr = "Map.HashMap " + render_hs_type(ktype, true) + " " + render_hs_type(vtype, true);
-
-  } else if (type->is_set()) {
-    t_type* etype = ((t_set*)type)->get_elem_type();
-    type_repr = "Set.HashSet " + render_hs_type(etype, true);
-
-  } else if (type->is_list()) {
-    t_type* etype = ((t_list*)type)->get_elem_type();
-    type_repr = "Vector.Vector " + render_hs_type(etype, true);
-
-  } else {
-    throw "INVALID TYPE IN type_to_enum: " + type->get_name();
-  }
-
-  return needs_parens ? "(" + type_repr + ")" : type_repr;
-}
-
-/**
- * Converts the parse type to a haskell constructor
- */
-string t_hs_generator::type_to_constructor(t_type* type) {
-  type = get_true_type(type);
-
-  if (type->is_base_type()) {
-    t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
-    switch (tbase) {
-    case t_base_type::TYPE_VOID:
-      throw "invalid type: T_VOID";
-    case t_base_type::TYPE_STRING:
-      return type->is_binary() ? "T.TBinary" : "T.TString";
-    case t_base_type::TYPE_BOOL:
-      return "T.TBool";
-    case t_base_type::TYPE_I8:
-      return "T.TByte";
-    case t_base_type::TYPE_I16:
-      return "T.TI16";
-    case t_base_type::TYPE_I32:
-      return "T.TI32";
-    case t_base_type::TYPE_I64:
-      return "T.TI64";
-    case t_base_type::TYPE_DOUBLE:
-      return "T.TDouble";
-    }
-
-  } else if (type->is_enum()) {
-    return "T.TI32";
-
-  } else if (type->is_struct() || type->is_xception()) {
-    return "T.TStruct";
-
-  } else if (type->is_map()) {
-    return "T.TMap _ _";
-
-  } else if (type->is_set()) {
-    return "T.TSet _";
-
-  } else if (type->is_list()) {
-    return "T.TList _";
-  }
-  throw "INVALID TYPE IN type_to_enum: " + type->get_name();
-}
-
-THRIFT_REGISTER_GENERATOR(hs, "Haskell", "")
diff --git a/compiler/cpp/src/thrift/generate/t_js_generator.cc b/compiler/cpp/src/thrift/generate/t_js_generator.cc
index fddcef4..48d7250 100644
--- a/compiler/cpp/src/thrift/generate/t_js_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_js_generator.cc
@@ -909,13 +909,9 @@
       out << indent() << dval << ";" << endl;
     }
     if (gen_ts_) {
-      if (gen_node_) {
-        f_types_ts_ << ts_indent() << "public " << (*m_iter)->get_name() << ": "
-                    << ts_get_type((*m_iter)->get_type()) << ";" << endl;
-      } else {
-        f_types_ts_ << ts_indent() << (*m_iter)->get_name() << ": "
-                    << ts_get_type((*m_iter)->get_type()) << ";" << endl;
-      }
+      string ts_access = gen_node_ ? "public " : "";
+      f_types_ts_ << ts_indent() << ts_access << (*m_iter)->get_name() << ts_get_req(*m_iter) << ": "
+                  << ts_get_type((*m_iter)->get_type()) << ";" << endl;
     }
   }
 
diff --git a/compiler/cpp/src/thrift/generate/t_lua_generator.cc b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
index 17dbac7..410c883 100644
--- a/compiler/cpp/src/thrift/generate/t_lua_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_lua_generator.cc
@@ -593,7 +593,21 @@
     vector<t_field*>::const_iterator fld_iter;
     for (fld_iter = args.begin(); fld_iter != args.end(); ++fld_iter) {
       std::string argname = (*fld_iter)->get_name();
-      indent(out) << "args." << argname << " = " << argname << endl;
+      if ((*fld_iter)->get_value() != nullptr) {
+        // Insert default value for nil arguments
+        t_type* type = get_true_type((*fld_iter)->get_type());
+        indent(out) << "if " << argname << " ~= nil then" << endl;
+        indent_up();
+        indent(out) << "args." << argname << " = " << argname << endl;
+        indent_down();
+        indent(out) << "else" << endl;
+        indent_up();
+        indent(out) << "args." << argname << " = " << render_const_value(type, (*fld_iter)->get_value()) << endl;
+        indent_down();
+        indent(out) << "end" << endl;
+      } else {
+        indent(out) << "args." << argname << " = " << argname << endl;
+      }
     }
 
     indent(out) << "args:write(self.oprot)" << endl;
diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
index 5048c0e..464ca6a 100644
--- a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
@@ -52,6 +52,7 @@
 {
     (void)option_string;
     suppress_deepcopy = false;
+    add_async_postfix = false;
     use_pascal_case_properties = false;
     union_ = false;
     serialize_ = false;
@@ -80,6 +81,9 @@
         else if (iter->first.compare("no_deepcopy") == 0) {
           suppress_deepcopy = true;
         }
+        else if (iter->first.compare("async_postfix") == 0) {
+          add_async_postfix = true;
+        }
         else {
           throw "unknown option netstd:" + iter->first;
         }
@@ -88,18 +92,6 @@
     out_dir_base_ = "gen-netstd";
 }
 
-static string correct_function_name_for_async(string const& function_name)
-{
-    string const async_end = "Async";
-    size_t i = function_name.find(async_end);
-    if (i != string::npos)
-    {
-        return function_name + async_end;
-    }
-
-    return function_name;
-}
-
 /**
 * \brief Search and replace "_args" substring in struct name if exist (for C# class naming)
 * \param struct_name
@@ -191,11 +183,12 @@
     }
 
     pverbose(".NET Standard options:\n");
-    pverbose("- union ......... %s\n", (is_union_enabled() ? "ON" : "off"));
-    pverbose("- serialize ..... %s\n", (is_serialize_enabled() ? "ON" : "off"));
-    pverbose("- wcf ........... %s\n", (is_wcf_enabled() ? "ON" : "off"));
-    pverbose("- pascal ........ %s\n", (use_pascal_case_properties ? "ON" : "off"));
-    pverbose("- no_deepcopy ... %s\n", (suppress_deepcopy ? "ON" : "off"));
+    pverbose("- union ........... %s\n", (is_union_enabled() ? "ON" : "off"));
+    pverbose("- serialize ....... %s\n", (is_serialize_enabled() ? "ON" : "off"));
+    pverbose("- wcf ............. %s\n", (is_wcf_enabled() ? "ON" : "off"));
+    pverbose("- pascal .......... %s\n", (use_pascal_case_properties ? "ON" : "off"));
+    pverbose("- no_deepcopy ..... %s\n", (suppress_deepcopy ? "ON" : "off"));
+    pverbose("- async_postfix ... %s\n", (add_async_postfix ? "ON" : "off"));
 }
 
 string t_netstd_generator::normalize_name(string name)
@@ -335,6 +328,7 @@
 {
     out << "#pragma warning disable IDE0079  // remove unnecessary pragmas" << endl
         << "#pragma warning disable IDE1006  // parts of the code use IDL spelling" << endl
+        << "#pragma warning disable IDE0083  // pattern matching \"that is not SomeType\" requires net5.0 but we still support earlier versions" << endl
         << endl;
 
     if (!namespace_name_.empty())
@@ -666,7 +660,7 @@
     }
     else if (type->is_enum())
     {
-        render << type->get_name() << "." << value->get_identifier_name();
+        render << type_name(type) << "." << value->get_identifier_name();
     }
     else
     {
@@ -1355,19 +1349,21 @@
     const vector<t_field*>& fields = tstruct->get_sorted_members();
     vector<t_field*>::const_iterator f_iter;
 
-    out << indent() << "var struc = new TStruct(\"" << name << "\");" << endl
-        << indent() << "await oprot.WriteStructBeginAsync(struc, cancellationToken);" << endl;
+    string tmpvar = tmp("tmp");
+    out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << endl
+        << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", cancellationToken);" << endl;
 
     if (fields.size() > 0)
     {
-        out << indent() << "var field = new TField();" << endl;
+        tmpvar = tmp("tmp");
+        out << indent() << "var " << tmpvar << " = new TField();" << endl;
         for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
         {
             generate_null_check_begin( out, *f_iter);
-            out << indent() << "field.Name = \"" << (*f_iter)->get_name() << "\";" << endl
-                << indent() << "field.Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl
-                << indent() << "field.ID = " << (*f_iter)->get_key() << ";" << endl
-                << indent() << "await oprot.WriteFieldBeginAsync(field, cancellationToken);" << endl;
+            out << indent() << tmpvar << ".Name = \"" << (*f_iter)->get_name() << "\";" << endl
+                << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl
+                << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << endl
+                << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", cancellationToken);" << endl;
 
             generate_serialize_field(out, *f_iter);
 
@@ -1405,12 +1401,14 @@
     const vector<t_field*>& fields = tstruct->get_sorted_members();
     vector<t_field*>::const_iterator f_iter;
 
-    out << indent() << "var struc = new TStruct(\"" << name << "\");" << endl
-        << indent() << "await oprot.WriteStructBeginAsync(struc, cancellationToken);" << endl;
+    string tmpvar = tmp("tmp");
+    out << indent() << "var " << tmpvar << " = new TStruct(\"" << name << "\");" << endl
+        << indent() << "await oprot.WriteStructBeginAsync(" << tmpvar << ", cancellationToken);" << endl;
 
     if (fields.size() > 0)
     {
-        out << indent() << "var field = new TField();" << endl;
+        tmpvar = tmp("tmp");
+        out << indent() << "var " << tmpvar << " = new TField();" << endl;
         bool first = true;
         for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter)
         {
@@ -1436,10 +1434,10 @@
                 indent_up();
             }
 
-            out << indent() << "field.Name = \"" << prop_name(*f_iter) << "\";" << endl
-                << indent() << "field.Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl
-                << indent() << "field.ID = " << (*f_iter)->get_key() << ";" << endl
-                << indent() << "await oprot.WriteFieldBeginAsync(field, cancellationToken);" << endl;
+            out << indent() << tmpvar << ".Name = \"" << prop_name(*f_iter) << "\";" << endl
+                << indent() << tmpvar << ".Type = " << type_to_enum((*f_iter)->get_type()) << ";" << endl
+                << indent() << tmpvar << ".ID = " << (*f_iter)->get_key() << ";" << endl
+                << indent() << "await oprot.WriteFieldBeginAsync(" << tmpvar << ", cancellationToken);" << endl;
 
             generate_serialize_field(out, *f_iter);
 
@@ -1472,10 +1470,11 @@
 
 void t_netstd_generator::generate_netstd_struct_tostring(ostream& out, t_struct* tstruct)
 {
+    string tmpvar = tmp("tmp");
     out << indent() << "public override string ToString()" << endl
         << indent() << "{" << endl;
-    indent_up();
-    out << indent() << "var sb = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl;
+    indent_up();	
+    out << indent() << "var " << tmpvar << " = new StringBuilder(\"" << tstruct->get_name() << "(\");" << endl;
 
     const vector<t_field*>& fields = tstruct->get_members();
     vector<t_field*>::const_iterator f_iter;
@@ -1501,15 +1500,15 @@
 
         if (useFirstFlag && (!had_required))
         {
-            out << indent() << "if(0 < " << tmp_count.c_str() << (is_required ? "" : "++") << ") { sb.Append(\", \"); }" << endl;
-            out << indent() << "sb.Append(\"" << prop_name(*f_iter) << ": \");" << endl;
+            out << indent() << "if(0 < " << tmp_count.c_str() << (is_required ? "" : "++") << ") { " << tmpvar << ".Append(\", \"); }" << endl;
+            out << indent() << tmpvar << ".Append(\"" << prop_name(*f_iter) << ": \");" << endl;
         }
         else
         {
-            out << indent() << "sb.Append(\", " << prop_name(*f_iter) << ": \");" << endl;
+            out << indent() << tmpvar << ".Append(\", " << prop_name(*f_iter) << ": \");" << endl;
         }
 
-        out << indent() << prop_name(*f_iter) << ".ToString(sb);" << endl;
+        out << indent() << prop_name(*f_iter) << ".ToString(" << tmpvar << ");" << endl;
 
         generate_null_check_end(out, *f_iter);
         if (is_required) {
@@ -1517,8 +1516,8 @@
         }
     }
 
-    out << indent() << "sb.Append(')');" << endl
-        << indent() << "return sb.ToString();" << endl;
+    out << indent() << tmpvar << ".Append(')');" << endl
+        << indent() << "return " << tmpvar << ".ToString();" << endl;
     indent_down();
     out << indent() << "}" << endl;
 }
@@ -1925,6 +1924,7 @@
         out << indent() << "[ServiceContract(Namespace=\"" << wcf_namespace_ << "\")]" << endl;
     }
 
+    prepare_member_name_mapping(tservice);
     out << indent() << "public interface IAsync" << extends_iface << endl
         << indent() << "{" << endl;
 
@@ -1948,10 +1948,21 @@
             }
         }
 
+        auto iter = (*f_iter)->annotations_.find("deprecated");
+        if( (*f_iter)->annotations_.end() != iter) {
+          out << indent() << "[Obsolete";
+          // empty annotation values end up with "1" somewhere, ignore these as well
+          if ((iter->second.length() > 0) && (iter->second != "1")) {
+            out << "(" << make_csharp_string_literal(iter->second) << ")";
+          }
+          out << "]" << endl;
+        }
+
         out << indent() << function_signature_async(*f_iter) << ";" << endl << endl;
     }
     indent_down();
     out << indent() << "}" << endl << endl;
+    cleanup_member_name_mapping(tservice);
 }
 
 void t_netstd_generator::generate_service_helpers(ostream& out, t_service* tservice)
@@ -1959,6 +1970,7 @@
     vector<t_function*> functions = tservice->get_functions();
     vector<t_function*>::iterator f_iter;
 
+    prepare_member_name_mapping(tservice);
     out << indent() << "public class InternalStructs" << endl;
     out << indent() << "{" << endl;
     indent_up();
@@ -1973,6 +1985,7 @@
 
     indent_down();
     out << indent() << "}" << endl << endl;
+    cleanup_member_name_mapping(tservice);
 }
 
 void t_netstd_generator::generate_service_client(ostream& out, t_service* tservice)
@@ -1992,7 +2005,7 @@
     out << endl;
 
     generate_netstd_doc(out, tservice);
-
+    prepare_member_name_mapping(tservice);
     out << indent() << "public class Client : " << extends_client << "IAsync" << endl
         << indent() << "{" << endl;
     indent_up();
@@ -2010,20 +2023,22 @@
 
     for (functions_iterator = functions.begin(); functions_iterator != functions.end(); ++functions_iterator)
     {
-        string function_name = correct_function_name_for_async((*functions_iterator)->get_name());
+        string raw_func_name = (*functions_iterator)->get_name();
+        string function_name = raw_func_name + (add_async_postfix ? "Async" : "");
 
         // async
         out << indent() << "public async " << function_signature_async(*functions_iterator, "") << endl
             << indent() << "{" << endl;
         indent_up();
 
+        string tmpvar = tmp("tmp");
         string argsname = (*functions_iterator)->get_name() + "Args";
 
-        out << indent() << "await OutputProtocol.WriteMessageBeginAsync(new TMessage(\"" << function_name
+        out << indent() << "await OutputProtocol.WriteMessageBeginAsync(new TMessage(\"" << raw_func_name
             << "\", TMessageType." << ((*functions_iterator)->is_oneway() ? "Oneway" : "Call") 
             << ", SeqId), cancellationToken);" << endl
             << indent() << endl
-            << indent() << "var args = new InternalStructs." << argsname << "() {" << endl;
+            << indent() << "var " << tmpvar << " = new InternalStructs." << argsname << "() {" << endl;
         indent_up();
 
         t_struct* arg_struct = (*functions_iterator)->get_arglist();
@@ -2042,7 +2057,7 @@
 
 
         out << indent() << endl
-            << indent() << "await args.WriteAsync(OutputProtocol, cancellationToken);" << endl
+            << indent() << "await " << tmpvar << ".WriteAsync(OutputProtocol, cancellationToken);" << endl
             << indent() << "await OutputProtocol.WriteMessageEndAsync(cancellationToken);" << endl
             << indent() << "await OutputProtocol.Transport.FlushAsync(cancellationToken);" << endl;
 
@@ -2054,29 +2069,32 @@
             collect_extensions_types(xs);
             prepare_member_name_mapping(xs, xs->get_members(), resultname);
 
+            tmpvar = tmp("tmp");
             out << indent() << endl
-                << indent() << "var msg = await InputProtocol.ReadMessageBeginAsync(cancellationToken);" << endl
-                << indent() << "if (msg.Type == TMessageType.Exception)" << endl
+                << indent() << "var " << tmpvar << " = await InputProtocol.ReadMessageBeginAsync(cancellationToken);" << endl
+                << indent() << "if (" << tmpvar << ".Type == TMessageType.Exception)" << endl
                 << indent() << "{" << endl;
             indent_up();
 
-            out << indent() << "var x = await TApplicationException.ReadAsync(InputProtocol, cancellationToken);" << endl
+            tmpvar = tmp("tmp");
+            out << indent() << "var " << tmpvar << " = await TApplicationException.ReadAsync(InputProtocol, cancellationToken);" << endl
                 << indent() << "await InputProtocol.ReadMessageEndAsync(cancellationToken);" << endl
-                << indent() << "throw x;" << endl;
+                << indent() << "throw " << tmpvar << ";" << endl;
             indent_down();
 
+            tmpvar = tmp("tmp");
             out << indent() << "}" << endl
                 << endl
-                << indent() << "var result = new InternalStructs." << resultname << "();" << endl
-                << indent() << "await result.ReadAsync(InputProtocol, cancellationToken);" << endl
+                << indent() << "var " << tmpvar << " = new InternalStructs." << resultname << "();" << endl
+                << indent() << "await " << tmpvar << ".ReadAsync(InputProtocol, cancellationToken);" << endl
                 << indent() << "await InputProtocol.ReadMessageEndAsync(cancellationToken);" << endl;
 
             if (!(*functions_iterator)->get_returntype()->is_void())
             {
-                out << indent() << "if (result.__isset.success)" << endl
+                out << indent() << "if (" << tmpvar << ".__isset.success)" << endl
                     << indent() << "{" << endl;
                 indent_up();
-                out << indent() << "return result.Success;" << endl;
+                out << indent() << "return " << tmpvar << ".Success;" << endl;
                 indent_down();
                 out << indent() << "}" << endl;
             }
@@ -2085,10 +2103,10 @@
             vector<t_field*>::const_iterator x_iter;
             for (x_iter = xceptions.begin(); x_iter != xceptions.end(); ++x_iter)
             {
-                out << indent() << "if (result.__isset." << get_isset_name(normalize_name((*x_iter)->get_name())) << ")" << endl
+                out << indent() << "if (" << tmpvar << ".__isset." << get_isset_name(normalize_name((*x_iter)->get_name())) << ")" << endl
                     << indent() << "{" << endl;
                 indent_up();
-                out << indent() << "throw result." << prop_name(*x_iter) << ";" << endl;
+                out << indent() << "throw " << tmpvar << "." << prop_name(*x_iter) << ";" << endl;
                 indent_down();
                 out << indent() << "}" << endl;
             }
@@ -2103,7 +2121,7 @@
                     << function_name << " failed: unknown result\");" << endl;
             }
 
-            cleanup_member_name_mapping((*functions_iterator)->get_xceptions());
+            cleanup_member_name_mapping(xs);
             indent_down();
             out << indent() << "}" << endl << endl;
         }
@@ -2112,10 +2130,13 @@
             indent_down();
             out << indent() << "}" << endl;
         }
+
+        cleanup_member_name_mapping(arg_struct);
     }
 
     indent_down();
     out << indent() << "}" << endl << endl;
+    cleanup_member_name_mapping(tservice);
 }
 
 void t_netstd_generator::generate_service_server(ostream& out, t_service* tservice)
@@ -2131,6 +2152,7 @@
         extends_processor = extends + ".AsyncProcessor, ";
     }
 
+    prepare_member_name_mapping(tservice);
     out << indent() << "public class AsyncProcessor : " << extends_processor << "ITAsyncProcessor" << endl
         << indent() << "{" << endl;
 
@@ -2154,8 +2176,8 @@
     out << indent() << "_logger = logger;" << endl;
     for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter)
     {
-        string function_name = (*f_iter)->get_name();
-        out << indent() << "processMap_[\"" << correct_function_name_for_async(function_name) << "\"] = " << function_name << "_ProcessAsync;" << endl;
+        string raw_func_name = (*f_iter)->get_name();
+        out << indent() << "processMap_[\"" << raw_func_name << "\"] = " << raw_func_name << "_ProcessAsync;" << endl;
     }
 
     indent_down();
@@ -2242,6 +2264,7 @@
 
     indent_down();
     out << indent() << "}" << endl << endl;
+    cleanup_member_name_mapping(tservice);
 }
 
 void t_netstd_generator::generate_function_helpers(ostream& out, t_function* tfunction)
@@ -2281,13 +2304,15 @@
     string argsname = tfunction->get_name() + "Args";
     string resultname = tfunction->get_name() + "Result";
 
-    out << indent() << "var args = new InternalStructs." << argsname << "();" << endl
-        << indent() << "await args.ReadAsync(iprot, cancellationToken);" << endl
+    string args = tmp("tmp");
+    out << indent() << "var " << args << " = new InternalStructs." << argsname << "();" << endl
+        << indent() << "await " << args << ".ReadAsync(iprot, cancellationToken);" << endl
         << indent() << "await iprot.ReadMessageEndAsync(cancellationToken);" << endl;
 
+    string tmpResult = tmp("tmp");
     if (!tfunction->is_oneway())
     {
-        out << indent() << "var result = new InternalStructs." << resultname << "();" << endl;
+        out << indent() << "var " << tmpResult << " = new InternalStructs." << resultname << "();" << endl;
     }
 
     out << indent() << "try" << endl
@@ -2308,13 +2333,18 @@
     const vector<t_field*>& fields = arg_struct->get_members();
     vector<t_field*>::const_iterator f_iter;
 
+    bool is_deprecated = (tfunction->annotations_.end() != tfunction->annotations_.find("deprecated"));
+    if( is_deprecated) {
+      out << indent() << "#pragma warning disable CS0618,CS0612" << endl; 
+    }
+
     out << indent();
     if (!tfunction->is_oneway() && !tfunction->get_returntype()->is_void())
     {
-        out << "result.Success = ";
+        out << tmpResult << ".Success = ";
     }
 
-    out << "await _iAsync." << normalize_name(tfunction->get_name()) << "Async(";
+    out << "await _iAsync." << func_name(normalize_name(tfunction->get_name()) + (add_async_postfix ? "Async" : "")) << "(";
 
     bool first = true;
     collect_extensions_types(arg_struct);
@@ -2330,7 +2360,7 @@
             out << ", ";
         }
 
-        out << "args." << prop_name(*f_iter);
+        out << args << "." << prop_name(*f_iter);
     }
 
     cleanup_member_name_mapping(arg_struct);
@@ -2342,6 +2372,10 @@
 
     out << "cancellationToken);" << endl;
 
+    if( is_deprecated) {
+      out << indent() << "#pragma warning restore CS0618,CS0612" << endl; 
+    }
+
     vector<t_field*>::const_iterator x_iter;
 
     collect_extensions_types(xs);
@@ -2359,7 +2393,7 @@
             if (!tfunction->is_oneway())
             {
                 indent_up();
-                out << indent() << "result." << prop_name(*x_iter) << " = " << (*x_iter)->get_name() << ";" << endl;
+                out << indent() << tmpResult << "." << prop_name(*x_iter) << " = " << (*x_iter)->get_name() << ";" << endl;
                 indent_down();
             }
             out << indent() << "}" << endl;
@@ -2369,30 +2403,32 @@
     if (!tfunction->is_oneway())
     {
         out << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\""
-                << correct_function_name_for_async(tfunction->get_name()) << "\", TMessageType.Reply, seqid), cancellationToken); " << endl
-            << indent() << "await result.WriteAsync(oprot, cancellationToken);" << endl;
+                << tfunction->get_name() << "\", TMessageType.Reply, seqid), cancellationToken); " << endl
+            << indent() << "await " << tmpResult << ".WriteAsync(oprot, cancellationToken);" << endl;
     }
     indent_down();
 
     cleanup_member_name_mapping(xs);
 
+    string tmpex = tmp("tmp");
     out << indent() << "}" << endl
         << indent() << "catch (TTransportException)" << endl
         << indent() << "{" << endl
         << indent() << "  throw;" << endl
-        << indent() << "}" << endl
-        << indent() << "catch (Exception ex)" << endl
+        << indent() << "}" << endl 
+        << indent() << "catch (Exception " << tmpex << ")" << endl
         << indent() << "{" << endl;
     indent_up();
 
-    out << indent() << "var sErr = $\"Error occurred in {GetType().FullName}: {ex.Message}\";" << endl;
+    string tmpvar = tmp("tmp");
+    out << indent() << "var " << tmpvar << " = $\"Error occurred in {GetType().FullName}: {" << tmpex << ".Message}\";" << endl;
     out << indent() << "if(_logger != null)" << endl;
     indent_up();
-    out << indent() << "_logger.LogError(ex, sErr);" << endl;
+    out << indent() << "_logger.LogError(" << tmpex << ", " << tmpvar << ");" << endl;
     indent_down();
     out << indent() << "else" << endl;
     indent_up();
-    out << indent() << "Console.Error.WriteLine(sErr);" << endl;
+    out << indent() << "Console.Error.WriteLine(" << tmpvar << ");" << endl;
     indent_down();
 
     if (tfunction->is_oneway())
@@ -2402,10 +2438,11 @@
     }
     else
     {
-        out << indent() << "var x = new TApplicationException(TApplicationException.ExceptionType.InternalError,\" Internal error.\");" << endl
-            << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\"" << correct_function_name_for_async(tfunction->get_name())
+        tmpvar = tmp("tmp");
+        out << indent() << "var " << tmpvar << " = new TApplicationException(TApplicationException.ExceptionType.InternalError,\" Internal error.\");" << endl
+            << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\"" << tfunction->get_name()
             << "\", TMessageType.Exception, seqid), cancellationToken);" << endl
-            << indent() << "await x.WriteAsync(oprot, cancellationToken);" << endl;
+            << indent() << "await " << tmpvar << ".WriteAsync(oprot, cancellationToken);" << endl;
         indent_down();
 
         out << indent() << "}" << endl
@@ -2430,14 +2467,15 @@
     out << indent() << "try" << endl;
     scope_up(out);
 
-    out << indent() << tunion->get_name() << " retval;" << endl;
+    string tmpRetval = tmp("tmp");
+    out << indent() << tunion->get_name() << " " << tmpRetval << ";" << endl;
     out << indent() << "await iprot.ReadStructBeginAsync(cancellationToken);" << endl;
     out << indent() << "TField field = await iprot.ReadFieldBeginAsync(cancellationToken);" << endl;
     // we cannot have the first field be a stop -- we must have a single field defined
     out << indent() << "if (field.Type == TType.Stop)" << endl;
     scope_up(out);
     out << indent() << "await iprot.ReadFieldEndAsync(cancellationToken);" << endl;
-    out << indent() << "retval = new ___undefined();" << endl;
+    out << indent() << "" << tmpRetval << " = new ___undefined();" << endl;
     scope_down(out);
     out << indent() << "else" << endl;
     scope_up(out);
@@ -2451,13 +2489,14 @@
         out << indent() << "if (field.Type == " << type_to_enum((*f_iter)->get_type()) << ") {" << endl;
         indent_up();
 
-        out << indent() << type_name((*f_iter)->get_type()) << " temp;" << endl;
-        generate_deserialize_field(out, (*f_iter), "temp", true);
-        out << indent() << "retval = new " << (*f_iter)->get_name() << "(temp);" << endl;
+        string tmpvar = tmp("tmp");
+        out << indent() << type_name((*f_iter)->get_type()) << " " << tmpvar << ";" << endl;
+        generate_deserialize_field(out, (*f_iter), tmpvar, true);
+        out << indent() << tmpRetval << " = new " << (*f_iter)->get_name() << "(" << tmpvar << ");" << endl;
 
         indent_down();
         out << indent() << "} else { " << endl << indent() << " await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);"
-            << endl << indent() << "  retval = new ___undefined();" << endl << indent() << "}" << endl
+            << endl << indent() << "  " << tmpRetval << " = new ___undefined();" << endl << indent() << "}" << endl
             << indent() << "break;" << endl;
         indent_down();
     }
@@ -2465,7 +2504,7 @@
     out << indent() << "default: " << endl;
     indent_up();
     out << indent() << "await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);" << endl << indent()
-        << "retval = new ___undefined();" << endl;
+        << tmpRetval << " = new ___undefined();" << endl;
     out << indent() << "break;" << endl;
     indent_down();
 
@@ -2481,7 +2520,7 @@
     // end of else for TStop
     scope_down(out);
     out << indent() << "await iprot.ReadStructEndAsync(cancellationToken);" << endl;
-    out << indent() << "return retval;" << endl;
+    out << indent() << "return " << tmpRetval << ";" << endl;
     indent_down();
 
     scope_down(out);
@@ -2943,6 +2982,30 @@
     out << endl;
 }
 
+string t_netstd_generator::make_csharp_string_literal( string const& value)
+{
+  if (value.length() == 0) {
+    return "";
+  }
+
+  std::stringstream result;
+  result << "\"";
+  for (signed char const c: value) {
+    if( (c >= 0) && (c < 32)) {  // convert ctrl chars, but leave UTF-8 alone
+      int width = std::max( (int)sizeof(c), 4);
+      result << "\\x" << std::hex << std::setw(width) << std::setfill('0') << (int)c;
+    } else if ((c == '\\') || (c == '"')) {
+      result << "\\" << c;
+    } else {
+      result << c;   // anything else "as is"
+    }
+  }
+  result << "\"";
+  
+  return result.str();
+}
+
+
 string t_netstd_generator::make_valid_csharp_identifier(string const& fromName)
 {
     string str = fromName;
@@ -3006,12 +3069,17 @@
     return name;
 }
 
+void t_netstd_generator::prepare_member_name_mapping(t_service* tservice)
+{
+    prepare_member_name_mapping(tservice, tservice->get_functions(), tservice->get_name());
+}
+
 void t_netstd_generator::prepare_member_name_mapping(t_struct* tstruct)
 {
     prepare_member_name_mapping(tstruct, tstruct->get_members(), tstruct->get_name());
 }
 
-void t_netstd_generator::prepare_member_name_mapping(void* scope, const vector<t_field*>& members, const string& structname)
+void t_netstd_generator::prepare_member_name_mapping(t_struct* scope, const vector<t_field*>& members, const string& structname)
 {
     // begin new scope
     member_mapping_scopes.emplace_back();
@@ -3024,11 +3092,9 @@
     std::set<string> used_member_names;
     vector<t_field*>::const_iterator iter;
 
-    // prevent name conflicts with struct (CS0542 error)
+    // prevent name conflicts with struct (CS0542 error + THRIFT-2942)
     used_member_names.insert(structname);
     used_member_names.insert("Isset");
-
-    // prevent name conflicts with known methods (THRIFT-2942)
     used_member_names.insert("Read");
     used_member_names.insert("Write");
 
@@ -3057,6 +3123,51 @@
 }
 
 
+void t_netstd_generator::prepare_member_name_mapping(t_service* scope, const vector<t_function*>& members, const string& structname)
+{
+    // begin new scope
+    member_mapping_scopes.emplace_back();
+    member_mapping_scope& active = member_mapping_scopes.back();
+    active.scope_member = scope;
+
+    // current C# generator policy:
+    // - prop names are always rendered with an Uppercase first letter
+    // - struct names are used as given
+    std::set<string> used_member_names;
+    vector<t_function*>::const_iterator iter;
+
+    // prevent name conflicts with service/intf
+    used_member_names.insert(structname);
+    used_member_names.insert("Client");
+    used_member_names.insert("IAsync");
+    used_member_names.insert("AsyncProcessor");
+    used_member_names.insert("InternalStructs");
+
+    for (iter = members.begin(); iter != members.end(); ++iter)
+    {
+        string oldname = (*iter)->get_name();
+        string newname = func_name(*iter, true);
+        while (true)
+        {
+            // new name conflicts with another method
+            if (used_member_names.find(newname) != used_member_names.end())
+            {
+                pverbose("service %s: method %s conflicts with another method\n", structname.c_str(), newname.c_str());
+                newname += '_';
+                continue;
+            }
+
+            // add always, this helps us to detect edge cases like
+            // different spellings ("foo" and "Foo") within the same service
+            pverbose("service %s: method mapping %s => %s\n", structname.c_str(), oldname.c_str(), newname.c_str());
+            active.mapping_table[oldname] = newname;
+            used_member_names.insert(newname);
+            break;
+        }
+    }
+}
+
+
 string t_netstd_generator::convert_to_pascal_case(const string& str) {
   string out;
   bool must_capitalize = true;
@@ -3098,6 +3209,18 @@
   return name;
 }
 
+string t_netstd_generator::func_name(t_function* tfunc, bool suppress_mapping) {
+  return func_name(tfunc->get_name(), suppress_mapping);
+}
+
+string t_netstd_generator::func_name(std::string fname, bool suppress_mapping) {
+  if (suppress_mapping) {
+    return fname;
+  }
+
+  return get_mapped_member_name(fname);
+}
+
 string t_netstd_generator::type_name(t_type* ttype)
 {
     ttype = resolve_typedef(ttype);
@@ -3258,7 +3381,7 @@
 string t_netstd_generator::function_signature(t_function* tfunction, string prefix)
 {
     t_type* ttype = tfunction->get_returntype();
-    return type_name(ttype) + " " + normalize_name(prefix + tfunction->get_name()) + "(" + argument_list(tfunction->get_arglist()) + ")";
+    return type_name(ttype) + " " + func_name(normalize_name(prefix + tfunction->get_name())) + "(" + argument_list(tfunction->get_arglist()) + ")";
 }
 
 string t_netstd_generator::function_signature_async(t_function* tfunction, string prefix)
@@ -3270,7 +3393,7 @@
         task += "<" + type_name(ttype) + ">";
     }
 
-    string result = task + " " + normalize_name(prefix + tfunction->get_name()) + "Async(";
+    string result = task + " " + func_name(normalize_name(prefix + tfunction->get_name()) + (add_async_postfix ? "Async" : "")) + "(";
     string args = argument_list(tfunction->get_arglist());
     result += args;
     if (!args.empty())
@@ -3457,4 +3580,5 @@
     "    union:           Use new union typing, which includes a static read function for union types.\n"
     "    pascal:          Generate Pascal Case property names according to Microsoft naming convention.\n"
     "    no_deepcopy:     Suppress generation of DeepCopy() method.\n"
+    "    async_postfix:   Append \"Async\" to all service methods (maintains compatibility with existing code).\n"
 )
diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.h b/compiler/cpp/src/thrift/generate/t_netstd_generator.h
index 1217cc8..b35550d 100644
--- a/compiler/cpp/src/thrift/generate/t_netstd_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.h
@@ -139,6 +139,8 @@
   string argument_list(t_struct* tstruct);
   string type_to_enum(t_type* ttype);
   string prop_name(t_field* tfield, bool suppress_mapping = false);
+  string func_name(t_function* tfunc, bool suppress_mapping = false);
+  string func_name(std::string fname, bool suppress_mapping = false);
   string convert_to_pascal_case(const string& str);
   string get_enum_class_name(t_type* type);
 
@@ -152,6 +154,7 @@
   bool wcf_;
   bool use_pascal_case_properties;
   bool suppress_deepcopy;
+  bool add_async_postfix;
 
   string wcf_namespace_;
   map<string, int> netstd_keywords;
@@ -162,8 +165,11 @@
   void init_keywords();
   string normalize_name(string name);
   string make_valid_csharp_identifier(string const& fromName);
+  string make_csharp_string_literal( string const& value);
+  void prepare_member_name_mapping(t_service* tservice);
   void prepare_member_name_mapping(t_struct* tstruct);
-  void prepare_member_name_mapping(void* scope, const vector<t_field*>& members, const string& structname);
+  void prepare_member_name_mapping(t_struct* scope, const vector<t_field*>& members, const string& structname);
+  void prepare_member_name_mapping(t_service* scope, const vector<t_function*>& members, const string& structname);
   void cleanup_member_name_mapping(void* scope);
   string get_mapped_member_name(string oldname);
   string get_isset_name(const string& str);
diff --git a/compiler/cpp/src/thrift/generate/t_rs_generator.cc b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
index f55b7e0..40905c5 100644
--- a/compiler/cpp/src/thrift/generate/t_rs_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_rs_generator.cc
@@ -18,7 +18,6 @@
  */
 
 #include <string>
-#include <fstream>
 #include <iostream>
 
 #include "thrift/platform.h"
@@ -27,9 +26,10 @@
 using std::map;
 using std::ofstream;
 using std::ostringstream;
+using std::pair;
+using std::set;
 using std::string;
 using std::vector;
-using std::set;
 
 static const string endl("\n"); // avoid ostream << std::endl flushes
 static const string SERVICE_RESULT_VARIABLE("result_value");
@@ -106,7 +106,7 @@
   void render_attributes_and_includes();
 
   // Create the closure of Rust modules referenced by this service.
-  void compute_service_referenced_modules(t_service *tservice, set<string> &referenced_modules);
+  void compute_service_referenced_modules(t_service *tservice, set<pair<string, string>> &referenced_modules);
 
   // Write the rust representation of an enum.
   void render_enum_definition(t_enum* tenum, const string& enum_name);
@@ -116,7 +116,7 @@
 
   // Write the impl block associated with the rust representation of an enum. This includes methods
   // to write the enum to a protocol, read it from a protocol, etc.
-  void render_enum_impl(const string& enum_name);
+  void render_enum_impl(t_enum* tenum, const string& enum_name);
 
   // Write a simple rust const value (ie. `pub const FOO: foo...`).
   void render_const_value(const string& name, t_type* ttype, t_const_value* tvalue);
@@ -409,10 +409,10 @@
   bool is_double(t_type* ttype);
 
   // Return a string representing the rust type given a `t_type`.
-  string to_rust_type(t_type* ttype, bool ordered_float = true);
+  string to_rust_type(t_type* ttype);
 
   // Return a string representing the `const` rust type given a `t_type`
-  string to_rust_const_type(t_type* ttype, bool ordered_float = true);
+  string to_rust_const_type(t_type* ttype);
 
   // Return a string representing the rift `protocol::TType` given a `t_type`.
   string to_rust_field_type_enum(t_type* ttype);
@@ -547,9 +547,15 @@
   f_gen_ << "#![allow(unused_extern_crates)]" << endl;
   // constructors take *all* struct parameters, which can trigger the "too many arguments" warning
   // some auto-gen'd types can be deeply nested. clippy recommends factoring them out which is hard to autogen
-  f_gen_ << "#![allow(clippy::too_many_arguments, clippy::type_complexity)]" << endl;
+  // FIXME: re-enable the 'vec_box' lint see: [THRIFT-5364](https://issues.apache.org/jira/browse/THRIFT-5364)
+  // This can happen because we automatically generate a Vec<Box<Type>> when the type is a typedef
+  // and it's a forward typedef. This (typedef + forward typedef) can happen in two situations:
+  // 1. When the type is recursive
+  // 2. When you define types out of order
+  f_gen_ << "#![allow(clippy::too_many_arguments, clippy::type_complexity, clippy::vec_box)]" << endl;
   // prevent rustfmt from running against this file
   // lines are too long, code is (thankfully!) not visual-indented, etc.
+  // can't use #[rustfmt::skip] see: https://github.com/rust-lang/rust/issues/54726
   f_gen_ << "#![cfg_attr(rustfmt, rustfmt_skip)]" << endl;
   f_gen_ << endl;
 
@@ -578,13 +584,13 @@
   // NOTE: this is more involved than you would expect because of service extension
   // Basically, I have to find the closure of all the services and include their modules at the top-level
 
-  set<string> referenced_modules;
+  set<pair<string, string>> referenced_modules; // set<module, namespace>
 
   // first, start by adding explicit thrift includes
   const vector<t_program*> includes = get_program()->get_includes();
   vector<t_program*>::const_iterator includes_iter;
   for(includes_iter = includes.begin(); includes_iter != includes.end(); ++includes_iter) {
-    referenced_modules.insert((*includes_iter)->get_name());
+    referenced_modules.insert(std::make_pair((*includes_iter)->get_name(), (*includes_iter)->get_namespace("rs")));
   }
 
   // next, recursively iterate through all the services and add the names of any programs they reference
@@ -596,9 +602,18 @@
 
   // finally, write all the "pub use..." declarations
   if (!referenced_modules.empty()) {
-    set<string>::iterator module_iter;
+    set<pair<string, string>>::iterator module_iter;
     for (module_iter = referenced_modules.begin(); module_iter != referenced_modules.end(); ++module_iter) {
-      f_gen_ << "use crate::" << rust_snake_case(*module_iter) << ";" << endl;
+      string module_name((*module_iter).first);
+
+      string module_namespace((*module_iter).second);
+      string_replace(module_namespace, ".", "::");
+
+      if (module_namespace.empty()) {
+        f_gen_ << "use crate::" << rust_snake_case(module_name) << ";" << endl;
+      } else {
+        f_gen_ << "use crate::" << module_namespace << "::" << rust_snake_case(module_name) << ";" << endl;
+      }
     }
     f_gen_ << endl;
   }
@@ -606,12 +621,12 @@
 
 void t_rs_generator::compute_service_referenced_modules(
   t_service *tservice,
-  set<string> &referenced_modules
+  set<pair<string, string>> &referenced_modules
 ) {
   t_service* extends = tservice->get_extends();
   if (extends) {
     if (extends->get_program() != get_program()) {
-      referenced_modules.insert(extends->get_program()->get_name());
+      referenced_modules.insert(std::make_pair(extends->get_program()->get_name(), extends->get_program()->get_namespace("rs")));
     }
     compute_service_referenced_modules(extends, referenced_modules);
   }
@@ -868,49 +883,63 @@
 void t_rs_generator::generate_enum(t_enum* tenum) {
   string enum_name(rust_camel_case(tenum->get_name()));
   render_enum_definition(tenum, enum_name);
-  render_enum_impl(enum_name);
+  render_enum_impl(tenum, enum_name);
   render_enum_conversion(tenum, enum_name);
 }
 
 void t_rs_generator::render_enum_definition(t_enum* tenum, const string& enum_name) {
   render_rustdoc((t_doc*) tenum);
   f_gen_ << "#[derive(Copy, Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]" << endl;
-  f_gen_ << "pub enum " << enum_name << " {" << endl;
-  indent_up();
-
-  vector<t_enum_value*> constants = tenum->get_constants();
-  vector<t_enum_value*>::iterator constants_iter;
-  for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) {
-    t_enum_value* val = (*constants_iter);
-    render_rustdoc((t_doc*) val);
-    f_gen_
-      << indent()
-      << rust_enum_variant_name(val->get_name())
-      << " = "
-      << val->get_value()
-      << ","
-      << endl;
-  }
-
-  indent_down();
-  f_gen_ << "}" << endl;
+  f_gen_ << "pub struct " << enum_name << "(pub i32);" << endl;
   f_gen_ << endl;
 }
 
-void t_rs_generator::render_enum_impl(const string& enum_name) {
+void t_rs_generator::render_enum_impl(t_enum* tenum, const string& enum_name) {
   f_gen_ << "impl " << enum_name << " {" << endl;
   indent_up();
 
-  // taking enum as 'self' here because Thrift enums
-  // are represented as Rust enums with integer values
-  // it's cheaper to copy the integer as opposed to
-  // taking a reference to the enum
+  vector<t_enum_value*> constants = tenum->get_constants();
+
+  // associated constants for each IDL-defined enum variant
+  {
+      vector<t_enum_value*>::iterator constants_iter;
+      for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) {
+        t_enum_value* val = (*constants_iter);
+        render_rustdoc((t_doc*) val);
+        f_gen_
+            << indent()
+            << "pub const " << rust_enum_variant_name(val->get_name()) << ": " << enum_name
+            << " = "
+            << enum_name << "(" << val->get_value() << ")"
+            << ";"
+            << endl;
+      }
+  }
+
+  // array containing all IDL-defined enum variants
+  {
+    f_gen_ << indent() << "pub const ENUM_VALUES: &'static [Self] = &[" << endl;
+    indent_up();
+    vector<t_enum_value*>::iterator constants_iter;
+    for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) {
+      t_enum_value* val = (*constants_iter);
+      f_gen_
+          << indent()
+          << "Self::" << rust_enum_variant_name(val->get_name())
+          << ","
+          << endl;
+    }
+    indent_down();
+    f_gen_ << indent() << "];" << endl;
+  }
+
+  f_gen_ << indent() << "#[allow(clippy::trivially_copy_pass_by_ref)]" << endl;
   f_gen_
     << indent()
-    << "pub fn write_to_out_protocol(self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {"
+    << "pub fn write_to_out_protocol(&self, o_prot: &mut dyn TOutputProtocol) -> thrift::Result<()> {"
     << endl;
   indent_up();
-  f_gen_ << indent() << "o_prot.write_i32(self as i32)" << endl;
+  f_gen_ << indent() << "o_prot.write_i32(self.0)" << endl;
   indent_down();
   f_gen_ << indent() << "}" << endl;
 
@@ -919,10 +948,8 @@
     << "pub fn read_from_in_protocol(i_prot: &mut dyn TInputProtocol) -> thrift::Result<" << enum_name << "> {"
     << endl;
   indent_up();
-
   f_gen_ << indent() << "let enum_value = i_prot.read_i32()?;" << endl;
-  f_gen_ << indent() << enum_name << "::try_from(enum_value)";
-
+  f_gen_ << indent() << "Ok(" << enum_name << "::from(enum_value)" << ")" << endl;
   indent_down();
   f_gen_ << indent() << "}" << endl;
 
@@ -932,17 +959,13 @@
 }
 
 void t_rs_generator::render_enum_conversion(t_enum* tenum, const string& enum_name) {
-  f_gen_ << "impl TryFrom<i32> for " << enum_name << " {" << endl;
+  // From trait: i32 -> ENUM_TYPE
+  f_gen_ << "impl From<i32> for " << enum_name << " {" << endl;
   indent_up();
-
-  f_gen_ << indent() << "type Error = thrift::Error;";
-
-  f_gen_ << indent() << "fn try_from(i: i32) -> Result<Self, Self::Error> {" << endl;
+  f_gen_ << indent() << "fn from(i: i32) -> Self {" << endl;
   indent_up();
-
   f_gen_ << indent() << "match i {" << endl;
   indent_up();
-
   vector<t_enum_value*> constants = tenum->get_constants();
   vector<t_enum_value*>::iterator constants_iter;
   for (constants_iter = constants.begin(); constants_iter != constants.end(); ++constants_iter) {
@@ -950,26 +973,50 @@
     f_gen_
       << indent()
       << val->get_value()
-      << " => Ok(" << enum_name << "::" << rust_enum_variant_name(val->get_name()) << "),"
+      << " => " << enum_name << "::" << rust_enum_variant_name(val->get_name()) << ","
       << endl;
   }
-  f_gen_ << indent() << "_ => {" << endl;
+  f_gen_ << indent() << "_ => " << enum_name << "(i)" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
+
+  // From trait: &i32 -> ENUM_TYPE
+  f_gen_ << "impl From<&i32> for " << enum_name << " {" << endl;
   indent_up();
-  render_thrift_error(
-    "Protocol",
-    "ProtocolError",
-    "ProtocolErrorKind::InvalidData",
-    "format!(\"cannot convert enum constant {} to " + enum_name + "\", i)"
-  );
-  indent_down();
-  f_gen_ << indent() << "}," << endl;
-
+  f_gen_ << indent() << "fn from(i: &i32) -> Self {" << endl;
+  indent_up();
+  f_gen_ << indent() << enum_name << "::from(*i)" << endl;
   indent_down();
   f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
 
+  // From trait: ENUM_TYPE -> int
+  f_gen_ << "impl From<" << enum_name << "> for i32 {" << endl;
+  indent_up();
+  f_gen_ << indent() << "fn from(e: " << enum_name << ") -> i32 {" << endl;
+  indent_up();
+  f_gen_ << indent() << "e.0" << endl;
   indent_down();
   f_gen_ << indent() << "}" << endl;
+  indent_down();
+  f_gen_ << "}" << endl;
+  f_gen_ << endl;
 
+  // From trait: &ENUM_TYPE -> int
+  f_gen_ << "impl From<&" << enum_name << "> for i32 {" << endl;
+  indent_up();
+  f_gen_ << indent() << "fn from(e: &" << enum_name << ") -> i32 {" << endl;
+  indent_up();
+  f_gen_ << indent() << "e.0" << endl;
+  indent_down();
+  f_gen_ << indent() << "}" << endl;
   indent_down();
   f_gen_ << "}" << endl;
   f_gen_ << endl;
@@ -1050,15 +1097,7 @@
 
 void t_rs_generator::render_exception_struct_error_trait_impls(const string& struct_name, t_struct* tstruct) {
   // error::Error trait
-  f_gen_ << "impl Error for " << struct_name << " {" << endl;
-  indent_up();
-  f_gen_ << indent() << "fn description(&self) -> &str {" << endl;
-  indent_up();
-  f_gen_ << indent() << "\"" << "remote service threw " << tstruct->get_name() << "\"" << endl; // use *original* name
-  indent_down();
-  f_gen_ << indent() << "}" << endl;
-  indent_down();
-  f_gen_ << "}" << endl;
+  f_gen_ << "impl Error for " << struct_name << " {}" << endl;
   f_gen_ << endl;
 
   // convert::From trait
@@ -1078,7 +1117,12 @@
   indent_up();
   f_gen_ << indent() << "fn fmt(&self, f: &mut Formatter) -> fmt::Result {" << endl;
   indent_up();
-  f_gen_ << indent() << "self.description().fmt(f)" << endl;
+  f_gen_
+      << indent()
+      << "write!(f, "
+      << "\"remote service threw " << tstruct->get_name() << "\"" // use *original* name
+      << ")"
+      << endl;
   indent_down();
   f_gen_ << indent() << "}" << endl;
   indent_down();
@@ -2859,7 +2903,7 @@
 
   f_gen_ << indent() << "let ret_err = {" << endl;
   indent_up();
-  render_thrift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "usr_err.description()");
+  render_thrift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "usr_err.to_string()");
   indent_down();
   f_gen_ << indent() << "};" << endl;
   render_sync_handler_send_exception_response(tfunc, "ret_err");
@@ -2882,7 +2926,7 @@
 void t_rs_generator::render_sync_handler_failed_default_exception_branch(t_function *tfunc) {
   f_gen_ << indent() << "let ret_err = {" << endl;
   indent_up();
-  render_thrift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "e.description()");
+  render_thrift_error_struct("ApplicationError", "ApplicationErrorKind::Unknown", "e.to_string()");
   indent_down();
   f_gen_ << indent() << "};" << endl;
   if (tfunc->is_oneway()) {
@@ -3001,7 +3045,7 @@
   return false;
 }
 
-string t_rs_generator::to_rust_type(t_type* ttype, bool ordered_float) {
+string t_rs_generator::to_rust_type(t_type* ttype) {
   // ttype = get_true_type(ttype); <-- recurses through as many typedef layers as necessary
   if (ttype->is_base_type()) {
     t_base_type* tbase_type = ((t_base_type*)ttype);
@@ -3025,11 +3069,7 @@
     case t_base_type::TYPE_I64:
       return "i64";
     case t_base_type::TYPE_DOUBLE:
-      if (ordered_float) {
-        return "OrderedFloat<f64>";
-      } else {
-        return "f64";
-      }
+      return "OrderedFloat<f64>";
     }
   } else if (ttype->is_typedef()) {
     t_typedef* ttypedef = (t_typedef*)ttype;
@@ -3054,7 +3094,7 @@
   throw "cannot find rust type for " + ttype->get_name();
 }
 
-string t_rs_generator::to_rust_const_type(t_type* ttype, bool ordered_float) {
+string t_rs_generator::to_rust_const_type(t_type* ttype) {
   if (ttype->is_base_type()) {
     t_base_type* tbase_type = ((t_base_type*)ttype);
     if (tbase_type->get_base() == t_base_type::TYPE_STRING) {
@@ -3066,7 +3106,7 @@
     }
   }
 
-  return to_rust_type(ttype, ordered_float);
+  return to_rust_type(ttype);
 }
 
 string t_rs_generator::to_rust_field_type_enum(t_type* ttype) {
@@ -3288,23 +3328,38 @@
   bool all_uppercase = true;
 
   for (char i : name) {
-    if (isalnum(i) && islower(i)) {
+    if (isalpha(i) && islower(i)) {
       all_uppercase = false;
       break;
     }
   }
 
   if (all_uppercase) {
-    return capitalize(camelcase(lowercase(name)));
+    return name;
   } else {
-    return capitalize(camelcase(name));
+    string modified_name(uppercase(underscore(name)));
+    string_replace(modified_name, "__", "_");
+    return modified_name;
   }
 }
 
 string t_rs_generator::rust_upper_case(const string& name) {
-  string str(uppercase(underscore(name)));
-  string_replace(str, "__", "_");
-  return str;
+  bool all_uppercase = true;
+
+  for (char i : name) {
+    if (isalpha(i) && islower(i)) {
+      all_uppercase = false;
+      break;
+    }
+  }
+
+  if (all_uppercase) {
+    return name;
+  } else {
+    string str(uppercase(underscore(name)));
+    string_replace(str, "__", "_");
+    return str;
+  }
 }
 
 string t_rs_generator::rust_snake_case(const string& name) {
diff --git a/compiler/cpp/src/thrift/version.h b/compiler/cpp/src/thrift/version.h
index 1dcc5df..8cbec4e 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.14.2"
+#define THRIFT_VERSION "0.15.0"
 
 #endif // _THRIFT_VERSION_H_
diff --git a/compiler/cpp/tests/CMakeLists.txt b/compiler/cpp/tests/CMakeLists.txt
index 924e167..0e82541 100644
--- a/compiler/cpp/tests/CMakeLists.txt
+++ b/compiler/cpp/tests/CMakeLists.txt
@@ -97,7 +97,6 @@
 endmacro()
 
 # The following compiler with unit tests can be enabled or disabled
-THRIFT_ADD_COMPILER(as3     "Enable compiler for ActionScript 3" OFF)
 THRIFT_ADD_COMPILER(c_glib  "Enable compiler for C with Glib" OFF)
 THRIFT_ADD_COMPILER(cl      "Enable compiler for Common LISP" OFF)
 THRIFT_ADD_COMPILER(cpp     "Enable compiler for C++" OFF)
@@ -108,7 +107,6 @@
 THRIFT_ADD_COMPILER(go      "Enable compiler for Go" OFF)
 THRIFT_ADD_COMPILER(gv      "Enable compiler for GraphViz" OFF)
 THRIFT_ADD_COMPILER(haxe    "Enable compiler for Haxe" OFF)
-THRIFT_ADD_COMPILER(hs      "Enable compiler for Haskell" OFF)
 THRIFT_ADD_COMPILER(html    "Enable compiler for HTML Documentation" OFF)
 THRIFT_ADD_COMPILER(java    "Enable compiler for Java"   OFF)
 THRIFT_ADD_COMPILER(javame  "Enable compiler for Java ME" OFF)
diff --git a/configure.ac b/configure.ac
index ef47daf..93d761d 100755
--- a/configure.ac
+++ b/configure.ac
@@ -20,11 +20,11 @@
 AC_PREREQ(2.65)
 AC_CONFIG_MACRO_DIR([./aclocal])
 
-AC_INIT([thrift], [0.14.2])
+AC_INIT([thrift], [0.15.0])
 
 AC_CONFIG_AUX_DIR([.])
 
-AM_INIT_AUTOMAKE([1.13 subdir-objects tar-ustar])
+AM_INIT_AUTOMAKE([1.13 subdir-objects tar-ustar foreign])
 PKG_PROG_PKG_CONFIG
 
 AC_ARG_VAR([PY_PREFIX], [Prefix for installing Python modules.
@@ -70,12 +70,6 @@
                            Default = "/usr/local/lib"])
 AS_IF([test "x$PERL_PREFIX" = x], [PERL_PREFIX="/usr/local"])
 
-AC_ARG_VAR([CABAL_CONFIGURE_FLAGS],
-           [Extra flags to pass to cabal: "cabal Setup.lhs configure $CABAL_CONFIGURE_FLAGS".
-            (Typically used to set --user or force --global.)])
-
-AC_SUBST(CABAL_CONFIGURE_FLAGS)
-
 AC_ARG_VAR([D_IMPORT_PREFIX], [Prefix for installing D modules.
                            [INCLUDEDIR/d2]])
 AS_IF([test "x$D_IMPORT_PREFIX" = x], [D_IMPORT_PREFIX="${includedir}/d2"])
@@ -116,7 +110,6 @@
 have_libs=yes
 if test "$enable_libs" = "no"; then
   have_libs="no"
-  with_as3="no"
   with_cpp="no"
   with_c_glib="no"
   with_cl="no"
@@ -124,7 +117,6 @@
   with_python="no"
   with_py3="no"
   with_ruby="no"
-  with_haskell="no"
   with_haxe="no"
   with_netstd="no"
   with_perl="no"
@@ -141,18 +133,6 @@
   with_swift="no"
 fi
 
-AX_THRIFT_LIB(as3, [as3], yes)
-have_as3=no
-if test "$with_as3" = "yes"; then
-  if test "${FLEX_HOME+set}" = set; then 
-    AC_PATH_PROGS([FLEX_COMPC], [compc], "fail", [$PATH$PATH_SEPARATOR$FLEX_HOME/bin])
-    if test "$FLEX_COMPC" != "fail"; then
-      have_as3="yes"
-    fi
-  fi
-fi
-AM_CONDITIONAL(WITH_AS3, [test "$have_as3" = "yes"])
-
 AX_THRIFT_LIB(cpp, [C++], yes)
 have_cpp=no
 if test "$with_cpp" = "yes";  then
@@ -240,15 +220,9 @@
   if test -n "$ERL" -a -n "$ERLC" && test "x$REBAR" != "x" ; then
     have_erlang="yes"
 
-    # otp_release is simply a number (like "17") for OTP17+ while "R16..." for OTP16 or less.
-    # OTP version is currently only used for running tests.
-    if $ERL -eval 'erlang:display(erlang:system_info(otp_release)),halt().' -noshell | grep "^\"R" >/dev/null; then
-      erlang_otp16_or_less="yes"
-    fi
   fi
 fi
 AM_CONDITIONAL(WITH_ERLANG, [test "$have_erlang" = "yes"])
-AM_CONDITIONAL(ERLANG_OTP16, [test "$erlang_otp16_or_less" = "yes"])
 
 AX_THRIFT_LIB(nodejs, [Nodejs], yes)
 have_nodejs=no
@@ -379,24 +353,6 @@
 AM_CONDITIONAL(WITH_RUBY, [test "$have_ruby" = "yes"])
 AM_CONDITIONAL(HAVE_BUNDLER, [test "x$BUNDLER" != "x"])
 
-AX_THRIFT_LIB(haskell, [Haskell], yes)
-have_haskell=no
-RUNHASKELL=true
-CABAL=true
-if test "$with_haskell" = "yes"; then
-  AC_PATH_PROG([CABAL], [cabal])
-  AC_PATH_PROG([RUNHASKELL], [runhaskell])
-  if test "x$CABAL" != "x" -a "x$RUNHASKELL" != "x"; then
-    have_haskell="yes"
-  else
-    RUNHASKELL=true
-    CABAL=true
-  fi
-fi
-AC_SUBST(CABAL)
-AC_SUBST(RUNHASKELL)
-AM_CONDITIONAL(WITH_HASKELL, [test "$have_haskell" = "yes"])
-
 AX_THRIFT_LIB(go, [Go], yes)
 if test "$with_go" = "yes";  then
   AC_PATH_PROG([GO], [go])
@@ -480,7 +436,7 @@
 if test "$with_haxe" = "yes";  then
   AC_PATH_PROG([HAXE], [haxe])
   if [[ -x "$HAXE" ]] ; then
-    AX_PROG_HAXE_VERSION( [3.1.3], have_haxe="yes", have_haxe="no")
+    AX_PROG_HAXE_VERSION( [4.2.1], have_haxe="yes", have_haxe="no")
   fi
 fi
 AM_CONDITIONAL(WITH_HAXE, [test "$have_haxe" = "yes"])
@@ -776,7 +732,6 @@
   compiler/cpp/src/Makefile
   compiler/cpp/test/Makefile
   lib/Makefile
-  lib/as3/Makefile
   lib/cl/Makefile
   lib/cpp/Makefile
   lib/cpp/test/Makefile
@@ -792,8 +747,8 @@
   lib/erl/Makefile
   lib/go/Makefile
   lib/go/test/Makefile
+  lib/go/test/fuzz/Makefile
   lib/haxe/test/Makefile
-  lib/hs/Makefile
   lib/java/Makefile
   lib/js/Makefile
   lib/js/test/Makefile
@@ -811,6 +766,12 @@
   lib/rb/Makefile
   lib/rs/Makefile
   lib/rs/test/Makefile
+  lib/rs/test_recursive/Makefile
+  lib/rs/test_recursive/src/Makefile
+  lib/rs/test_recursive/src/maintenance/Makefile
+  lib/rs/test_recursive/src/transit/Makefile
+  lib/rs/test_recursive/src/transit/light/Makefile
+  lib/rs/test_recursive/src/transit/services/Makefile
   lib/lua/Makefile
   lib/swift/Makefile
   lib/ts/Makefile
@@ -824,7 +785,6 @@
   test/erl/Makefile
   test/go/Makefile
   test/haxe/Makefile
-  test/hs/Makefile
   test/lua/Makefile
   test/netstd/Makefile
   test/php/Makefile
@@ -842,7 +802,6 @@
   tutorial/d/Makefile
   tutorial/go/Makefile
   tutorial/haxe/Makefile
-  tutorial/hs/Makefile
   tutorial/java/Makefile
   tutorial/js/Makefile
   tutorial/netstd/Makefile
@@ -857,8 +816,6 @@
   tutorial/rs/Makefile
 ])
 
-if test "$have_as3" = "yes" ; then MAYBE_AS3="as3" ; else MAYBE_AS3="" ; fi
-AC_SUBST([MAYBE_AS3])
 if test "$have_cpp" = "yes" ; then MAYBE_CPP="cpp" ; else MAYBE_CPP="" ; fi
 AC_SUBST([MAYBE_CPP])
 if test "$have_c_glib" = "yes" ; then MAYBE_C_GLIB="c_glib" ; else MAYBE_C_GLIB="" ; fi
@@ -873,8 +830,6 @@
 AC_SUBST([MAYBE_PY3])
 if test "$have_ruby" = "yes" ; then MAYBE_RUBY="rb" ; else MAYBE_RUBY="" ; fi
 AC_SUBST([MAYBE_RUBY])
-if test "$have_haskell" = "yes" ; then MAYBE_HASKELL="hs" ; else MAYBE_HASKELL="" ; fi
-AC_SUBST([MAYBE_HASKELL])
 if test "$have_perl" = "yes" ; then MAYBE_PERL="perl" ; else MAYBE_PERL="" ; fi
 AC_SUBST([MAYBE_PERL])
 if test "$have_php" = "yes" ; then MAYBE_PHP="php" ; else MAYBE_PHP="" ; fi
@@ -906,7 +861,6 @@
 echo
 echo "$PACKAGE $VERSION"
 echo
-echo "Building ActionScript3 Library : $have_as3"
 echo "Building C (GLib) Library .... : $have_c_glib"
 echo "Building C++ Library ......... : $have_cpp"
 echo "Building Common Lisp Library.. : $have_cl"
@@ -915,7 +869,6 @@
 echo "Building .NET Standard Library : $have_netstd"
 echo "Building Erlang Library ...... : $have_erlang"
 echo "Building Go Library .......... : $have_go"
-echo "Building Haskell Library ..... : $have_haskell"
 echo "Building Haxe Library ........ : $have_haxe"
 echo "Building Java Library ........ : $have_java"
 echo "Building Lua Library ......... : $have_lua"
@@ -928,12 +881,6 @@
 echo "Building Rust Library ........ : $have_rs"
 echo "Building Swift Library ....... : $have_swift"
 
-if test "$have_as3" = "yes" ; then
-  echo
-  echo "ActionScript Library:"
-  echo "   FLEX_HOME ................. : $FLEX_HOME"
-  echo "   Using compc version ....... : $($FLEX_COMPC --version)"
-fi
 if test "$have_c_glib" = "yes" ; then
   echo
   echo "C (glib):"
@@ -988,13 +935,6 @@
   echo "   Using Go................... : $GO"
   echo "   Using Go version........... : $($GO version)"
 fi
-if test "$have_haskell" = "yes" ; then
-  echo
-  echo "Haskell Library:"
-  echo "   Using Cabal ............... : $CABAL"
-  echo "   Using Haskell ............. : $RUNHASKELL"
-  echo "   Using Haskell version ..... : $($RUNHASKELL --version)"
-fi
 if test "$have_haxe" = "yes" ; then
   echo
   echo "Haxe Library:"
diff --git a/contrib/README.md b/contrib/README.md
new file mode 100644
index 0000000..0f1354f
--- /dev/null
+++ b/contrib/README.md
@@ -0,0 +1,15 @@
+Apache Thrift contrib folder
+========================================
+
+The code in the /contrib folder is not maintained on a regular basis and its purpose is mainly to serve 
+as repository of (a) sample code what can be done with Thrift and (b) possibly helpfil utilities or other 
+potentially useful stuff. 
+
+You are of course free to provide patches for it, but other than that, the contrib stuff may or may not 
+work for your purpose, environment or software version, as it does not part of regular testing procedures.
+
+Below are some links (3rd-party sites) that lead you to some fairly good explanations of how it works.
+
+  * https://drewdevault.com/2020/06/06/Add-a-contrib-directory.html
+  * https://softwareengineering.stackexchange.com/questions/252053/whats-in-the-contrib-folder
+
diff --git a/contrib/Rebus/Properties/AssemblyInfo.cs b/contrib/Rebus/Properties/AssemblyInfo.cs
index 825897c..ba587b5 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.14.2.0")]
-[assembly: AssemblyFileVersion("0.14.2.0")]
+[assembly: AssemblyVersion("0.15.0.0")]
+[assembly: AssemblyFileVersion("0.15.0.0")]
diff --git a/contrib/Vagrantfile b/contrib/Vagrantfile
index 6d2d420..d4a7b82 100644
--- a/contrib/Vagrantfile
+++ b/contrib/Vagrantfile
@@ -68,10 +68,6 @@
 echo "golang-go golang-go/dashboard boolean false" | debconf-set-selections
 sudo apt-get -y install -qq golang golang-go
 
-# Haskell dependencies
-sudo apt-get install -qq ghc cabal-install libghc-binary-dev libghc-network-dev libghc-http-dev libghc-hashable-dev libghc-unordered-containers-dev libghc-vector-dev
-sudo cabal update
-
 # Lua dependencies
 sudo apt-get install -qq lua5.2 lua5.2-dev
 
diff --git a/contrib/thrift-maven-plugin/pom.xml b/contrib/thrift-maven-plugin/pom.xml
index 1294cb5..8928453 100644
--- a/contrib/thrift-maven-plugin/pom.xml
+++ b/contrib/thrift-maven-plugin/pom.xml
@@ -32,7 +32,7 @@
   <artifactId>thrift-maven-plugin</artifactId>
   <packaging>maven-plugin</packaging>
   <name>thrift-maven-plugin</name>
-  <version>0.14.2</version>
+  <version>0.15.0</version>
 
   <properties>
     <maven.compiler.source>1.8</maven.compiler.source>
diff --git a/contrib/thrift.spec b/contrib/thrift.spec
index 442c0b3..8578bac 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.14.2
+Version:        0.15.0
 Release:        0
 URL:            http://thrift.apache.org
 Packager:       Thrift Developers <dev@thrift.apache.org>
diff --git a/contrib/vagrant/centos-6.5/Vagrantfile b/contrib/vagrant/centos-6.5/Vagrantfile
index 51a2239..fe12da7 100644
--- a/contrib/vagrant/centos-6.5/Vagrantfile
+++ b/contrib/vagrant/centos-6.5/Vagrantfile
@@ -130,14 +130,6 @@
 #####################################
 sudo yum install -y mono-core mono-devel mono-web-devel mono-extras mingw32-binutils mingw32-runtime mingw32-nsis
 
-# Haskell LIB Dependencies
-#####################################
-wget http://sherkin.justhub.org/el6/RPMS/x86_64/justhub-release-2.0-4.0.el6.x86_64.rpm
-sudo rpm -ivh justhub-release-2.0-4.0.el6.x86_64.rpm
-sudo yum -y install haskell
-sudo cabal update
-sudo cabal install cabal-install
-
 # Build and Test Apache Thrift
 #####################################
 date > /etc/vagrant.provision_end
diff --git a/contrib/zeromq/csharp/AssemblyInfo.cs b/contrib/zeromq/csharp/AssemblyInfo.cs
index 12a47f4..8043c6d 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.14.2.0")]
+[assembly: AssemblyVersion("0.15.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/debian/control b/debian/control
index a9e934f..f69f73b 100644
--- a/debian/control
+++ b/debian/control
@@ -1,7 +1,7 @@
 Source: thrift
 Section: devel
 Priority: extra
-Build-Depends: dotnet-runtime-3.1, dotnet-sdk-3.1, debhelper (>= 9), build-essential, python-dev, ant,
+Build-Depends: dotnet-runtime-5.0, dotnet-sdk-5.0, debhelper (>= 9), build-essential, python-dev, ant,
     erlang-base, ruby-dev | ruby1.9.1-dev, ruby-bundler ,autoconf, automake,
     pkg-config, libtool, bison, flex, libboost-dev | libboost1.56-dev | libboost1.63-all-dev,
     python-all, python-setuptools, python-all-dev, python-all-dbg,
@@ -129,7 +129,7 @@
 Package: libthrift-netstd
 Architecture: all
 Section: netstd
-Depends: dotnet-runtime-3.1, ${misc:Depends}
+Depends: dotnet-runtime-5.0, ${misc:Depends}
 Description: NET Standard bindings for Thrift
  Thrift is a software framework for scalable cross-language services
  development. It combines a software stack with a code generation engine to
diff --git a/debian/copyright b/debian/copyright
index ada769b..a7038b1 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -17,69 +17,67 @@
 --------------------------------------------------
 Portions of the following files are licensed under the MIT License:
 
-  lib/erl/src/Makefile.am
+  lib/erl/Makefile.am
 
-Please see doc/otp-base-license.txt for the full terms of this license.
+Please see doc/licenses/otp-base-license.txt for the full terms of this license.
 
 
 --------------------------------------------------
 The following files contain some portions of code contributed under
-the Thrift Software License (see doc/old-thrift-license.txt), and relicensed
+the Thrift Software License (see doc/licenses/old-thrift-license.txt), and relicensed
 under the Apache 2.0 License:
 
   compiler/cpp/Makefile.am
-  compiler/cpp/src/generate/t_cpp_generator.cc
-  compiler/cpp/src/generate/t_netstd_generator.cc
-  compiler/cpp/src/generate/t_erl_generator.cc
-  compiler/cpp/src/generate/t_hs_generator.cc
-  compiler/cpp/src/generate/t_java_generator.cc
-  compiler/cpp/src/generate/t_ocaml_generator.cc
-  compiler/cpp/src/generate/t_perl_generator.cc
-  compiler/cpp/src/generate/t_php_generator.cc
-  compiler/cpp/src/generate/t_py_generator.cc
-  compiler/cpp/src/generate/t_rb_generator.cc
-  compiler/cpp/src/generate/t_st_generator.cc
-  compiler/cpp/src/generate/t_xsd_generator.cc
-  compiler/cpp/src/main.cc
-  compiler/cpp/src/parse/t_field.h
-  compiler/cpp/src/parse/t_program.h
-  compiler/cpp/src/platform.h
-  compiler/cpp/src/thriftl.ll
-  compiler/cpp/src/thrifty.yy
-  lib/netstd/src/Protocol/TBinaryProtocol.cs
-  lib/netstd/src/Protocol/TField.cs
-  lib/netstd/src/Protocol/TList.cs
-  lib/netstd/src/Protocol/TMap.cs
-  lib/netstd/src/Protocol/TMessage.cs
-  lib/netstd/src/Protocol/TMessageType.cs
-  lib/netstd/src/Protocol/TProtocol.cs
-  lib/netstd/src/Protocol/TProtocolException.cs
-  lib/netstd/src/Protocol/TProtocolFactory.cs
-  lib/netstd/src/Protocol/TProtocolUtil.cs
-  lib/netstd/src/Protocol/TSet.cs
-  lib/netstd/src/Protocol/TStruct.cs
-  lib/netstd/src/Protocol/TType.cs
-  lib/netstd/src/Server/TServer.cs
-  lib/netstd/src/Server/TSimpleServer.cs
-  lib/netstd/src/Server/TThreadPoolServer.cs
-  lib/netstd/src/TApplicationException.cs
-  lib/netstd/src/Thrift.csproj
-  lib/netstd/src/Thrift.sln
-  lib/netstd/src/TProcessor.cs
-  lib/netstd/src/Transport/TServerSocket.cs
-  lib/netstd/src/Transport/TServerTransport.cs
-  lib/netstd/src/Transport/TSocket.cs
-  lib/netstd/src/Transport/TStreamTransport.cs
-  lib/netstd/src/Transport/TTransport.cs
-  lib/netstd/src/Transport/TTransportException.cs
-  lib/netstd/src/Transport/TTransportFactory.cs
-  lib/netstd/ThriftMSBuildTask/Properties/AssemblyInfo.cs
-  lib/netstd/ThriftMSBuildTask/ThriftBuild.cs
-  lib/netstd/ThriftMSBuildTask/ThriftMSBuildTask.csproj
+  compiler/cpp/src/thrift/generate/t_cpp_generator.cc
+  compiler/cpp/src/thrift/generate/t_netstd_generator.cc
+  compiler/cpp/src/thrift/generate/t_erl_generator.cc
+  compiler/cpp/src/thrift/generate/t_hs_generator.cc
+  compiler/cpp/src/thrift/generate/t_java_generator.cc
+  compiler/cpp/src/thrift/generate/t_ocaml_generator.cc
+  compiler/cpp/src/thrift/generate/t_perl_generator.cc
+  compiler/cpp/src/thrift/generate/t_php_generator.cc
+  compiler/cpp/src/thrift/generate/t_py_generator.cc
+  compiler/cpp/src/thrift/generate/t_rb_generator.cc
+  compiler/cpp/src/thrift/generate/t_st_generator.cc
+  compiler/cpp/src/thrift/generate/t_xsd_generator.cc
+  compiler/cpp/src/thrift/main.cc
+  compiler/cpp/src/thrift/parse/t_field.h
+  compiler/cpp/src/thrift/parse/t_program.h
+  compiler/cpp/src/thrift/platform.h
+  compiler/cpp/src/thrift/thriftl.ll
+  compiler/cpp/src/thrift/thrifty.yy
+  lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
+  lib/netstd/Thrift/Protocol/Entities/TField.cs
+  lib/netstd/Thrift/Protocol/Entities/TList.cs
+  lib/netstd/Thrift/Protocol/Entities/TMap.cs
+  lib/netstd/Thrift/Protocol/Entities/TMessage.cs
+  lib/netstd/Thrift/Protocol/Entities/TMessageType.cs
+  lib/netstd/Thrift/Protocol/TProtocol.cs
+  lib/netstd/Thrift/Protocol/TProtocolException.cs
+  lib/netstd/Thrift/Protocol/TProtocolFactory.cs
+  lib/netstd/Thrift/Protocol/Utilities/TProtocolUtil.cs
+  lib/netstd/Thrift/Protocol/Entities/TSet.cs
+  lib/netstd/Thrift/Protocol/Entities/TStruct.cs
+  lib/netstd/Thrift/Protocol/Entities/TType.cs
+  lib/netstd/Thrift/Server/TServer.cs
+  lib/netstd/Thrift/Server/TSimpleAsyncServer.cs
+  lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs
+  lib/netstd/Thrift/TApplicationException.cs
+  lib/netstd/Thrift/Thrift.csproj
+  lib/netstd/Thrift.sln
+  lib/netstd/Thrift/Transport/Server/TServerSocketTransport.cs
+  lib/netstd/Thrift/Transport/Server/TServerTransport.cs
+  lib/netstd/Thrift/Transport/Client/TSocketTransport.cs
+  lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
+  lib/netstd/Thrift/Transport/TTransport.cs
+  lib/netstd/Thrift/Transport/TTransportException.cs
+  lib/netstd/Thrift/Transport/TTransportFactory.cs
+  lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Properties/AssemblyInfo.cs
+  lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift.PublicInterfaces.Compile.Tests.csproj
   lib/rb/lib/thrift.rb
-  lib/st/README
+  lib/st/README.md
   lib/st/thrift.st
-  test/OptionalRequiredTest.cpp
+  lib/cpp/test/OptionalRequiredTest.cpp
   test/OptionalRequiredTest.thrift
   test/ThriftTest.thrift
 
@@ -91,38 +89,3 @@
 #   Copying and distribution of this file, with or without
 #   modification, are permitted in any medium without royalty provided
 #   the copyright notice and this notice are preserved.
-
---------------------------------------------------
-For the compiler/cpp/src/md5.[ch] components:
-
-/*
-  Copyright (C) 1999, 2000, 2002 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-
----------------------------------------------------
-For the lib/rb/setup.rb: Copyright (c) 2000-2005 Minero Aoki,
-lib/ocaml/OCamlMakefile and lib/ocaml/README-OCamlMakefile components:
-     Copyright (C) 1999 - 2007  Markus Mottl
-
-Licensed under the terms of the GNU Lesser General Public License 2.1
-(see doc/lgpl-2.1.txt for the full terms of this license)
diff --git a/doap.rdf b/doap.rdf
index 7143ec1..53ff1fc 100755
--- a/doap.rdf
+++ b/doap.rdf
@@ -41,7 +41,6 @@
     <programming-language>Delphi</programming-language>
     <programming-language>Erlang</programming-language>
     <programming-language>Go</programming-language>
-    <programming-language>Haskell</programming-language>
     <programming-language>Haxe</programming-language>
     <programming-language>Java</programming-language>
     <programming-language>JavaScript</programming-language>
diff --git a/doc/ReleaseManagement.md b/doc/ReleaseManagement.md
index d2b6f34..70df31c 100644
--- a/doc/ReleaseManagement.md
+++ b/doc/ReleaseManagement.md
@@ -399,8 +399,6 @@
   * Run "pub publish" and go through the google account authorization to allow it.
 * [dlang] Within a day, the dlang dub site https://code.dlang.org/packages/apache-thrift?tab=info
   should pick up the release based on the tag.  No action is needed.
-* [haskell] https://hackage.haskell.org/package/thrift
-    https://jira.apache.org/jira/browse/THRIFT-4698
 * [npmjs] @jfarrell is the only one who can do this right now.
     https://issues.apache.org/jira/browse/THRIFT-4688
 * [perl] A submission to CPAN is necessary (normally jeking3 does this):
diff --git a/doc/install/debian.md b/doc/install/debian.md
index d6b5500..92d68e9 100644
--- a/doc/install/debian.md
+++ b/doc/install/debian.md
@@ -33,9 +33,7 @@
  * Erlang
 	* erlang-base erlang-eunit erlang-dev rebar
  * NetStd
-	* apt-transport-https dotnet-sdk-3.1 aspnetcore-runtime-3.1
- * Haskell
-	* ghc cabal-install libghc-binary-dev libghc-network-dev libghc-http-dev
+	* apt-transport-https dotnet-sdk-5.0 aspnetcore-runtime-5.0
  * Thrift Compiler for Windows
 	* mingw-w64 mingw-w64-x86-64-dev nsis
  * Rust
diff --git a/doc/specs/idl.md b/doc/specs/idl.md
index ded6cf8..adcbb71 100644
--- a/doc/specs/idl.md
+++ b/doc/specs/idl.md
@@ -1,6 +1,6 @@
 ## Thrift interface description language
 
-For Thrift version 0.14.2.
+For Thrift version 0.15.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.
 
@@ -210,6 +210,21 @@
 
     [42] Digit           ::=  ['0'-'9']
 
+## Reserved keywords
+
+    "BEGIN", "END", "__CLASS__", "__DIR__", "__FILE__", "__FUNCTION__",
+    "__LINE__", "__METHOD__", "__NAMESPACE__", "abstract", "alias", "and", "args", "as",
+    "assert", "begin", "break", "case", "catch", "class", "clone", "continue", "declare",
+    "def", "default", "del", "delete", "do", "dynamic", "elif", "else", "elseif", "elsif",
+    "end", "enddeclare", "endfor", "endforeach", "endif", "endswitch", "endwhile", "ensure",
+    "except", "exec", "finally", "float", "for", "foreach", "from", "function", "global",
+    "goto", "if", "implements", "import", "in", "inline", "instanceof", "interface", "is",
+    "lambda", "module", "native", "new", "next", "nil", "not", "or", "package", "pass",
+    "public", "print", "private", "protected", "raise", "redo", "rescue", "retry", "register",
+    "return", "self", "sizeof", "static", "super", "switch", "synchronized", "then", "this",
+    "throw", "transient", "try", "undef", "unless", "unsigned", "until", "use", "var",
+    "virtual", "volatile", "when", "while", "with", "xor", "yield" 
+
 ## Examples
 
 Here are some examples of Thrift definitions, using the Thrift IDL:
diff --git a/doc/specs/thrift-compact-protocol.md b/doc/specs/thrift-compact-protocol.md
index 6be2a62..89301eb 100644
--- a/doc/specs/thrift-compact-protocol.md
+++ b/doc/specs/thrift-compact-protocol.md
@@ -61,9 +61,21 @@
 def zigzagToLong(n: Long): Long = (n >>> 1) ^ - (n & 1)
 ```
 
-The zigzag int is then encoded as a *var int*. Var ints take 1 to 5 bytes (int32) or 1 to 10 bytes (int64). The most
-significant bit of each byte indicates if more bytes follow. The concatenation of the least significant 7 bits from each
-byte form the number, where the first byte has the most significant bits (so they are in big endian or network order).
+The zigzag int is then encoded as a *var int*, also known as *Unsigned LEB128*.  Var ints take 1 to 5 bytes (int32) or 
+1 to 10 bytes (int64). The process consists in taking a Big Endian unsigned integer, left-padding the bit-string to 
+make it a multiple of 7 bits, splitting it into 7-bit groups, prefixing the most-significant 7-bit group with the 0 
+bit, prefixing the remaining 7-bit groups with the 1 bit and encoding the resulting bit-string in Little Endian.
+
+For example, the integer 50399 is encoded as follows:
+
+```
+50399 = 1100 0100 1101 1111         (Big Endian representation)
+      = 00000 1100 0100 1101 1111   (Left-padding)
+      = 0000011 0001001 1011111     (7-bit groups)
+      = 00000011 10001001 11011111  (Most-significant bit prefixes)
+      = 11011111 10001001 00000011  (Little Endian representation)
+      = 0xDF 0x89 0x03
+```
 
 Var ints are sometimes used directly inside the compact protocol to represent positive numbers.
 
@@ -92,7 +104,8 @@
 
 ### String encoding
 
-*String*s are first encoded to UTF-8, and then send as binary.
+*String*s are first encoded to UTF-8, and then send as binary. They do not
+include a NUL delimiter.
 
 ### Double encoding
 
diff --git a/dub.json b/dub.json
index af76afc..72b7fbc 100644
--- a/dub.json
+++ b/dub.json
@@ -9,12 +9,29 @@
   "dependencies": {
     "libevent": {
       "version": "~>2.0.2"
-    },
-    "openssl": {
-      "version": ">=1.1.6"
     }
   },
-  "systemDependencies": "On systems with native openssl 1.0.x use dub package openssl~>1.1, on systems with native openssl 1.1.x use dub package openssl~>2.0",
+  "systemDependencies": "On systems with native openssl 1.0.x use dub package openssl~>1.1, on systems with native openssl 1.1.x use dub package openssl~>2.0.3 (with build bug fix: https://github.com/D-Programming-Deimos/openssl/issues/63)",
+  "configurations": [
+    {
+      "name": "use_openssl_1_0",
+      "versions": ["use_openssl_1_0_x"],
+      "dependencies": {
+        "openssl": {
+          "version": "~>1.1.6"
+        }
+      }
+    },
+    {
+      "name": "use_openssl_1_1",
+      "versions": ["use_openssl_1_1_x"],
+      "dependencies": {
+        "openssl": {
+          "version": "~>2.0.3"
+        }
+      }
+    }
+  ],
   "targetType": "library",
   "sourcePaths": [
     "lib/d/src" 
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..474ec99
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,5 @@
+module github.com/apache/thrift
+
+go 1.15
+
+require github.com/golang/mock v1.5.0
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..646b11a
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,14 @@
+github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
+github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 5d16256..56b295f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -20,10 +20,6 @@
 SUBDIRS = json xml
 PRECROSS_TARGET =
 
-if WITH_AS3
-SUBDIRS += as3
-endif
-
 if WITH_CPP
 SUBDIRS += cpp
 endif
@@ -52,10 +48,6 @@
 SUBDIRS += rb
 endif
 
-if WITH_HASKELL
-SUBDIRS += hs
-endif
-
 if WITH_PERL
 SUBDIRS += perl
 endif
@@ -106,7 +98,6 @@
 # All of the libs that don't use Automake need to go in here
 # so they will end up in our release tarballs.
 EXTRA_DIST = \
-	as3 \
 	d \
 	dart \
 	delphi \
diff --git a/lib/as3/CMakeLists.txt b/lib/as3/CMakeLists.txt
deleted file mode 100644
index 999905d..0000000
--- a/lib/as3/CMakeLists.txt
+++ /dev/null
@@ -1,68 +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.
-#
-
-if (IS_ABSOLUTE "${LIB_INSTALL_DIR}")
-    set(AS3_INSTALL_DIR "${LIB_INSTALL_DIR}/as3")
-else ()
-    set(AS3_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/as3")
-endif ()
-
-set(PRELEASE "true")
-if (CMAKE_BUILD_TYPE MATCHES DEBUG)
-    set(PRELEASE "false")
-endif ()
-
-add_custom_target(ThriftAs3 ALL
-    COMMENT "Building as3 library using Gradle Wrapper"
-    COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} compileFlex
-        --console=plain --no-daemon
-        -Prelease=${PRELEASE}
-        "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    )
-
-# Enable publishing from CMake if the publishing information is provided
-if (NOT CMAKE_BUILD_TYPE MATCHES DEBUG)
-    add_custom_target(MavenPublishAs3
-        COMMENT "Publishing as3 library to Apache Maven staging"
-        COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} clean publishMavenPublicationToMavenRepository
-            --console=plain --no-daemon
-            -Prelease=${PRELEASE}
-            -Psign=${PRELEASE}
-            "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    )
-endif ()
-
-# Hook the CMake install process to the results from make ALL.
-# This works best when 'make all && sudo make install/fast' is used.
-# Using slash to end the source location to avoid copying the directory path.
-install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build/libs/
-        DESTINATION ${AS3_INSTALL_DIR}
-        FILES_MATCHING PATTERN "libthrift-as3.swc")
-
-if (BUILD_TESTING)
-    add_test(NAME As3Test
-            COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} test
-                --console=plain --no-daemon
-                -Prelease=${PRELEASE}
-                "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
-                "-Pthrift.compiler=${THRIFT_COMPILER}"
-            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-endif ()
diff --git a/lib/as3/Makefile.am b/lib/as3/Makefile.am
deleted file mode 100644
index 0b3c3be..0000000
--- a/lib/as3/Makefile.am
+++ /dev/null
@@ -1,60 +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.
-#
-
-all-local:
-	./gradlew $(GRADLE_OPTS) compile \
-		-Prelease=true \
-		--console=plain
-
-install-exec-hook:
-	./gradlew $(GRADLE_OPTS) publishToMavenLocal \
-		-Prelease=true \
-		--console=plain
-
-clean-local:
-	./gradlew $(GRADLE_OPTS) clean \
-		-Prelease=true \
-                --console=plain
-	$(RM) -r .gradle
-
-check-local: $(THRIFT)
-	./gradlew $(GRADLE_OPTS) test \
-		-Prelease=true \
-		--console=plain
-
-maven-publish:
-	./gradlew $(GRADLE_OPTS) publishMavenPublicationToMavenRepository \
-		-Prelease=true \
-                -Psign=true \
-		--console=plain
-
-dist-hook:
-	$(RM) -r $(distdir)/.gradle/
-
-EXTRA_DIST = \
-	CMakeLists.txt \
-	README.md \
-	build.gradle \
-	coding_standards.md \
-	gradle \
-	gradle.properties \
-	gradlew \
-	gradlew.bat \
-	settings.gradle \
-	src
diff --git a/lib/as3/README.md b/lib/as3/README.md
deleted file mode 100644
index c14f8c7..0000000
--- a/lib/as3/README.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# Apache Thrift ActionScript Library
-
-## Building
-
-We use gradle and gradlefx to build the as3 library.  Unfortunately gradlefx requires
-an older version of gradle (2.5) but it still works - for now.  If you use the docker
-container to do the build, the Adobe Flex SDK 4.6 is installed and the FLEX_HOME
-environment variable is configured:
-
-    dev@ubuntu:~/thrift$ docker run -v $(pwd):/thrift/src:rw -it thrift/thrift-build:ubuntu-bionic /bin/bash
-    root@7624b61bbf84:/thrift/src# cd lib/as3
-    root@7624b61bbf84:/thrift/src/lib/as3# ./gradlew -Prelease=true compileFlex
-
-    ...
-
-    :compileFlex UP-TO-DATE
-
-    BUILD SUCCESSFUL
-
-    Total time: 10.784 secs
-
-    root@7624b61bbf84:/thrift/src/lib/as3# ls -ls build/
-    total 4
-    4 -rw-r--r-- 1 root root 1379 Jan 22 19:23 libthrift-as3.swc
-
-## Publishing
-
-We use a similar gradle-based signing and publishing mechanism as in the java
-library.  See the java library [README.md](../java/README.md) for more details.
-
-To publish into a local .m2 repository you can mount a directory into the docker container,
-for example:
-
-    dev@ubuntu:~/thrift$ docker run -v~/.m2:/root/.m2 -v $(pwd):/thrift/src:rw -it thrift/thrift-build:ubuntu-bionic /bin/bash
-    root@7624b61bbf84:/thrift/src/lib/as3# ./gradlew -Prelease=true publishToMavenLocal
-
-You will find your `~/.m2` directory is now populated with a release build `swc`.
diff --git a/lib/as3/build.gradle b/lib/as3/build.gradle
deleted file mode 100644
index 7853499..0000000
--- a/lib/as3/build.gradle
+++ /dev/null
@@ -1,56 +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.
- */
-
-buildscript {
-    repositories {
-        mavenLocal()
-        mavenCentral()
-    }
-    dependencies {
-        classpath group: 'org.gradlefx', name: 'gradlefx', version: '1.5.0'
-    }
-}
-
-plugins {
-    id 'maven-publish'
-    id 'signing'
-}
-
-apply plugin: 'gradlefx'
-
-description = 'Apache Thrift ActionScript Library'
-frameworkLinkage = 'none'
-group = property('thrift.groupid')
-srcDirs = ['src']
-type = 'swc'
-
-// We use the SNAPSHOT suffix for non-release versions
-if (Boolean.parseBoolean(project.release)) {
-    additionalCompilerOptions = ['-compiler.debug=false', '-compiler.strict=true']
-    version = property('thrift.version')
-} else {
-    additionalCompilerOptions = ['-compiler.debug=true', '-compiler.strict=true']
-    version = property('thrift.version') + '-SNAPSHOT'
-}
-
-defaultTasks 'compile'
-
-// Keeping the rest of the build logic in functional named scripts for clarity
-apply from: 'gradle/publishing.gradle'
-
diff --git a/lib/as3/coding_standards.md b/lib/as3/coding_standards.md
deleted file mode 100644
index fa0390b..0000000
--- a/lib/as3/coding_standards.md
+++ /dev/null
@@ -1 +0,0 @@
-Please follow [General Coding Standards](/doc/coding_standards.md)
diff --git a/lib/as3/gradle.properties b/lib/as3/gradle.properties
deleted file mode 100644
index ca89964..0000000
--- a/lib/as3/gradle.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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.14.2
-thrift.groupid=org.apache.thrift
-release=false
-sign=false
-
-# Local Install paths
-install.path=/usr/local/lib
-install.javadoc.path=/usr/local/lib
-
-# Test execution properties
-testPort=9090
-
-# Maven dependency download locations
-mvn.repo=https://repo1.maven.org/maven2
-apache.repo=https://repository.apache.org/content/repositories/releases
-
-# Apache Maven publish
-license=https://www.apache.org/licenses/LICENSE-2.0.txt
-maven-repository-url=https://repository.apache.org/service/local/staging/deploy/maven2
-maven-repository-id=apache.releases.https
diff --git a/lib/as3/gradle/publishing.gradle b/lib/as3/gradle/publishing.gradle
deleted file mode 100644
index 3e0ecf3..0000000
--- a/lib/as3/gradle/publishing.gradle
+++ /dev/null
@@ -1,96 +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.
- */
-
-// Following Gradle best practices to keep build logic organized
-
-model {
-    tasks.signMavenPublication {
-        dependsOn compileFlex
-    }
-}
-
-publishing {
-    publications {
-        maven(MavenPublication) {
-
-            groupId = "$group"
-            artifactId = "${project.name}"
-            version = "$version"
-
-            def swcFile = file("$buildDir/libthrift-as3.swc")
-            artifact(swcFile)
-
-            pom {
-                description = 'Thrift is a software framework for scalable cross-language services development.'
-                packaging = 'swc'
-
-                // older gradle doesn't recognize all the properties, so we inject them..
-                withXml {
-                    asNode().with {
-                        appendNode('name', 'Apache Thrift')
-                        appendNode('url', 'http://thrift.apache.org/')
-                        appendNode('scm').with {
-                            appendNode('url', 'https://github.com/apache/thrift/')
-                            appendNode('connection', 'scm:git:https://github.com/apache/thrift.git')
-                            appendNode('developerConnection', 'scm:git:git@github.com:apache/thrift.git')
-                        }
-                        appendNode('issueManagement').with {
-                            appendNode('url', 'https://issues.apache.org/jira/projects/THRIFT/')
-                            appendNode('system', 'Jira')
-                        }
-                        appendNode('licenses').with {
-                            appendNode('license').with {
-                                appendNode('name', 'The Apache Software License, Version 2.0')
-                                appendNode('url', "${project.license}")
-                            }
-                        }
-                        appendNode('organization').with {
-                            appendNode('name', 'The Apache Software Foundation')
-                            appendNode('url', 'http://www.apache.org/')
-                        }
-                        appendNode('developers').with {
-                            appendNode('developer').with {
-                                appendNode('id', 'dev')
-                                appendNode('name', 'Apache Thrift Developers')
-                                appendNode('email', 'dev@thrift.apache.org')
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-    repositories {
-        maven {
-            url = property('maven-repository-url')
-
-            if (project.hasProperty('mavenUser') && project.hasProperty('mavenPassword')) {
-                credentials {
-                    username = property('mavenUser')
-                    password = property('mavenPassword')
-                }
-            }
-        }
-    }
-}
-
-signing {
-    required { property('sign') }
-    sign publishing.publications.maven
-}
diff --git a/lib/as3/gradle/wrapper/gradle-wrapper.jar b/lib/as3/gradle/wrapper/gradle-wrapper.jar
deleted file mode 100644
index 87b738c..0000000
--- a/lib/as3/gradle/wrapper/gradle-wrapper.jar
+++ /dev/null
Binary files differ
diff --git a/lib/as3/gradle/wrapper/gradle-wrapper.properties b/lib/as3/gradle/wrapper/gradle-wrapper.properties
deleted file mode 100644
index 5028f28..0000000
--- a/lib/as3/gradle/wrapper/gradle-wrapper.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-distributionBase=GRADLE_USER_HOME
-distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip
-zipStoreBase=GRADLE_USER_HOME
-zipStorePath=wrapper/dists
diff --git a/lib/as3/gradlew b/lib/as3/gradlew
deleted file mode 100755
index af6708f..0000000
--- a/lib/as3/gradlew
+++ /dev/null
@@ -1,172 +0,0 @@
-#!/usr/bin/env sh
-
-##############################################################################
-##
-##  Gradle start up script for UN*X
-##
-##############################################################################
-
-# Attempt to set APP_HOME
-# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
-    ls=`ls -ld "$PRG"`
-    link=`expr "$ls" : '.*-> \(.*\)$'`
-    if expr "$link" : '/.*' > /dev/null; then
-        PRG="$link"
-    else
-        PRG=`dirname "$PRG"`"/$link"
-    fi
-done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
-
-APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m"'
-
-# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
-
-warn () {
-    echo "$*"
-}
-
-die () {
-    echo
-    echo "$*"
-    echo
-    exit 1
-}
-
-# OS specific support (must be 'true' or 'false').
-cygwin=false
-msys=false
-darwin=false
-nonstop=false
-case "`uname`" in
-  CYGWIN* )
-    cygwin=true
-    ;;
-  Darwin* )
-    darwin=true
-    ;;
-  MINGW* )
-    msys=true
-    ;;
-  NONSTOP* )
-    nonstop=true
-    ;;
-esac
-
-CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
-
-# Determine the Java command to use to start the JVM.
-if [ -n "$JAVA_HOME" ] ; then
-    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
-        # IBM's JDK on AIX uses strange locations for the executables
-        JAVACMD="$JAVA_HOME/jre/sh/java"
-    else
-        JAVACMD="$JAVA_HOME/bin/java"
-    fi
-    if [ ! -x "$JAVACMD" ] ; then
-        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-    fi
-else
-    JAVACMD="java"
-    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-
-Please set the JAVA_HOME variable in your environment to match the
-location of your Java installation."
-fi
-
-# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
-    MAX_FD_LIMIT=`ulimit -H -n`
-    if [ $? -eq 0 ] ; then
-        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
-            MAX_FD="$MAX_FD_LIMIT"
-        fi
-        ulimit -n $MAX_FD
-        if [ $? -ne 0 ] ; then
-            warn "Could not set maximum file descriptor limit: $MAX_FD"
-        fi
-    else
-        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
-    fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
-    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
-    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
-    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-    JAVACMD=`cygpath --unix "$JAVACMD"`
-
-    # We build the pattern for arguments to be converted via cygpath
-    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
-    SEP=""
-    for dir in $ROOTDIRSRAW ; do
-        ROOTDIRS="$ROOTDIRS$SEP$dir"
-        SEP="|"
-    done
-    OURCYGPATTERN="(^($ROOTDIRS))"
-    # Add a user-defined pattern to the cygpath arguments
-    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
-        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
-    fi
-    # Now convert the arguments - kludge to limit ourselves to /bin/sh
-    i=0
-    for arg in "$@" ; do
-        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
-        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
-
-        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
-            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
-        else
-            eval `echo args$i`="\"$arg\""
-        fi
-        i=$((i+1))
-    done
-    case $i in
-        (0) set -- ;;
-        (1) set -- "$args0" ;;
-        (2) set -- "$args0" "$args1" ;;
-        (3) set -- "$args0" "$args1" "$args2" ;;
-        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
-        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
-        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
-        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
-        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
-        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
-    esac
-fi
-
-# Escape application args
-save () {
-    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
-    echo " "
-}
-APP_ARGS=$(save "$@")
-
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
-  cd "$(dirname "$0")"
-fi
-
-exec "$JAVACMD" "$@"
diff --git a/lib/as3/gradlew.bat b/lib/as3/gradlew.bat
deleted file mode 100644
index 9618d8d..0000000
--- a/lib/as3/gradlew.bat
+++ /dev/null
@@ -1,100 +0,0 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem      https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem  Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto init
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
diff --git a/lib/as3/src/org/apache/thrift/AbstractMethodError.as b/lib/as3/src/org/apache/thrift/AbstractMethodError.as
deleted file mode 100644
index a2082b8..0000000
--- a/lib/as3/src/org/apache/thrift/AbstractMethodError.as
+++ /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.
- */
- 
-package org.apache.thrift {
-
-  import flash.errors.IllegalOperationError;
-
-  public class AbstractMethodError extends IllegalOperationError {
-    
-    public function AbstractMethodError(message:String="") {
-      super("Attempt to call an abstract method");
-    }
-    
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/Set.as b/lib/as3/src/org/apache/thrift/Set.as
deleted file mode 100644
index ae5f428..0000000
--- a/lib/as3/src/org/apache/thrift/Set.as
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift {
-  import flash.utils.Dictionary;
-  
-  
-  public class Set {
-    
-    private var _elements:Dictionary = new Dictionary();
-    private var _size:int = 0;
-    
-    public function Set(... values) {
-      for each (var value:* in values) {
-        add(value);
-      }
-    }
-
-    public function add(o:*):Boolean {
-      var alreadyPresent:Boolean = _elements.hasOwnProperty(o);
-      if (! alreadyPresent) {
-        _size++;
-        _elements[o] = true;
-      }
-     
-      return ! alreadyPresent;
-    }
-
-    public function clear():void {
-      for (var value:* in _elements) {
-        remove(value);
-      }
-    }
-    
-    public function contains(o:Object):Boolean {
-      return _elements.hasOwnProperty(o);
-    }
-    
-    public function isEmpty():Boolean {
-      return _size == 0;
-    }
-    
-    public function remove(o:*):Boolean {
-      if (contains(o)) {
-        delete _elements[o];
-        _size--;
-        return true;
-      }
-      else {
-        return false;
-      }
-    }
-    
-    public function toArray():Array {
-      var ret:Array = new Array();
-      for (var key:* in _elements) {
-        ret.push(key);
-      }
-      return ret;
-    }
-    
-    public function get size():int {
-      return _size;
-    }
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/TApplicationError.as b/lib/as3/src/org/apache/thrift/TApplicationError.as
deleted file mode 100644
index 3448fce..0000000
--- a/lib/as3/src/org/apache/thrift/TApplicationError.as
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift {
-
-  import org.apache.thrift.protocol.TField;
-  import org.apache.thrift.protocol.TProtocol;
-  import org.apache.thrift.protocol.TProtocolUtil;
-  import org.apache.thrift.protocol.TStruct;
-  import org.apache.thrift.protocol.TType;
-
-  /**
-   * Application level exception
-   */
-  public class TApplicationError extends TError {
-
-    private static const TAPPLICATION_EXCEPTION_STRUCT:TStruct = new TStruct("TApplicationException");
-    private static const MESSAGE_FIELD:TField = new TField("message", TType.STRING, 1);
-    private static const TYPE_FIELD:TField = new TField("type", TType.I32, 2);
-
-    public static const UNKNOWN:int = 0;
-    public static const UNKNOWN_METHOD:int = 1;
-    public static const INVALID_MESSAGE_TYPE:int = 2;
-    public static const WRONG_METHOD_NAME:int = 3;
-    public static const BAD_SEQUENCE_ID:int = 4;
-    public static const MISSING_RESULT:int = 5;
-    public static const INTERNAL_ERROR:int = 6;
-    public static const PROTOCOL_ERROR:int = 7;
-    public static const INVALID_TRANSFORM:int = 8;
-    public static const INVALID_PROTOCOL:int = 9;
-    public static const UNSUPPORTED_CLIENT_TYPE:int = 10;
-
-    public function TApplicationError(type:int = UNKNOWN, message:String = "") {
-      super(message, type);
-    }
-
-    public static function read(iprot:TProtocol):TApplicationError {
-      var field:TField;
-      iprot.readStructBegin();
-
-      var message:String = null;
-      var type:int = UNKNOWN;
-
-      while (true) {
-        field = iprot.readFieldBegin();
-        if (field.type == TType.STOP) {
-          break;
-        }
-        switch (field.id) {
-          case 1:
-            if (field.type == TType.STRING) {
-              message = iprot.readString();
-            }
-            else {
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          case 2:
-            if (field.type == TType.I32) {
-              type = iprot.readI32();
-            }
-            else {
-              TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            TProtocolUtil.skip(iprot, field.type);
-            break;
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-      return new TApplicationError(type, message);
-    }
-
-    public function write(oprot:TProtocol):void {
-        oprot.writeStructBegin(TAPPLICATION_EXCEPTION_STRUCT);
-        if (message != null) {
-          oprot.writeFieldBegin(MESSAGE_FIELD);
-          oprot.writeString(message);
-          oprot.writeFieldEnd();
-        }
-        oprot.writeFieldBegin(TYPE_FIELD);
-        oprot.writeI32(errorID);
-        oprot.writeFieldEnd();
-        oprot.writeFieldStop();
-        oprot.writeStructEnd();
-      }
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/TBase.as b/lib/as3/src/org/apache/thrift/TBase.as
deleted file mode 100644
index 615db1d..0000000
--- a/lib/as3/src/org/apache/thrift/TBase.as
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift {
-
-  import org.apache.thrift.protocol.TProtocol;
-
-  /**
-   * Generic base interface for generated Thrift objects.
-   *
-   */
-  public interface TBase {
-  
-    /**
-     * Reads the TObject from the given input protocol.
-     *
-     * @param iprot Input protocol
-     */
-    function read(iprot:TProtocol):void;
-  
-    /**
-     * Writes the objects out to the protocol
-     *
-     * @param oprot Output protocol
-     */
-    function write(oprot:TProtocol):void;
-  
-    /**
-     * Check if a field is currently set or unset.
-     *
-     * @param fieldId The field's id tag as found in the IDL.
-     */
-    function isSet(fieldId:int):Boolean;
-  
-    /**
-     * Get a field's value by id. Primitive types will be wrapped in the 
-     * appropriate "boxed" types.
-     *
-     * @param fieldId The field's id tag as found in the IDL.
-     */
-    function getFieldValue(fieldId:int):*;
-  
-    /**
-     * Set a field's value by id. Primitive types must be "boxed" in the 
-     * appropriate object wrapper type.
-     *
-     * @param fieldId The field's id tag as found in the IDL.
-     */
-    function setFieldValue(fieldId:int, value:*):void;
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/TError.as b/lib/as3/src/org/apache/thrift/TError.as
deleted file mode 100644
index ccc13b5..0000000
--- a/lib/as3/src/org/apache/thrift/TError.as
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- 
-package org.apache.thrift {
-  
-  public class TError extends Error {
-    
-    public function TError(message:String = "", errorCode:int = 0) {
-      super(message, errorCode);
-    }
-    
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/TProcessor.as b/lib/as3/src/org/apache/thrift/TProcessor.as
deleted file mode 100644
index 850acc9..0000000
--- a/lib/as3/src/org/apache/thrift/TProcessor.as
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
- package org.apache.thrift {
-
-import org.apache.thrift.protocol.TProtocol;
-
-    /**
-     * A processor is a generic object which operates upon an input stream and
-     * writes to some output stream.
-     *
-     */
-    public interface TProcessor {
-      function process(input:TProtocol, output:TProtocol):Boolean;
-    }
-}
diff --git a/lib/as3/src/org/apache/thrift/meta_data/FieldMetaData.as b/lib/as3/src/org/apache/thrift/meta_data/FieldMetaData.as
deleted file mode 100644
index cb18a14..0000000
--- a/lib/as3/src/org/apache/thrift/meta_data/FieldMetaData.as
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.meta_data {
-
-  import flash.utils.Dictionary;
-
-  /**
-   * This class is used to store meta data about thrift fields. Every field in a
-   * a struct should have a corresponding instance of this class describing it.
-   *
-   */
-  public class FieldMetaData {
-  
-    public var fieldName:String;
-    public var requirementType:int;
-    public var valueMetaData:FieldValueMetaData;
-  
-    private static var structMap:Dictionary = new Dictionary();
-  
-    public function FieldMetaData(name:String, req:int, vMetaData:FieldValueMetaData) {
-      this.fieldName = name;
-      this.requirementType = req;
-      this.valueMetaData = vMetaData;
-    }
-  
-    public static function addStructMetaDataMap(sClass:Class, map:Dictionary):void{
-      structMap[sClass] = map;
-    }
-
-    /**
-     * Returns a map with metadata (i.e. instances of FieldMetaData) that
-     * describe the fields of the given class.
-     *
-     * @param sClass The TBase class for which the metadata map is requested
-     */
-    public static function getStructMetaDataMap(sClass:Class):Dictionary {
-      return structMap[sClass];
-    }
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/meta_data/FieldValueMetaData.as b/lib/as3/src/org/apache/thrift/meta_data/FieldValueMetaData.as
deleted file mode 100644
index 07fe1be..0000000
--- a/lib/as3/src/org/apache/thrift/meta_data/FieldValueMetaData.as
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.meta_data {
-
-  import org.apache.thrift.protocol.TType;
-
-  /**
-   * FieldValueMetaData and collection of subclasses to store metadata about
-   * the value(s) of a field
-   */
-  public class FieldValueMetaData {
-  
-    public var type:int;  
- 
-    public function FieldValueMetaData(type:int) {
-      this.type = type;
-    }
-  
-    public function isStruct():Boolean {
-      return type == TType.STRUCT; 
-    }
-  
-    public function isContainer():Boolean {
-      return type == TType.LIST || type == TType.MAP || type == TType.SET;
-    }
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/meta_data/ListMetaData.as b/lib/as3/src/org/apache/thrift/meta_data/ListMetaData.as
deleted file mode 100644
index a2cc732..0000000
--- a/lib/as3/src/org/apache/thrift/meta_data/ListMetaData.as
+++ /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.
- */
-
-package org.apache.thrift.meta_data {
-  
-  public class ListMetaData extends FieldValueMetaData {
-    
-    public var elemMetaData:FieldValueMetaData;
-  
-    public function ListMetaData(type:int, eMetaData:FieldValueMetaData) {
-      super(type);
-      this.elemMetaData = eMetaData;
-    }    
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/meta_data/SetMetaData.as b/lib/as3/src/org/apache/thrift/meta_data/SetMetaData.as
deleted file mode 100644
index 390f034..0000000
--- a/lib/as3/src/org/apache/thrift/meta_data/SetMetaData.as
+++ /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.
- */
-
-package org.apache.thrift.meta_data {
-
-  public class SetMetaData extends FieldValueMetaData {
-  
-    public var elemMetaData:FieldValueMetaData;
-  
-    public function SetMetaData(type:int, eMetaData:FieldValueMetaData) {
-      super(type);
-      this.elemMetaData = eMetaData; 
-    }
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/meta_data/StructMetaData.as b/lib/as3/src/org/apache/thrift/meta_data/StructMetaData.as
deleted file mode 100644
index fc9b0be..0000000
--- a/lib/as3/src/org/apache/thrift/meta_data/StructMetaData.as
+++ /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.
- */
-
-package org.apache.thrift.meta_data {
-
-  public class StructMetaData extends FieldValueMetaData {
-    
-    public var structClass:Class;
-  
-    public function StructMetaData(type:int, sClass:Class) {
-      super(type);
-      this.structClass = sClass;
-    }
-  }    
-}
diff --git a/lib/as3/src/org/apache/thrift/protocol/TBinaryProtocol.as b/lib/as3/src/org/apache/thrift/protocol/TBinaryProtocol.as
deleted file mode 100644
index b2ff9d8..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TBinaryProtocol.as
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol {
-
-  import flash.utils.ByteArray;
-  
-  import org.apache.thrift.TError;
-  import org.apache.thrift.transport.THttpClient;
-  import org.apache.thrift.transport.TTransport;
-    
-  /**
-   * Binary protocol implementation for thrift.
-   */
-  public class TBinaryProtocol implements TProtocol {
-
-    private static var ANONYMOUS_STRUCT:TStruct = new TStruct();
-
-    protected static const VERSION_MASK:int = int(0xffff0000);
-    protected static const VERSION_1:int = int(0x80010000);
-
-    protected var strictRead_:Boolean = false;
-    protected var strictWrite_:Boolean = true;
-    
-  /**
-   * Factory
-   */
-   /*
-  public static class Factory implements TProtocolFactory {
-    protected boolean strictRead_ = false;
-    protected boolean strictWrite_ = true;
-
-    public Factory() {
-      this(false, true);
-    }
-
-    public Factory(boolean strictRead, boolean strictWrite) {
-      strictRead_ = strictRead;
-      strictWrite_ = strictWrite;
-    }
-
-    public TProtocol getProtocol(TTransport trans) {
-      return new TBinaryProtocol(trans, strictRead_, strictWrite_);
-    }
-  }
-  */
-  
-    private var trans_:TTransport;
-    
-    /**
-     * Constructor
-     */
-    public function TBinaryProtocol(trans:TTransport, strictRead:Boolean=false, strictWrite:Boolean=true) {
-      trans_ = trans;
-      strictRead_ = strictRead;
-      strictWrite_ = strictWrite;
-    }
-  
-    public function getTransport():TTransport {
-      return trans_;
-    }
-    
-    public function writeMessageBegin(message:TMessage):void {
-        if (strictWrite_) {
-          var version:int = VERSION_1 | message.type;
-          writeI32(version);
-          writeString(message.name);
-          writeI32(message.seqid);
-        } else {
-          writeString(message.name);
-          writeByte(message.type);
-          writeI32(message.seqid);
-        }
-    }
-    
-      public function writeMessageEnd():void {}
-  
-    public function writeStructBegin(struct:TStruct):void {}
-  
-    public function writeStructEnd():void {}
-  
-    public function writeFieldBegin(field:TField):void {
-      writeByte(field.type);
-      writeI16(field.id);
-    }
-    
-    public function writeFieldEnd():void {}
-    
-    public function writeFieldStop():void {
-      writeByte(TType.STOP);
-    }
-    
-    public function writeMapBegin(map:TMap):void {
-      writeByte(map.keyType);
-      writeByte(map.valueType);
-      writeI32(map.size);
-    }
-    
-    public function writeMapEnd():void {}
-    
-    public function writeListBegin(list:TList):void {
-        writeByte(list.elemType);
-        writeI32(list.size);
-    }
-    
-    public function writeListEnd():void {}
-    
-    public function writeSetBegin(set:TSet):void {
-        writeByte(set.elemType);
-        writeI32(set.size);
-      }
-      
-      public function writeSetEnd():void {}
-      
-      public function writeBool(b:Boolean):void {
-        writeByte(b ? 1 : 0);
-      }
-      
-      private var out:ByteArray = new ByteArray();
-      public function writeByte(b:int):void {
-        reset(out);
-        out.writeByte(b);
-        trans_.write(out, 0, 1);
-      }
-      
-      public function writeI16(i16:int):void {
-        reset(out);
-        out.writeShort(i16);
-        trans_.write(out, 0, 2);
-      }
-      
-      public function writeI32(i32:int):void {
-        reset(out);
-        out.writeInt(i32);
-        trans_.write(out, 0, 4);
-      }
-      
-      //private byte[] i64out = new byte[8];
-      //public function writeI64(i64:Number):void {
-        //i64out[0] = (byte)(0xff & (i64 >> 56));
-        //i64out[1] = (byte)(0xff & (i64 >> 48));
-        //i64out[2] = (byte)(0xff & (i64 >> 40));
-        //i64out[3] = (byte)(0xff & (i64 >> 32));
-        //i64out[4] = (byte)(0xff & (i64 >> 24));
-        //i64out[5] = (byte)(0xff & (i64 >> 16));
-        //i64out[6] = (byte)(0xff & (i64 >> 8));
-        //i64out[7] = (byte)(0xff & (i64));
-        //trans_.write(i64out, 0, 8);
-      //}
-      
-      public function writeDouble(dub:Number):void {
-        reset(out);
-        out.writeDouble(dub);
-        trans_.write(out, 0, 8);
-      }
-      
-      private var stringOut:ByteArray = new ByteArray();
-      
-      public function writeString(str:String):void {
-        reset(stringOut);
-        stringOut.writeUTFBytes(str);
-        
-        writeI32(stringOut.length);
-        trans_.write(stringOut, 0, stringOut.length);
-      }
-  
-    public function writeBinary(bin:ByteArray):void {
-      writeI32(bin.length);
-      trans_.write(bin, 0, bin.length);
-    }
-  
-    /**
-     * Reading methods.
-     */
-  
-    public function readMessageBegin():TMessage {
-      var size:int = readI32();
-      if (size < 0) {
-        var version:int = size & VERSION_MASK;
-        if (version != VERSION_1) {
-          throw new TProtocolError(TProtocolError.BAD_VERSION, "Bad version in readMessageBegin");
-        }
-        return new TMessage(readString(), size & 0x000000ff, readI32());
-      }
-      else {
-        if (strictRead_) {
-          throw new TProtocolError(TProtocolError.BAD_VERSION, "Missing version in readMessageBegin, old client?");
-        }
-            return new TMessage(readStringBody(size), readByte(), readI32());
-          }
-    }
-  
-    public function readMessageEnd():void {}
-  
-    public function readStructBegin():TStruct {
-        return ANONYMOUS_STRUCT;
-      }
-  
-    public function readStructEnd():void {}
-  
-    public function readFieldBegin():TField {
-        var type:int = readByte();
-        var id:int = type == TType.STOP ? 0 : readI16();
-        return new TField("", type, id);
-    }
-  
-    public function readFieldEnd():void {}
-  
-    public function readMapBegin():TMap {
-        return new TMap(readByte(), readByte(), readI32());
-    }
-  
-    public function readMapEnd():void {}
-  
-    public function readListBegin():TList {
-        return new TList(readByte(), readI32());
-    }
-  
-    public function readListEnd():void {}
-  
-    public function readSetBegin():TSet {
-      return new TSet(readByte(), readI32());
-    }
-  
-    public function readSetEnd():void {}
-  
-    public function readBool():Boolean {
-        return (readByte() == 1);
-    }
-  
-    private var bytes:ByteArray = new ByteArray();
-    
-    public function readByte():int {
-      readAll(1);
-        return bytes.readByte();
-      }
-  
-    public function readI16():int {
-        readAll(2);
-        return bytes.readShort();
-    }
-  
-    public function readI32():int {
-      readAll(4);
-      return bytes.readInt();
-    }
-  
-    //private byte[] i64rd = new byte[8];
-    /*
-    public function readI64() throws TException {
-      readAll(i64rd, 0, 8);
-      return
-        ((long)(i64rd[0] & 0xff) << 56) |
-        ((long)(i64rd[1] & 0xff) << 48) |
-        ((long)(i64rd[2] & 0xff) << 40) |
-        ((long)(i64rd[3] & 0xff) << 32) |
-        ((long)(i64rd[4] & 0xff) << 24) |
-        ((long)(i64rd[5] & 0xff) << 16) |
-        ((long)(i64rd[6] & 0xff) <<  8) |
-        ((long)(i64rd[7] & 0xff));
-    }
-    */
-  
-    public function readDouble():Number {
-      readAll(8);
-      return bytes.readDouble();
-    }
-  
-    public function readString():String {
-      var size:int = readI32();
-        readAll(size);
-        return bytes.readUTFBytes(size);
-      }
-  
-    public function readStringBody(size:int):String {
-        readAll(size);
-        return bytes.readUTFBytes(size);
-      }
-  
-    public function readBinary():ByteArray {
-        var size:int = readI32();
-        var buf:ByteArray = new ByteArray();
-        trans_.readAll(buf, 0, size);
-        return buf;
-    }
-  
-    private function readAll(len:int):void {
-      reset(bytes);
-      
-        trans_.readAll(bytes, 0, len);
-        
-        bytes.position = 0;
-      }
-    
-    private static function reset(arr:ByteArray):void {
-      arr.length = 0;
-      arr.position = 0;
-    }
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/protocol/TField.as b/lib/as3/src/org/apache/thrift/protocol/TField.as
deleted file mode 100644
index 1277f3a..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TField.as
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- 
-package org.apache.thrift.protocol {
-    
-  public class TField {
-    
-    public var name:String;
-    public var type:int;
-    public var id:int;
-      
-    public function TField(n:String = "", t:int = 0, i:int = 0) {
-      name = n;
-      type = t;
-      id = i;
-    }
-    
-    public function toString():String {
-      return "<TField name:'" + name + "' type:" + type + " field-id:" + id + ">";
-    }
-    
-    public function equals(otherField:TField):Boolean {
-      return type == otherField.type && id == otherField.id;
-    }
-        
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TList.as b/lib/as3/src/org/apache/thrift/protocol/TList.as
deleted file mode 100644
index f0bdbad..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TList.as
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- 
-package org.apache.thrift.protocol {
-  
-  public class TList {
-
-    public var elemType:int;
-    public var size:int;
-  
-      public function TList(t:int = 0, s:int = 0) {
-        elemType = t;
-        size = s;
-      }
-      
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TMap.as b/lib/as3/src/org/apache/thrift/protocol/TMap.as
deleted file mode 100644
index 2298804..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TMap.as
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- 
-package org.apache.thrift.protocol {
-  public class TMap {
-    
-    public var keyType:int;
-    public var valueType:int;
-    public var size:int;
-  
-    public function TMap(k:int = 0, v:int = 0, s:int = 0) {
-      keyType = k;
-      valueType = v;
-      size = s;
-    }
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TMessage.as b/lib/as3/src/org/apache/thrift/protocol/TMessage.as
deleted file mode 100644
index 9817235..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TMessage.as
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- 
-package org.apache.thrift.protocol {
-  
-  public class TMessage {
-    
-    public var name:String;
-    public var type:int;
-    public var seqid:int;
-  
-    public function TMessage(n:String = "", t:int = 0, s:int = 0) {
-      name = n;
-      type = t;
-      seqid = s;
-    }
-    
-    public function toString():String {
-      return "<TMessage name:'" + name + "' type: " + type + " seqid:" + seqid + ">";
-    }
-    
-    public function equals(other:TMessage):Boolean {
-      return name == other.name && type == other.type && seqid == other.seqid;
-    }
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TMessageType.as b/lib/as3/src/org/apache/thrift/protocol/TMessageType.as
deleted file mode 100644
index 56a9ba5..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TMessageType.as
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
- 
-package org.apache.thrift.protocol {
-  
-  public class TMessageType {
-    public static const CALL:int  = 1;
-    public static const REPLY:int = 2;
-    public static const EXCEPTION:int = 3;
-    public static const ONEWAY:int = 4;
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TProtocol.as b/lib/as3/src/org/apache/thrift/protocol/TProtocol.as
deleted file mode 100644
index bb9d744..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TProtocol.as
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol {
-
-  import org.apache.thrift.TError;
-  import org.apache.thrift.transport.TTransport;
-
-  import flash.utils.ByteArray;
-  
-  /**
-   * Protocol interface definition
-   */
-  public interface TProtocol {
-  
-    function TProtocol(trans:TTransport);
-
-    function getTransport():TTransport;
-
-    /**
-     * Writing methods.
-     */
-    function writeMessageBegin(message:TMessage):void;
-  
-    function writeMessageEnd():void;
-    
-    function writeStructBegin(struct:TStruct):void;
-    
-    function writeStructEnd():void;
-    
-    function writeFieldBegin(field:TField):void;
-    
-    function writeFieldEnd():void;
-    
-    function writeFieldStop():void;
-    
-    function writeMapBegin(map:TMap):void;
-    
-    function writeMapEnd():void;
-    
-    function writeListBegin(list:TList):void;
-    
-    function writeListEnd():void;
-    
-    function writeSetBegin(set:TSet):void;
-    
-    function writeSetEnd():void;
-    
-    function writeBool(b:Boolean):void;
-    
-    function writeByte(b:int):void;
-    
-    function writeI16(i16:int):void;
-    
-    function writeI32(i32:int):void;
-    
-    //function writeI64(i64:Number):void;
-    
-    function writeDouble(dub:Number):void;
-    
-    function writeString(str:String):void;
-    
-    function writeBinary(bin:ByteArray):void;
-    
-    /**
-     * Reading methods.
-     */
-    function readMessageBegin():TMessage;
-    
-    function readMessageEnd():void;
-    
-    function readStructBegin():TStruct;
-    
-    function readStructEnd():void;
-    
-    function readFieldBegin():TField;
-    
-    function readFieldEnd():void;
-    
-    function readMapBegin():TMap;
-    
-    function readMapEnd():void;
-    
-    function readListBegin():TList;
-    
-    function readListEnd():void;
-    
-    function readSetBegin():TSet;
-    
-    function readSetEnd():void;
-    
-    function readBool():Boolean;
-    
-    function readByte():int;
-    
-    function readI16():int;
-    
-    function readI32():int;
-    
-    //function readI64():Number;
-    
-    function readDouble():Number;
-    
-    function readString():String;
-    
-    function readBinary():ByteArray;
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TProtocolError.as b/lib/as3/src/org/apache/thrift/protocol/TProtocolError.as
deleted file mode 100644
index 9fff730..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TProtocolError.as
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol {
-  
-  import org.apache.thrift.TError;
-
-  public class TProtocolError extends TError {
-    
-    public static const UNKNOWN:int = 0;
-    public static const INVALID_DATA:int = 1;
-    public static const NEGATIVE_SIZE:int = 2;
-    public static const SIZE_LIMIT:int = 3;
-    public static const BAD_VERSION:int = 4;
-    public static const NOT_IMPLEMENTED:int = 5;
-    public static const DEPTH_LIMIT:int = 6;
-  
-    public function TProtocolError(error:int = UNKNOWN, message:String = "") {
-      super(message, error);
-    }
-    
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TProtocolFactory.as b/lib/as3/src/org/apache/thrift/protocol/TProtocolFactory.as
deleted file mode 100644
index c7f5e29..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TProtocolFactory.as
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol {
-
-  import org.apache.thrift.transport.TTransport;
-  
-  public interface TProtocolFactory {
-     function getProtocol(trans:TTransport):TProtocol;
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TProtocolUtil.as b/lib/as3/src/org/apache/thrift/protocol/TProtocolUtil.as
deleted file mode 100644
index 22877b7..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TProtocolUtil.as
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol {
-
-  import org.apache.thrift.TError;
-
-  /**
-   * Utility class with static methods for interacting with protocol data
-   * streams.
-   *
-   */
-  public class TProtocolUtil {
-
-    /**
-     * The maximum recursive depth the skip() function will traverse before
-     * throwing a TException.
-     */
-    private static var maxSkipDepth:int = int.MAX_VALUE;
-
-    /**
-     * Specifies the maximum recursive depth that the skip function will
-     * traverse before throwing a TException.  This is a global setting, so
-     * any call to skip in this JVM will enforce this value.
-     *
-     * @param depth  the maximum recursive depth.  A value of 2 would allow
-     *    the skip function to skip a structure or collection with basic children,
-     *    but it would not permit skipping a struct that had a field containing
-     *    a child struct.  A value of 1 would only allow skipping of simple
-     *    types and empty structs/collections.
-     */
-    public function setMaxSkipDepth(depth:int):void {
-      maxSkipDepth = depth;
-    }
-
-    /**
-     * Skips over the next data element from the provided input TProtocol object.
-     *
-     * @param prot  the protocol object to read from
-     * @param type  the next value will be intepreted as this TType value.
-     */
-    public static function skip(prot:TProtocol, type:int):void {
-      skipMaxDepth(prot, type, maxSkipDepth);
-    }
-
-     /**
-     * Skips over the next data element from the provided input TProtocol object.
-     *
-     * @param prot  the protocol object to read from
-     * @param type  the next value will be intepreted as this TType value.
-     * @param maxDepth  this function will only skip complex objects to this
-     *   recursive depth, to prevent Java stack overflow.
-     */
-    public static function skipMaxDepth(prot:TProtocol, type:int, maxDepth:int):void {
-      if (maxDepth <= 0) {
-        throw new TError("Maximum skip depth exceeded");
-      }
-      switch (type) {
-        case TType.BOOL: {
-          prot.readBool();
-          break;
-        }
-        case TType.BYTE: {
-          prot.readByte();
-          break;
-        }
-        case TType.I16: {
-          prot.readI16();
-          break;
-        }
-        case TType.I32: {
-          prot.readI32();
-          break;
-        }
-        /*
-        case TType.I64: {
-          prot.readI64();
-          break;
-        }
-        */
-        case TType.DOUBLE: {
-          prot.readDouble();
-          break;
-        }
-        case TType.STRING: {
-          prot.readBinary();
-          break;
-        }
-        case TType.STRUCT: {
-          prot.readStructBegin();
-          while (true) {
-            var field:TField = prot.readFieldBegin();
-            if (field.type == TType.STOP) {
-              break;
-            }
-            skipMaxDepth(prot, field.type, maxDepth - 1);
-            prot.readFieldEnd();
-          }
-          prot.readStructEnd();
-          break;
-        }
-        case TType.MAP: {
-          var map:TMap = prot.readMapBegin();
-          for (var i:int = 0; i < map.size; i++) {
-            skipMaxDepth(prot, map.keyType, maxDepth - 1);
-            skipMaxDepth(prot, map.valueType, maxDepth - 1);
-          }
-          prot.readMapEnd();
-          break;
-        }
-        case TType.SET: {
-          var set:TSet = prot.readSetBegin();
-          for (var j:int = 0; j < set.size; j++) {
-            skipMaxDepth(prot, set.elemType, maxDepth - 1);
-          }
-          prot.readSetEnd();
-          break;
-        }
-        case TType.LIST: {
-          var list:TList = prot.readListBegin();
-          for (var k:int = 0; k < list.size; k++) {
-            skipMaxDepth(prot, list.elemType, maxDepth - 1);
-          }
-          prot.readListEnd();
-          break;
-        }
-        default:
-          throw new TProtocolError(TProtocolError.INVALID_DATA, "invalid data");
-      }
-    }
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/protocol/TSet.as b/lib/as3/src/org/apache/thrift/protocol/TSet.as
deleted file mode 100644
index 3f0e1a6..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TSet.as
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol {
-  
-  public class TSet {
-
-    public var elemType:int;
-    public var size:int;
-  
-      public function TSet(t:int = 0, s:int = 0) {
-        elemType = t;
-        size = s;
-      }
-      
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TStruct.as b/lib/as3/src/org/apache/thrift/protocol/TStruct.as
deleted file mode 100644
index dffad79..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TStruct.as
+++ /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.
- */
-
-package org.apache.thrift.protocol {
-  
-  public class TStruct {
-    
-    public var name:String;
-    
-    public function TStruct(n:String = "") {
-      name = n;
-    }
-    
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/protocol/TType.as b/lib/as3/src/org/apache/thrift/protocol/TType.as
deleted file mode 100644
index 69af208..0000000
--- a/lib/as3/src/org/apache/thrift/protocol/TType.as
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol {
-  
-  public class TType {
-    
-    public static const STOP:int   = 0;
-    public static const VOID:int   = 1;
-    public static const BOOL:int   = 2;
-    public static const BYTE:int   = 3;
-    public static const DOUBLE:int = 4;
-    public static const I16:int    = 6;
-    public static const I32:int    = 8;
-    public static const I64:int    = 10;
-    public static const STRING:int = 11;
-    public static const STRUCT:int = 12;
-    public static const MAP:int    = 13;
-    public static const SET:int    = 14;
-    public static const LIST:int   = 15;
-
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/transport/TFullDuplexHttpClient.as b/lib/as3/src/org/apache/thrift/transport/TFullDuplexHttpClient.as
deleted file mode 100644
index 863c59b..0000000
--- a/lib/as3/src/org/apache/thrift/transport/TFullDuplexHttpClient.as
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.transport
-{
-
-    import flash.errors.EOFError;
-    import flash.events.Event;
-    import flash.events.IOErrorEvent;
-    import flash.events.ProgressEvent;
-    import flash.events.SecurityErrorEvent;
-    import flash.net.URLLoader;
-    import flash.net.URLLoaderDataFormat;
-    import flash.net.URLRequest;
-    import flash.net.URLRequestMethod;
-    import flash.utils.IDataInput;
-    import flash.utils.IDataOutput;
-    import flash.utils.ByteArray;
-    import flash.net.Socket;
-    import flash.events.EventDispatcher;
-
-
-    /**
-     * HTTP implementation of the TTransport interface. Used for working with a
-     * Thrift web services implementation.
-     * Unlike Http Client, it uses a single POST, and chunk-encoding to transfer all messages.
-     */
-
-    public class TFullDuplexHttpClient extends TTransport
-    {
-        private var socket:Socket = null;
-
-        private var host:String;
-
-        private var port:int;
-
-        private var resource:String;
-
-        private var stripped:Boolean = false;
-
-        private var obuffer:ByteArray = new ByteArray();
-
-        private var input:IDataInput;
-
-        private var output:IDataOutput;
-
-        private var bytesInChunk:int = 0;
-
-        private var CRLF:ByteArray = new ByteArray();
-
-        private var ioCallback:Function = null;
-
-        private var eventDispatcher:EventDispatcher = new EventDispatcher();
-
-        public function TFullDuplexHttpClient(host:String, port:int, resource:String):void
-        {
-            CRLF.writeByte(13);
-            CRLF.writeByte(10);
-            this.host = host;
-            this.port = port;
-            this.resource = resource;
-        }
-
-        public override function close():void
-        {
-            this.input = null;
-            this.output = null;
-            this.stripped = false;
-            socket.close()
-        }
-
-    	public override function peek():Boolean
-    	{
-			if(socket.connected)
-			{
-				trace("Bytes remained:" + socket.bytesAvailable);
-				return socket.bytesAvailable>0;
-			}
-			return false;
-		}
-
-        public override function read(buf:ByteArray, off:int, len:int):int
-        {
-            var n1:int = 0, n2:int = 0, n3:int = 0, n4:int = 0, cidx:int = 2;
-            var chunkSize:ByteArray = new ByteArray();
-
-            try
-            {
-                while (!stripped)
-                {
-                    n1 = n2;
-                    n2 = n3;
-                    n3 = n4;
-                    n4 = input.readByte();
-                    if ((n1 == 13) && (n2 == 10) && (n3 == 13) && (n4 == 10))
-                    {
-                        stripped = true;
-                    }
-                }
-
-                // read chunk size
-                if (bytesInChunk == 0)
-                {
-                    n1 = input.readByte();
-                    n2 = input.readByte();
-
-                    chunkSize.writeByte(n1);
-                    chunkSize.writeByte(n2);
-
-                    while (!((n1 == 13) && (n2 == 10)))
-                    {
-                        n1 = n2;
-                        n2 = input.readByte();
-                        chunkSize.writeByte(n2);
-                    }
-
-                    bytesInChunk = parseInt(chunkSize.toString(), 16);
-                }
-
-                input.readBytes(buf, off, len);
-                debugBuffer(buf);
-                bytesInChunk -= len;
-
-                if (bytesInChunk == 0)
-                {
-                    // advance the : "\r\n"
-                    input.readUTFBytes(2);
-                }
-                return len;
-            }
-            catch (e:EOFError)
-            {
-                trace(e);
-                throw new TTransportError(TTransportError.UNKNOWN, "No more data available.");
-            }
-            catch (e:Error)
-            {
-                trace(e);
-                // WTF??
-                throw new TTransportError(TTransportError.UNKNOWN, "Bad IO error:" + e);
-            }
-            return 0;
-        }
-
-        public function debugBuffer(buf:ByteArray):void
-        {
-            var debug:String = "BUFFER >>";
-            var i:int;
-            for (i = 0; i < buf.length; i++)
-            {
-                debug += buf[i] as int;
-                debug += " ";
-            }
-
-            trace(debug + "<<");
-        }
-
-        public override function write(buf:ByteArray, off:int, len:int):void
-        {
-            obuffer.writeBytes(buf, off, len);
-        }
-
-        public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
-        {
-            this.eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
-        }
-
-        public override function open():void
-        {
-            this.socket = new Socket();
-            this.socket.addEventListener(Event.CONNECT, socketConnected);
-            this.socket.addEventListener(IOErrorEvent.IO_ERROR, socketError);
-            this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socketSecurityError);
-            this.socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
-            this.socket.connect(host, port);
-        }
-
-        public function socketConnected(event:Event):void
-        {
-            this.output = this.socket;
-            this.input = this.socket;
-            this.output.writeUTF("CONNECT " + resource + " HTTP/1.1\n" + "Host: " + host + ":" + port + "\r\n" + "User-Agent: Thrift/AS3\r\n" + "Transfer-Encoding: chunked\r\n" + "content-type: application/x-thrift\r\n" + "Accept: */*\r\n\r\n");
-            this.eventDispatcher.dispatchEvent(event);
-        }
-
-        public function socketError(event:IOErrorEvent):void
-        {
-            trace("Error Connecting:" + event);
-            this.close();
-            if (ioCallback == null)
-            {
-                return;
-            }
-            ioCallback(new TTransportError(TTransportError.UNKNOWN, "IOError: " + event.text));
-            this.eventDispatcher.dispatchEvent(event);
-        }
-
-        public function socketSecurityError(event:SecurityErrorEvent):void
-        {
-            trace("Security Error Connecting:" + event);
-            this.close();
-            this.eventDispatcher.dispatchEvent(event);
-        }
-
-        public function socketDataHandler(event:ProgressEvent):void
-        {
-        	trace("Got Data call:" +ioCallback);
-            if (ioCallback != null)
-            {
-                ioCallback(null);
-            };
-            this.eventDispatcher.dispatchEvent(event);
-        }
-
-        public override function flush(callback:Function = null):void
-        {
-            trace("set callback:" + callback);
-            this.ioCallback = callback;
-            this.output.writeUTF(this.obuffer.length.toString(16));
-            this.output.writeBytes(CRLF);
-            this.output.writeBytes(this.obuffer);
-            this.output.writeBytes(CRLF);
-            this.socket.flush();
-            // waiting for  new Flex sdk 3.5
-            //this.obuffer.clear();
-            this.obuffer = new ByteArray();
-        }
-
-        public override function isOpen():Boolean
-        {
-            return (this.socket == null ? false : this.socket.connected);
-        }
-
-    }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/transport/THttpClient.as b/lib/as3/src/org/apache/thrift/transport/THttpClient.as
deleted file mode 100644
index 435f911..0000000
--- a/lib/as3/src/org/apache/thrift/transport/THttpClient.as
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.transport {
-
-  import flash.errors.EOFError;
-  import flash.events.Event;
-  import flash.events.IOErrorEvent;
-  import flash.events.SecurityErrorEvent;
-  import flash.net.URLLoader;
-  import flash.net.URLLoaderDataFormat;
-  import flash.net.URLRequest;
-  import flash.net.URLRequestMethod;
-  import flash.system.Capabilities;
-  import flash.utils.ByteArray;
-  
-  /**
-   * HTTP implementation of the TTransport interface. Used for working with a
-   * Thrift web services implementation.
-   */
-  public class THttpClient extends TTransport {
-
-    private var request_:URLRequest = null;
-    private var requestBuffer_:ByteArray = new ByteArray();
-    private var responseBuffer_:ByteArray = null;
-    private var traceBuffers_:Boolean = Capabilities.isDebugger;
-
-    
-    public function getBuffer():ByteArray {
-      return requestBuffer_;
-    }
-    
-    public function THttpClient(request:URLRequest, traceBuffers:Boolean=true):void {
-      request.contentType = "application/x-thrift";
-      request_ = request;
-      if(traceBuffers == false) {
-        traceBuffers_ = traceBuffers;
-      }
-    }
-    
-    public override function open():void {
-    }
-
-    public override function close():void {
-    }
- 
-    public override function isOpen():Boolean {
-      return true;
-    }
-    
-    public override function read(buf:ByteArray, off:int, len:int):int {
-      if (responseBuffer_ == null) {
-        throw new TTransportError(TTransportError.UNKNOWN, "Response buffer is empty, no request.");
-      }
-        try {
-            responseBuffer_.readBytes(buf, off, len);
-            if (traceBuffers_) {
-              dumpBuffer(buf, "READ");
-            }
-            return len;
-          }
-          catch (e:EOFError) {
-            if (traceBuffers_) {
-              dumpBuffer(requestBuffer_, "FAILED-RESPONSE-REQUEST");
-              dumpBuffer(responseBuffer_, "FAILED-RESPONSE");
-            }
-            throw new TTransportError(TTransportError.UNKNOWN, "No more data available.");
-        }
-        return 0;
-    }
-
-    public override function write(buf:ByteArray, off:int, len:int):void {
-      requestBuffer_.writeBytes(buf, off, len);
-    }
-
-    public override function flush(callback:Function=null):void {
-      var loader:URLLoader = new URLLoader();
-      if (callback != null) {
-        loader.addEventListener(Event.COMPLETE, function(event:Event):void {
-         responseBuffer_ = URLLoader(event.target).data;
-         if (traceBuffers_) {
-           dumpBuffer(responseBuffer_, "RESPONSE_BUFFER");
-         }
-         callback(null);
-         responseBuffer_ = null;
-        });
-        loader.addEventListener(IOErrorEvent.IO_ERROR, function(event:IOErrorEvent):void {
-          callback(new TTransportError(TTransportError.UNKNOWN, "IOError: " + event.text));
-          responseBuffer_ = null;
-        });
-        loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function(event:SecurityErrorEvent):void {
-          callback(new TTransportError(TTransportError.UNKNOWN, "SecurityError: " + event.text));
-          responseBuffer_ = null;
-        });
-      }
-      request_.method = URLRequestMethod.POST;
-      loader.dataFormat = URLLoaderDataFormat.BINARY;
-      requestBuffer_.position = 0;
-      request_.data = requestBuffer_;
-      loader.load(request_);
-    }
-
-    private function dumpBuffer(buf:ByteArray, prefix:String):String {
-      var debugString : String = prefix + " BUFFER ";
-      if (buf != null) {
-        debugString += "length: " + buf.length + ", ";
-        for (var i : int = 0; i < buf.length; i++) {
-          debugString += "[" + buf[i].toString(16) + "]";
-        }
-      } else {
-        debugString = "null";
-      }
-      trace(debugString);
-      return debugString;
-    }
-
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/transport/TSocket.as b/lib/as3/src/org/apache/thrift/transport/TSocket.as
deleted file mode 100644
index c60d711..0000000
--- a/lib/as3/src/org/apache/thrift/transport/TSocket.as
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *		http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.transport
-{
-
-  import flash.events.EventDispatcher;
-  import flash.events.Event;
-  import flash.events.IOErrorEvent;
-  import flash.events.ProgressEvent;
-  import flash.events.SecurityErrorEvent;
-  import flash.errors.EOFError;
-  import flash.errors.IOError;
-  import flash.net.URLLoader;
-  import flash.net.URLLoaderDataFormat;
-  import flash.net.URLRequest;
-  import flash.net.URLRequestMethod;
-  import flash.utils.IDataInput;
-  import flash.utils.IDataOutput;
-  import flash.utils.ByteArray;
-  import flash.net.Socket;
-
-
-  /**
-   * Socket implementation of the TTransport interface. Used for working with a
-   * Thrift Socket Server based implementations.
-   */
-
-  public class TSocket extends TTransport
-  {
-    private var socket:Socket = null;
-
-    private var host:String;
-
-    private var port:int;
-
-    private var obuffer:ByteArray = new ByteArray();
-
-    private var input:IDataInput;
-
-    private var output:IDataOutput;
-
-    private var ioCallback:Function = null;
-
-    private var eventDispatcher:EventDispatcher = new EventDispatcher();
-
-    public function TSocket(host:String, port:int):void
-    {
-      this.host = host;
-      this.port = port;
-    }
-
-    public override function close():void
-    {
-      this.input = null;
-      this.output = null;
-      socket.close()
-    }
-
-    public override function peek():Boolean
-    {
-      if(socket.connected)
-      {
-        trace("Bytes remained:" + socket.bytesAvailable);
-        return socket.bytesAvailable>0;
-      }
-      return false;
-    }
-
-    public override function read(buf:ByteArray, off:int, len:int):int
-    {
-      var n1:int = 0, n2:int = 0, n3:int = 0, n4:int = 0, cidx:int = 2;
-      var chunkSize:ByteArray = new ByteArray();
-
-      try
-      {
-        input.readBytes(buf, off, len);
-        return len;
-      }
-      catch (e:EOFError)
-      {
-        trace(e);
-        throw new TTransportError(TTransportError.END_OF_FILE, "No more data available.");
-      }
-      catch (e:IOError)
-      {
-        trace(e);
-        if(isOpen())
-        {
-          throw new TTransportError(TTransportError.UNKNOWN, "IO error while reading: " + e);
-        }
-        else
-        {
-          throw new TTransportError(TTransportError.NOT_OPEN, "Socket seem not to be opened: " + e);
-    	}
-      }
-      catch (e:Error)
-      {
-        trace(e);
-        throw new TTransportError(TTransportError.UNKNOWN, "Bad IO error: " + e);
-      }
-      return 0;
-    }
-
-    public override function write(buf:ByteArray, off:int, len:int):void
-    {
-      obuffer.writeBytes(buf, off, len);
-    }
-
-    public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void
-    {
-      this.eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
-    }
-    
-    public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
-    {
-      this.eventDispatcher.removeEventListener(type, listener, useCapture);
-    }
-
-    public override function open():void
-    {
-      this.socket = new Socket();
-      this.socket.addEventListener(Event.CONNECT, socketConnected);
-      this.socket.addEventListener(IOErrorEvent.IO_ERROR, socketError);
-      this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socketSecurityError);
-      this.socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
-      this.socket.connect(host, port);
-    }
-
-    public function socketConnected(event:Event):void
-    {
-      this.output = this.socket;
-      this.input = this.socket;
-      this.eventDispatcher.dispatchEvent(event);
-    }
-
-    public function socketError(event:IOErrorEvent):void
-    {
-      trace("Error Connecting:" + event);
-      this.close();
-      if (ioCallback == null)
-      {
-        return;
-      }
-      ioCallback(new TTransportError(TTransportError.UNKNOWN, "IOError: " + event.text));
-      this.eventDispatcher.dispatchEvent(event);
-    }
-
-    public function socketSecurityError(event:SecurityErrorEvent):void
-    {
-      trace("Security Error Connecting:" + event);
-      this.close();
-      this.eventDispatcher.dispatchEvent(event);
-    }
-
-    public function socketDataHandler(event:ProgressEvent):void
-    {
-      if (ioCallback != null)
-      {
-        ioCallback(null);
-      }
-      this.eventDispatcher.dispatchEvent(event);
-    }
-
-    public override function flush(callback:Function = null):void
-    {
-      this.ioCallback = callback;
-      this.output.writeBytes(this.obuffer);
-      this.socket.flush();
-      this.obuffer.clear();
-    }
-
-    public override function isOpen():Boolean
-    {
-      return (this.socket == null ? false : this.socket.connected);
-    }
-  }
-}
diff --git a/lib/as3/src/org/apache/thrift/transport/TTransport.as b/lib/as3/src/org/apache/thrift/transport/TTransport.as
deleted file mode 100644
index 83160af..0000000
--- a/lib/as3/src/org/apache/thrift/transport/TTransport.as
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.transport {
-  
-  import flash.utils.ByteArray;
-  import org.apache.thrift.AbstractMethodError;
-  
-  public class TTransport {
-
-    /**
-     * Queries whether the transport is open.
-       *
-     * @return True if the transport is open.
-     */
-    public function isOpen():Boolean {
-      throw new AbstractMethodError();
-    }
-    
-    /**
-     * Is there more data to be read?
-     *
-     * @return True if the remote side is still alive and feeding us
-     */
-    public function peek():Boolean {
-      return isOpen();
-    }
-
-    /**
-     * Opens the transport for reading/writing.
-     *
-     * @throws TTransportException if the transport could not be opened
-     */
-    public function open():void {
-      throw new AbstractMethodError();
-    }
-
-    /**
-     * Closes the transport.
-     */
-    public function close():void {
-      throw new AbstractMethodError();
-    };
-
-    /**
-     * Reads up to len bytes into buffer buf, starting att offset off.
-     *
-     * @param buf Array to read into
-     * @param off Index to start reading at
-     * @param len Maximum number of bytes to read
-     * @return The number of bytes actually read
-     * @throws TTransportException if there was an error reading data
-     */
-     public function read(buf:ByteArray, off:int, len:int):int {
-      throw new AbstractMethodError();
-     }
-
-    /**
-     * Guarantees that all of len bytes are actually read off the transport.
-     *
-     * @param buf Array to read into
-     * @param off Index to start reading at
-     * @param len Maximum number of bytes to read
-     * @return The number of bytes actually read, which must be equal to len
-     * @throws TTransportException if there was an error reading data
-     */
-    public function readAll(buf:ByteArray, off:int, len:int):int {
-      var got:int = 0;
-        var ret:int = 0;
-        while (got < len) {
-            ret = read(buf, off+got, len-got);
-            if (ret <= 0) {
-              throw new TTransportError(TTransportError.UNKNOWN, "Cannot read. Remote side has closed. Tried to read " + len + " bytes, but only got " + got + " bytes.");
-            }
-            got += ret;
-          }
-        return got;
-      }
-
-    /**
-     * Writes the buffer to the output
-     *
-     * @param buf The output data buffer
-     * @throws TTransportException if an error occurs writing data
-     */
-    public function writeAll(buf:ByteArray):void {
-      write(buf, 0, buf.length);
-    }
-
-    /**
-     * Writes up to len bytes from the buffer.
-     *
-     * @param buf The output data buffer
-     * @param off The offset to start writing from
-     * @param len The number of bytes to write
-     * @throws TTransportException if there was an error writing data
-     */
-    public function write(buf:ByteArray, off:int, len:int):void {
-      throw new AbstractMethodError();
-    }
-
-    /**
-     * Flush any pending data out of a transport buffer.
-     *
-     * @throws TTransportException if there was an error writing out data.
-     */
-    public function flush(callback:Function=null):void {
-      throw new AbstractMethodError();
-    }
-  }
-}
\ No newline at end of file
diff --git a/lib/as3/src/org/apache/thrift/transport/TTransportError.as b/lib/as3/src/org/apache/thrift/transport/TTransportError.as
deleted file mode 100644
index 10a6f62..0000000
--- a/lib/as3/src/org/apache/thrift/transport/TTransportError.as
+++ /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.
- */
- 
-package org.apache.thrift.transport {
-  
-  import org.apache.thrift.TError;
-
-  public class TTransportError extends TError {
-    
-    public static const UNKNOWN:int = 0;
-    public static const NOT_OPEN:int = 1;
-    public static const ALREADY_OPEN:int = 2;
-    public static const TIMED_OUT:int = 3;
-    public static const END_OF_FILE:int = 4;
-  
-    public function TTransportError(error:int = UNKNOWN, message:String = "") {
-      super(message, error);
-    }
-    
-  }
-}
\ No newline at end of file
diff --git a/lib/c_glib/CMakeLists.txt b/lib/c_glib/CMakeLists.txt
index 3a1f188..2bee9e4 100644
--- a/lib/c_glib/CMakeLists.txt
+++ b/lib/c_glib/CMakeLists.txt
@@ -59,6 +59,17 @@
     src/thrift/c_glib/server/thrift_simple_server.c
 )
 
+set(thrift_c_glib_zlib_SOURCES
+    src/thrift/c_glib/thrift.c
+    src/thrift/c_glib/thrift_struct.c
+    src/thrift/c_glib/thrift_application_exception.c
+    src/thrift/c_glib/thrift_configuration.c
+    src/thrift/c_glib/transport/thrift_transport.c
+    src/thrift/c_glib/transport/thrift_transport_factory.c
+    src/thrift/c_glib/transport/thrift_zlib_transport.c
+    src/thrift/c_glib/transport/thrift_zlib_transport_factory.c   
+)
+
 # If OpenSSL is not found just ignore the OpenSSL stuff
 if(WITH_OPENSSL)
     list(APPEND thrift_c_glib_SOURCES
@@ -73,7 +84,15 @@
 include(ThriftMacros)
 
 ADD_LIBRARY_THRIFT(thrift_c_glib ${thrift_c_glib_SOURCES})
-TARGET_LINK_LIBRARIES_THRIFT(thrift_c_glib ${SYSLIBS})
+TARGET_LINK_LIBRARIES_THRIFT(thrift_c_glib PUBLIC ${SYSLIBS})
+
+# If Zlib is not found just ignore the Zlib stuff
+if(WITH_ZLIB)
+    include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
+    ADD_LIBRARY_THRIFT(thrift_c_glib_zlib ${thrift_c_glib_zlib_SOURCES})
+    TARGET_LINK_LIBRARIES_THRIFT(thrift_c_glib_zlib ${SYSLIBS} ${ZLIB_LIBRARIES})
+    TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thrift_c_glib_zlib thrift_c_glib)
+endif()
 
 # Install the headers
 install(DIRECTORY "src/thrift" DESTINATION "${INCLUDE_INSTALL_DIR}"
diff --git a/lib/c_glib/Makefile.am b/lib/c_glib/Makefile.am
index 7619fb4..b2061bb 100755
--- a/lib/c_glib/Makefile.am
+++ b/lib/c_glib/Makefile.am
@@ -49,6 +49,7 @@
                               src/thrift/c_glib/transport/thrift_transport_factory.c \
                               src/thrift/c_glib/transport/thrift_buffered_transport_factory.c \
                               src/thrift/c_glib/transport/thrift_framed_transport_factory.c \
+                              src/thrift/c_glib/transport/thrift_zlib_transport_factory.c \
                               src/thrift/c_glib/transport/thrift_socket.c \
                               src/thrift/c_glib/transport/thrift_ssl_socket.c \
                               src/thrift/c_glib/transport/thrift_server_transport.c \
@@ -56,12 +57,13 @@
                               src/thrift/c_glib/transport/thrift_buffered_transport.c \
                               src/thrift/c_glib/transport/thrift_fd_transport.c \
                               src/thrift/c_glib/transport/thrift_framed_transport.c \
+                              src/thrift/c_glib/transport/thrift_zlib_transport.c \
                               src/thrift/c_glib/transport/thrift_memory_buffer.c \
                               src/thrift/c_glib/server/thrift_server.c \
                               src/thrift/c_glib/server/thrift_simple_server.c
 
 libthrift_c_glib_la_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) -I$(top_builddir)/lib/c_glib/src/thrift
-libthrift_c_glib_la_LDFLAGS = $(AM_LDFLAGS) $(GLIB_LIBS) $(GOBJECT_LIBS)  $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) 
+libthrift_c_glib_la_LDFLAGS = $(AM_LDFLAGS) $(GLIB_LIBS) $(GOBJECT_LIBS)  $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) $(ZLIB_LDFLAGS) $(ZLIB_LIBS)
 
 include_thriftdir = $(includedir)/thrift/c_glib
 include_thrift_HEADERS = \
@@ -87,6 +89,7 @@
 include_transport_HEADERS = src/thrift/c_glib/transport/thrift_buffered_transport.h \
                             src/thrift/c_glib/transport/thrift_fd_transport.h \
                             src/thrift/c_glib/transport/thrift_framed_transport.h \
+                            src/thrift/c_glib/transport/thrift_zlib_transport.h \
                             src/thrift/c_glib/transport/thrift_memory_buffer.h \
                             src/thrift/c_glib/transport/thrift_server_socket.h \
                             src/thrift/c_glib/transport/thrift_server_transport.h \
@@ -96,7 +99,8 @@
                             src/thrift/c_glib/transport/thrift_transport.h \
                             src/thrift/c_glib/transport/thrift_transport_factory.h \
                             src/thrift/c_glib/transport/thrift_buffered_transport_factory.h \
-                            src/thrift/c_glib/transport/thrift_framed_transport_factory.h
+                            src/thrift/c_glib/transport/thrift_framed_transport_factory.h \
+                            src/thrift/c_glib/transport/thrift_zlib_transport_factory.h
 
 include_serverdir = $(include_thriftdir)/server
 include_server_HEADERS = src/thrift/c_glib/server/thrift_server.h \
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
index 1abd615..74def29 100644
--- a/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_server_socket.c
@@ -72,6 +72,8 @@
     g_set_error (error, THRIFT_SERVER_SOCKET_ERROR,
                  THRIFT_SERVER_SOCKET_ERROR_SETSOCKOPT,
                  "unable to set SO_REUSEADDR - %s", strerror(errno));
+    close (tsocket->sd);
+    tsocket->sd = THRIFT_INVALID_SOCKET;
     return FALSE;
   }
 
@@ -90,6 +92,8 @@
                    THRIFT_SERVER_SOCKET_ERROR_BIND,
                    "failed to bind to path %s: - %s",
                    tsocket->path, strerror(errno));
+      close (tsocket->sd);
+      tsocket->sd = THRIFT_INVALID_SOCKET;
       return FALSE;
     }
   }
@@ -108,6 +112,8 @@
                    THRIFT_SERVER_SOCKET_ERROR_BIND,
                    "failed to bind to port %d - %s",
                    tsocket->port, strerror(errno));
+      close (tsocket->sd);
+      tsocket->sd = THRIFT_INVALID_SOCKET;
       return FALSE;
     }
   }
@@ -120,7 +126,6 @@
                    THRIFT_SERVER_SOCKET_ERROR_BIND,
                    "failed to listen to path %s: - %s",
                    tsocket->path, strerror(errno));
-      return FALSE;
     }
     else
     {
@@ -128,8 +133,10 @@
                    THRIFT_SERVER_SOCKET_ERROR_LISTEN,
                    "failed to listen to port %d - %s",
                    tsocket->port, strerror(errno));
-      return FALSE;
     }
+    close (tsocket->sd);
+    tsocket->sd = THRIFT_INVALID_SOCKET;
+    return FALSE;
   }
 
   return TRUE;
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport.c
new file mode 100644
index 0000000..32f1ba2
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport.c
@@ -0,0 +1,783 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/transport/thrift_transport.h>
+#include <thrift/c_glib/transport/thrift_zlib_transport.h>
+
+#define DEFAULT_URBUF_SIZE      128
+#define DEFAULT_CRBUF_SIZE      1024
+#define DEFAULT_UWBUF_SIZE      128
+#define DEFAULT_CWBUF_SIZE      1024
+#define MIN_DIRECT_DEFLATE_SIZE 32
+
+/* object properties */
+enum _ThriftZlibTransportProperties
+{
+  PROP_0,
+  PROP_THRIFT_ZLIB_TRANSPORT_TRANSPORT,
+  PROP_THRIFT_ZLIB_TRANSPORT_URBUF_SIZE,
+  PROP_THRIFT_ZLIB_TRANSPORT_CRBUF_SIZE,
+  PROP_THRIFT_ZLIB_TRANSPORT_UWBUF_SIZE,
+  PROP_THRIFT_ZLIB_TRANSPORT_CWBUF_SIZE,
+  PROP_THRIFT_ZLIB_TRANSPORT_COMP_LEVEL,
+  PROP_THRIFT_ZLIB_TRANSPORT_CONFIGURATION,
+  PROP_THRIFT_ZLIB_TRANSPORT_REMAINING_MESSAGE_SIZE,
+  PROP_THRIFT_ZLIB_TRANSPORT_KNOW_MESSAGE_SIZE
+};
+
+G_DEFINE_TYPE (ThriftZlibTransport, thrift_zlib_transport, THRIFT_TYPE_TRANSPORT)
+
+/*! READING STRATEGY
+ * We have two buffers for reading: one containing the compressed data (crbuf)
+ * and one containing the uncompressed data (urbuf).  When read is called,
+ * we repeat the following steps until we have satisfied the request:
+ *  - Copy data from urbuf into the caller's buffer.
+ *  - If we had enough, return.
+ *  - If urbuf is empty, read some data into it from the underlying transport.
+ *  - Inflate data from crbuf into urbuf.
+ *
+ *  In standalone object, we set input_end to true when inflate returns
+ *  Z_STREAM_END.  This allows to make sure that a checksum was verified.
+ */
+int
+thrift_zlib_transport_read_avail (ThriftTransport *transport)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  return t->urbuf_size - t->rstream->avail_out - t->urpos;
+}
+
+/* overrides thrift_transport_is_open */
+gboolean
+thrift_zlib_transport_is_open (ThriftTransport *transport)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  return (thrift_zlib_transport_read_avail (transport) > 0) || \
+         (t->rstream->avail_in > 0) || THRIFT_TRANSPORT_GET_CLASS (t->transport)->is_open (t->transport);
+}
+
+/* overrides thrift_transport_peek */
+gboolean
+thrift_zlib_transport_peek (ThriftTransport *transport, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  return (thrift_zlib_transport_read_avail (transport) > 0) || \
+         (t->rstream->avail_in > 0) || THRIFT_TRANSPORT_GET_CLASS (t->transport)->peek (t->transport, error);
+}
+
+/* implements thrift_transport_open */
+gboolean
+thrift_zlib_transport_open (ThriftTransport *transport, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  return THRIFT_TRANSPORT_GET_CLASS (t->transport)->open (t->transport, error);
+}
+
+/* implements thrift_transport_close */
+gboolean
+thrift_zlib_transport_close (ThriftTransport *transport, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  return THRIFT_TRANSPORT_GET_CLASS (t->transport)->close (t->transport, error);
+}
+
+gint32
+thrift_zlib_transport_read_from_zlib(ThriftTransport *transport, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  gint32 got = 0;
+  int zlib_rv = Z_OK;
+
+  if (t->input_ended) {
+    /* If input end return error */
+    return -1;           
+  }
+
+  /* If we don't have any more compressed data available,
+   * read some from the underlying transport.
+   */
+    got = THRIFT_TRANSPORT_GET_CLASS(t->transport)->read (t->transport, t->crbuf, 1, error);
+    if (got < 0) {
+      return -1;
+    }
+    t->rstream->next_in = t->crbuf;
+    t->rstream->avail_in = got;
+
+    /* We have some compressed data now.  Uncompress it. */
+    zlib_rv = inflate (t->rstream, Z_SYNC_FLUSH);
+    if (zlib_rv == Z_STREAM_END) {
+      t->input_ended = TRUE;
+      inflateEnd(t->rstream);
+      return 0;
+    } else { 
+     if (zlib_rv != Z_OK) {
+        g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE,
+                     "zlib error: %d (status = %s)", zlib_rv, t->rstream->msg);
+        /* It must to return error */
+        return -1;
+     } else {
+       return 1;
+     }
+   }
+  
+  /* return 1 to continue to read */
+  return 1;
+}
+
+/* implements thrift_transport_read */
+gint32
+thrift_zlib_transport_read_slow (ThriftTransport *transport, gpointer buf,
+                            GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  gint *buf_tmp = buf;
+  gint32 need = 1;
+  gint give;
+  gint32 ret = 0;
+
+  while(TRUE)
+  {
+    if ((guint32)thrift_zlib_transport_read_avail (transport) < 1) {
+      give = thrift_zlib_transport_read_avail (transport);
+    } else {
+      give = need;
+    }
+    memcpy (buf_tmp, t->urbuf+t->urpos, give);
+    if (give > need) {
+      need = 0;
+    } else {
+      need -= give;
+    }
+    buf_tmp += give;
+    t->urpos += give;
+
+    /* If they were satisfied, we are done. */
+    if (need == 0) {
+      return 1;
+    }
+    
+    /* If we will need to read from the underlying transport to get more data,
+     * but we already have some data available, return it now.  Reading from
+     * the underlying transport may block, and read() is only allowed to block
+     * when no data is available.
+     */
+    if (need < 1 && t->rstream->avail_in == 0) {
+      return give;
+    }
+
+    /* If we get to this point, we need to get some more data. */
+
+    /* If zlib has reported the end of a stream, we can't really do any more. */
+    if (t->input_ended) {
+      return 1;
+    }
+
+    /* The uncompressed read buffer is empty, so reset the stream fields. */
+    t->rstream->next_out = t->urbuf;
+    t->rstream->avail_out = t->urbuf_size;
+    t->urpos = 0;
+
+    /* Call inflate() to uncompress some more data. */
+    if ((ret = thrift_zlib_transport_read_from_zlib(transport, error)) == 0) {
+      /* no data available from underlying transport */
+      return 1;
+    } else {
+      if (ret < 0) {
+        return -1;
+      }
+    }
+  }
+  /* Okay.  The read buffer should have whatever we can give it now. */
+  /* Loop back to the start and try to give some more. */
+}
+
+gint32
+thrift_zlib_transport_read (ThriftTransport *transport, gpointer buf,
+                             guint32 len, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport);
+  guint32 i;
+  gint32 ret;
+
+  if (!ttc->checkReadBytesAvailable (transport, len, error)){
+    return -1;
+  }
+
+  for (i=0; i < len; i=i+ret) {
+    if ((ret = thrift_zlib_transport_read_slow (transport, ((char*)buf)+i, error)) < 0) {
+      return ret;
+    }
+    if (t->input_ended)
+      break;
+  }
+
+  return len;
+}
+
+/* implements thrift_transport_read_end 
+ * called when read is complete. nothing to do on our end. */
+gboolean
+thrift_zlib_transport_read_end (ThriftTransport *transport, GError **error)
+{
+  /* satisfy -Wall */
+  THRIFT_UNUSED_VAR (error);
+  THRIFT_UNUSED_VAR (transport);
+
+  return TRUE;
+}
+
+gboolean
+thrift_zlib_transport_flush_to_zlib (ThriftTransport *transport, const gint8* buf,
+                                     gint len, gint flush, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  t->wstream->next_in = (guchar*)buf;
+  t->wstream->avail_in = len;
+
+  while (TRUE) {
+    if ((flush == Z_NO_FLUSH || flush == Z_BLOCK) && t->wstream->avail_in  == 0) {
+      break;
+    }
+
+    /* If our output buffer is full, flush to the underlying transport. */
+    if (t->wstream->avail_out == 0) {
+      THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
+                                                        t->cwbuf, t->cwbuf_size, error);
+      t->wstream->next_out = t->cwbuf;
+      t->wstream->avail_out = t->cwbuf_size;
+      break;
+    }
+
+    int zlib_rv = deflate(t->wstream, flush);
+
+    if (flush == Z_FINISH && zlib_rv == Z_STREAM_END) {
+      if (t->wstream->avail_in != 0) {
+        g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND,
+                     "wstream->avail_in != 0");
+        return FALSE;
+      }
+      deflateEnd(t->wstream);
+      t->output_finished = TRUE;
+      break;
+    }
+
+    if (zlib_rv != Z_OK) {
+      g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND,
+                   "zlib error: %d (status = %s)", zlib_rv, t->wstream->msg);
+      return FALSE;
+    }
+
+    if ((flush == Z_SYNC_FLUSH || flush == Z_FULL_FLUSH) && t->wstream->avail_in ==0
+        && t->wstream->avail_out != 0) {
+      break;
+    }
+  }
+  return TRUE;
+}
+
+/* implements thrift_transport_write 
+ * WRITING STRATEGY
+ * We buffer up small writes before sending them to zlib, so our logic is:
+ * - Is the write big?
+ *   - Send the buffer to zlib.
+ *   - Send this data to zlib.
+ * - Is the write small?
+ *   - Is there insufficient space in the buffer for it?
+ *     - Send the buffer to zlib.
+ *   - Copy the data to the buffer. 
+ *
+ * We have two buffers for writing also: the uncompressed buffer (mentioned
+ * above) and the compressed buffer.  When sending data to zlib we loop over
+ * the following until the source (uncompressed buffer or big write) is empty:
+ * - Is there no more space in the compressed buffer?
+ *   - Write the compressed buffer to the underkying transport.
+ * - Deflate from the source into the compressed buffer. */
+gboolean
+thrift_zlib_transport_write (ThriftTransport *transport,
+                             const gpointer buf,
+                             const guint32 len, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  
+  if (t->output_finished) { 
+    g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND,
+		 "write() called after write_end(): %s",
+		 strerror(errno));
+    return FALSE;
+  }
+
+  /* zlib's "deflate" function has enough logic in it that I think
+   * we're better off (performance-wise) buffering up small writes. */
+  if (len > MIN_DIRECT_DEFLATE_SIZE) {
+    if (!thrift_zlib_transport_flush_to_zlib (transport, (gint8*)t->uwbuf, t->uwpos, Z_NO_FLUSH, error)) {
+      return FALSE;
+    }
+    t->uwpos = 0;
+    if (!thrift_zlib_transport_flush_to_zlib (transport, buf, len, Z_NO_FLUSH, error)) {
+      return FALSE;
+    }
+    return TRUE;
+  } else if (len > 0) {
+    if ((guint32)(t->uwbuf_size - t->uwpos) < len) {
+      if (!thrift_zlib_transport_flush_to_zlib (transport, (gint8*)t->uwbuf, t->uwpos, Z_NO_FLUSH, error)) {
+        return FALSE;
+      }
+      t->uwpos = 0;
+    }
+    memcpy (t->uwbuf + t->uwpos, buf, len);
+    t->uwpos += len;
+    return TRUE;
+  }
+  return FALSE;
+}
+
+gboolean
+thrift_zlib_transport_flush_to_transport (ThriftTransport *transport, gint flush, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+
+  /* write pending data in uwbuf to zlib */
+  if (!thrift_zlib_transport_flush_to_zlib (transport, (gint8*)t->uwbuf, t->uwpos, flush, error)) {
+    return FALSE;
+  }
+  t->uwpos = 0;
+
+  /* write all available data from zlib to the transport */
+  if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write (t->transport,
+                                                    t->cwbuf, (t->cwbuf_size - t->wstream->avail_out),
+                                                    error)) {
+    return FALSE;
+  }
+
+  t->wstream->next_out = t->cwbuf;
+  t->wstream->avail_out = t->cwbuf_size;
+
+  /* flush the transport */
+  if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->flush(t->transport, error)) {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+/* implements thrift_transport_write_end
+ * called when write is complete.  nothing to do on our end. */
+gboolean
+thrift_zlib_transport_write_end (ThriftTransport *transport, GError **error)
+{
+  THRIFT_UNUSED_VAR (error);
+  THRIFT_UNUSED_VAR (transport);
+
+  return TRUE;
+}
+
+/* implements thrift_transport_flush */
+gboolean
+thrift_zlib_transport_flush (ThriftTransport *transport, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  ThriftTransportClass *ttc = THRIFT_TRANSPORT_GET_CLASS (transport);
+
+  if (t->output_finished) {
+    return FALSE;
+  }
+
+  thrift_zlib_transport_flush_to_zlib (transport, (gint8*)t->uwbuf, t->uwpos, Z_NO_FLUSH, error);
+  t->uwpos = 0;
+
+  if (t->wstream->avail_out < 6) {
+    if (!THRIFT_TRANSPORT_GET_CLASS (t->transport)->write(t->transport,
+                                                     t->cwbuf, t->cwbuf_size - t->wstream->avail_out,
+                                                     error)) {
+      return FALSE;
+    }
+    t->wstream->next_out = t->cwbuf;
+    t->wstream->avail_out = t->cwbuf_size;
+  }
+
+   if (!thrift_zlib_transport_flush_to_transport (transport, Z_FULL_FLUSH, error)) {
+    return FALSE;
+  }
+
+  if (!ttc->resetConsumedMessageSize (transport, -1, error)) {
+    return FALSE;
+  }
+  return TRUE; 
+}
+
+gboolean
+thrift_zlib_transport_verify_checksum(ThriftTransport *transport, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  
+  /* If zlib has already reported the end of the stream,
+   * it has verified the checksum. */
+  if (t->input_ended) {
+    return TRUE;
+  }
+
+  /* This should only be called when reading is complete.
+   * If the caller still has unread data, throw an exception. */
+  if (thrift_zlib_transport_read_avail (transport) > 0) {
+    g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE,
+                 "thrift_zlib_transport_verify_checksum() called bufore end of zlib stream.");
+    return FALSE;
+  }
+
+  /* Reset the rsteam fields, in case avail_out is 0.
+   * (Since thrift_zlib_transport_read_avail() is 0, we know there is no unread data in urbuf) */
+  t->rstream->next_out = t->urbuf;
+  t->rstream->avail_out = t->urbuf_size;
+  t->urpos = 0;
+
+  /* Call inflate()
+   * This will set the error if the checksum is bad. */
+  gboolean performed_inflate = thrift_zlib_transport_read_from_zlib (transport, error);
+  if (!performed_inflate) {
+    g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE,
+                 "checksum not available yet in thrift_zlib_transport_verify_checksum ()");
+    return FALSE;
+  }
+
+  /* If input_ended is TRUE now, the checksum has been verified */
+  if (t->input_ended) {
+    return TRUE;
+  }
+
+  /* The caller invoked us before the actual end of the data stream */
+  if (t->rstream->avail_out < (guint)t->urbuf_size) {
+    g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE,
+                 "rstream->avail_out >= urbuf_size");
+    return FALSE;
+  }
+
+  g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_RECEIVE,
+               "thrift_zlib_transport_verify_checksum() called bufore end of zlib stream.");
+  return FALSE;
+}
+
+gboolean
+thrift_zlib_transport_finish(ThriftTransport *transport, GError **error)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (transport);
+  
+  if (t->output_finished) {
+    g_set_error (error, THRIFT_TRANSPORT_ERROR, THRIFT_TRANSPORT_ERROR_SEND,
+		 "finish() called more than once");
+    return FALSE;
+  }
+
+   if (!thrift_zlib_transport_flush_to_transport (transport, Z_FINISH, error)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/* initializes the instance */
+static void
+thrift_zlib_transport_init (ThriftZlibTransport *transport)
+{
+  transport->transport = NULL;
+  transport->urpos = 0;
+  transport->uwpos = 0;
+  transport->input_ended = FALSE;
+  transport->output_finished = FALSE;
+
+  transport->rstream = g_new0 (struct z_stream_s, 1);
+  transport->wstream = g_new0 (struct z_stream_s, 1);
+
+  transport->rstream->zalloc = Z_NULL;
+  transport->wstream->zalloc = Z_NULL;
+  transport->rstream->zfree = Z_NULL;
+  transport->wstream->zfree = Z_NULL;
+  transport->rstream->opaque = Z_NULL;
+  transport->wstream->opaque = Z_NULL;
+
+  transport->rstream->avail_in = 0;
+  transport->wstream->avail_in = 0;
+}
+
+/* destructor */
+static void
+thrift_zlib_transport_finalize (GObject *object)
+{
+  ThriftZlibTransport *t = THRIFT_ZLIB_TRANSPORT (object);
+  inflateEnd (t->rstream);
+  deflateEnd (t->wstream);
+
+  if (t->urbuf != NULL) {
+    g_free (t->urbuf);
+  }
+  if (t->crbuf != NULL) {
+    g_free (t->crbuf);
+  }
+  if (t->uwbuf != NULL) {
+    g_free (t->uwbuf);
+  }
+  if (t->cwbuf != NULL) {
+    g_free (t->cwbuf);
+  }
+  if (t->rstream != NULL) {
+    g_free (t->rstream);
+  }
+  if (t->wstream != NULL) {
+    g_free (t->wstream);
+  }
+}
+
+/* property accessor */
+void
+thrift_zlib_transport_get_property (GObject *object, guint property_id,
+                                    GValue *value, GParamSpec *pspec)
+{
+  ThriftZlibTransport *transport = NULL;
+  ThriftTransport *tt = NULL;
+
+  THRIFT_UNUSED_VAR (pspec);
+
+  transport = THRIFT_ZLIB_TRANSPORT (object);
+  tt = THRIFT_TRANSPORT (object);
+
+  switch (property_id) {
+    case PROP_THRIFT_ZLIB_TRANSPORT_TRANSPORT:
+      g_value_set_object (value, transport->transport);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_URBUF_SIZE:
+      g_value_set_int (value, transport->urbuf_size);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_CRBUF_SIZE:
+      g_value_set_int (value, transport->crbuf_size);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_UWBUF_SIZE:
+      g_value_set_int (value, transport->uwbuf_size);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_CWBUF_SIZE:
+      g_value_set_int (value, transport->cwbuf_size);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_COMP_LEVEL:
+      g_value_set_int (value, transport->comp_level);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_CONFIGURATION:
+      g_value_set_object (value, tt->configuration);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_REMAINING_MESSAGE_SIZE:
+      g_value_set_long (value, tt->remainingMessageSize_);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_KNOW_MESSAGE_SIZE:
+      g_value_set_long (value, tt->knowMessageSize_);
+      break;
+    default:
+      break;
+  }
+}
+
+/* property mutator */
+void
+thrift_zlib_transport_set_property (GObject *object, guint property_id,
+                                    const GValue *value, GParamSpec *pspec)
+{
+  ThriftZlibTransport *transport = NULL;
+  ThriftTransport *tt = NULL;
+
+  THRIFT_UNUSED_VAR (pspec);
+
+  transport = THRIFT_ZLIB_TRANSPORT (object);
+  tt = THRIFT_TRANSPORT (object);
+
+  switch (property_id) {
+    case PROP_THRIFT_ZLIB_TRANSPORT_TRANSPORT:
+      transport->transport = g_value_get_object (value);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_URBUF_SIZE:
+      transport->urbuf_size = g_value_get_int (value);
+      transport->urbuf = g_new0 (guint8, transport->urbuf_size);
+      transport->rstream->next_out = transport->urbuf;
+      transport->rstream->avail_out = transport->urbuf_size;
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_CRBUF_SIZE:
+      transport->crbuf_size = g_value_get_int (value);
+      transport->crbuf = g_new0 (guint8, transport->crbuf_size);
+      transport->rstream->next_in = transport->crbuf;
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_UWBUF_SIZE:
+      transport->uwbuf_size = g_value_get_int (value);
+      transport->uwbuf = g_new0 (guint8, transport->uwbuf_size);
+      transport->wstream->next_in = transport->uwbuf;
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_CWBUF_SIZE:
+      transport->cwbuf_size = g_value_get_int (value);
+      transport->cwbuf = g_new0 (guint8, transport->cwbuf_size);
+      transport->wstream->next_out = transport->cwbuf;
+      transport->wstream->avail_out = transport->cwbuf_size;
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_COMP_LEVEL:
+      transport->comp_level = g_value_get_int (value);
+      if(inflateInit(transport->rstream) != Z_OK) {
+         printf("inflate_init fail \n");
+         return;
+      }
+      if(deflateInit (transport->wstream, transport->comp_level) != Z_OK) {
+	 printf("deflate init fail\n");
+         return;
+      }
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_CONFIGURATION:
+      tt->configuration = g_value_dup_object (value);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_REMAINING_MESSAGE_SIZE:
+      tt->remainingMessageSize_ = g_value_get_long (value);
+      break;
+    case PROP_THRIFT_ZLIB_TRANSPORT_KNOW_MESSAGE_SIZE:
+      tt->knowMessageSize_ = g_value_get_long (value);
+      break;
+    default:
+      break;
+  }
+}
+
+/* initialize the class */
+static void
+thrift_zlib_transport_class_init (ThriftZlibTransportClass *cls)
+{
+  ThriftTransportClass *ttc;
+  GObjectClass *gobject_class;
+  GParamSpec *param_spec;
+
+  ttc = THRIFT_TRANSPORT_CLASS (cls);
+  gobject_class = G_OBJECT_CLASS (cls);
+  param_spec = NULL;
+
+  /* setup accessors and mutators */
+  gobject_class->get_property = thrift_zlib_transport_get_property;
+  gobject_class->set_property = thrift_zlib_transport_set_property;
+  
+  param_spec = g_param_spec_object ("transport", "transport (construct)",
+                                    "Thrift transport",
+                                    THRIFT_TYPE_TRANSPORT,
+                                    G_PARAM_CONSTRUCT_ONLY |
+                                    G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_TRANSPORT,
+                                   param_spec);
+
+  param_spec = g_param_spec_int ("urbuf_size", "urbuf_size (construct)",
+                                 "Uncompressed buffer size for reading",
+                                 0, /* min */
+                                 G_MAXINT, /* max */
+                                 DEFAULT_URBUF_SIZE, /* default value */
+                                 G_PARAM_CONSTRUCT_ONLY |
+                                 G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_URBUF_SIZE,
+                                   param_spec);
+
+  param_spec = g_param_spec_int ("crbuf_size", "crbuf_size (construct)",
+                                 "Compressed buffer size for reading",
+                                 0, /* min */
+                                 G_MAXINT, /* max */
+                                 DEFAULT_CRBUF_SIZE, /* default value */
+                                 G_PARAM_CONSTRUCT_ONLY |
+                                 G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_CRBUF_SIZE,
+                                   param_spec);
+
+  param_spec = g_param_spec_int ("uwbuf_size", "uwbuf_size (construct)",
+                                 "Uncompressed buffer size for writing",
+                                 MIN_DIRECT_DEFLATE_SIZE, /* min */
+                                 G_MAXINT, /* max */
+                                 DEFAULT_UWBUF_SIZE, /* default value */
+                                 G_PARAM_CONSTRUCT_ONLY |
+                                 G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_UWBUF_SIZE,
+                                   param_spec);
+
+  param_spec = g_param_spec_int ("cwbuf_size", "cwbuf_size (construct)",
+                                 "Compressed buffer size of writing",
+                                 0,  /* min */
+                                 G_MAXINT,  /* max */
+                                 DEFAULT_CWBUF_SIZE, /* default value */
+                                 G_PARAM_CONSTRUCT_ONLY |
+                                 G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_CWBUF_SIZE,
+                                   param_spec);
+
+  param_spec = g_param_spec_int ("comp_level", "comp_level (construct)",
+                                 "Compression level (0=none[fast], 6=default, 9=max[slow])",
+                                 Z_DEFAULT_COMPRESSION, /* min */
+                                 Z_BEST_COMPRESSION, /* max */
+                                 Z_DEFAULT_COMPRESSION, /* default value */
+                                 G_PARAM_CONSTRUCT_ONLY |
+                                 G_PARAM_READWRITE);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_COMP_LEVEL,
+                                   param_spec);
+
+  param_spec = g_param_spec_object ("configuration", "configuration (construct)",
+                                    "Thrift Configuration",
+                                    THRIFT_TYPE_CONFIGURATION,
+                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_CONFIGURATION,
+                                   param_spec);
+
+  param_spec = g_param_spec_long ("remainingmessagesize", "remainingmessagesize (construct)",
+                                  "Set the size of the remaining message",
+                                  0, /* min */
+                                  G_MAXINT32, /* max */
+                                  DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */
+                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_REMAINING_MESSAGE_SIZE,
+                                   param_spec);
+
+  param_spec = g_param_spec_long ("knowmessagesize", "knowmessagesize (construct)",
+                                  "Set the size of the know message",
+                                  G_MININT, /* min */
+                                  G_MAXINT32, /* max */
+                                  DEFAULT_MAX_MESSAGE_SIZE, /* default by construct */
+                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+  g_object_class_install_property (gobject_class,
+                                   PROP_THRIFT_ZLIB_TRANSPORT_KNOW_MESSAGE_SIZE,
+                                   param_spec);
+
+  gobject_class->finalize = thrift_zlib_transport_finalize;
+  ttc->is_open = thrift_zlib_transport_is_open;
+  ttc->peek = thrift_zlib_transport_peek;
+  ttc->open = thrift_zlib_transport_open;
+  ttc->close = thrift_zlib_transport_close;
+  ttc->read = thrift_zlib_transport_read;
+  ttc->read_end = thrift_zlib_transport_read_end;
+  ttc->write = thrift_zlib_transport_write;
+  ttc->write_end = thrift_zlib_transport_write_end;
+  ttc->flush = thrift_zlib_transport_flush;
+}
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport.h
new file mode 100644
index 0000000..8d79ba5
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+#ifndef _THRIFT_ZLIB_TRANSPORT_H
+#define _THRIFT_ZLIB_TRANSPORT_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <zlib.h>
+
+#include "thrift_transport.h"
+
+G_BEGIN_DECLS
+
+/*! \file thrift_zlib_transport.h
+ *  \brief Class for Thrift file descriptor transports.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_ZLIB_TRANSPORT (thrift_zlib_transport_get_type ())
+#define THRIFT_ZLIB_TRANSPORT(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), THRIFT_TYPE_ZLIB_TRANSPORT, \
+                               ThriftZlibTransport))
+#define THRIFT_IS_ZLIB_TRANSPORT(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE ((obj), THRIFT_TYPE_ZLIB_TRANSPORT))
+#define THRIFT_ZLIB_TRANSPORT_CLASS(c) \
+  (G_TYPE_CHECK_CLASS_CAST ((c), THRIFT_TYPE_ZLIB_TRANSPORT, \
+                            ThriftZlibTransportClass))
+#define THRIFT_IS_ZLIB_TRANSPORT_CLASS(c) \
+  (G_TYPE_CHECK_CLASS_TYPE ((c), THRIFT_TYPE_ZLIB_TRANSPORT))
+#define THRIFT_ZLIB_TRANSPORT_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), THRIFT_TYPE_ZLIB_TRANSPORT, \
+                              ThriftZlibTransportClass))
+
+typedef struct _ThriftZlibTransport ThriftZlibTransport;\
+
+struct _ThriftZlibTransport
+{
+  ThriftTransport parent;
+
+  /* protected */
+  ThriftTransport *transport;
+  gint urbuf_size;
+  gint crbuf_size;
+  gint uwbuf_size;
+  gint cwbuf_size;
+  gint comp_level;
+  ThriftConfiguration *configuration;
+  glong remainingMessageSize_;
+  glong knowMessageSize_;
+
+  /* private */
+  gint urpos;
+  gint uwpos;
+  gboolean input_ended;  /* TRUE iff zlib has reached the end of the input stream*/
+  gboolean output_finished;  /* TRUE iff we have finished the ouput stream*/
+  guint8* urbuf;
+  guint8* crbuf;
+  guint8* uwbuf;
+  guint8* cwbuf;
+  struct z_stream_s* rstream;
+  struct z_stream_s* wstream;
+};
+
+typedef struct _ThriftZlibTransportClass ThriftZlibTransportClass;
+
+/*!
+ * Thrift Transport class
+ */
+struct _ThriftZlibTransportClass
+{
+  ThriftTransportClass parent;
+};
+
+/* used by THRIFT_TYPE_ZLIB_TRANSPORT */
+GType thrift_zlib_transport_get_type (void);
+
+gboolean
+thrift_zlib_transport_verify_checksum(ThriftTransport *transport, GError **error);
+
+gboolean
+thrift_zlib_transport_finish(ThriftTransport *transport, GError **error);
+
+G_END_DECLS
+
+#endif /* _THRIFT_ZLIB_TRANSPORT_H */
+
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport_factory.c b/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport_factory.c
new file mode 100644
index 0000000..7888c62
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport_factory.c
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/transport/thrift_zlib_transport.h>
+#include <thrift/c_glib/transport/thrift_zlib_transport_factory.h>
+
+G_DEFINE_TYPE (ThriftZlibTransportFactory,
+               thrift_zlib_transport_factory,
+               THRIFT_TYPE_TRANSPORT_FACTORY)
+
+/* Wraps a transport with a ThriftZlibTransport. */
+ThriftTransport *
+thrift_zlib_transport_factory_get_transport (ThriftTransportFactory *factory,
+                                             ThriftTransport *transport)
+{
+  THRIFT_UNUSED_VAR (factory);
+
+  return THRIFT_TRANSPORT (g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT,
+                                         "transport", transport,
+                                         NULL));
+}
+
+static void
+thrift_zlib_transport_factory_init (ThriftZlibTransportFactory *self)
+{
+  THRIFT_UNUSED_VAR (self);
+}
+
+static void 
+thrift_zlib_transport_factory_class_init (ThriftZlibTransportFactoryClass *klass)
+{
+  ThriftTransportFactoryClass *base_class = 
+    THRIFT_TRANSPORT_FACTORY_CLASS (klass);
+
+  base_class->get_transport = 
+    klass->get_transport =
+    thrift_zlib_transport_factory_get_transport;
+}
diff --git a/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport_factory.h b/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport_factory.h
new file mode 100644
index 0000000..5fa9e6b
--- /dev/null
+++ b/lib/c_glib/src/thrift/c_glib/transport/thrift_zlib_transport_factory.h
@@ -0,0 +1,85 @@
+/*
+ * 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.
+ */
+
+#ifndef _THRIFT_ZLIB_TRANSPORT_FACTORY_H
+#define _THRIFT_ZLIB_TRANSPORT_FACTORY_H
+
+#include <glib-object.h>
+
+#include <thrift/c_glib/transport/thrift_transport.h>
+#include <thrift/c_glib/transport/thrift_transport_factory.h>
+
+G_BEGIN_DECLS
+
+/*! \file thrift_zlib_transport_factory.h
+ *  \brief Wraps a transport with a ThriffZlibTransport.
+ */
+
+/* type macros */
+#define THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY (thrift_zlib_transport_factory_get_type())
+#define THRIFT_ZLIB_TRANSPORT_FACTORY(obj)                          \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj),                               \
+                               THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY,  \
+                               ThriftZlibTransportFactory))
+#define THRIFT_IS_ZLIB_TRANSPORT_FACTORY(obj)                       \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj),                               \
+                               THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY))
+#define THRIFT_ZLIB_TRANSPORT_FACTORY_CLASS(c)                      \
+  (G_TYPE_CHECK_CLASS_CAST ((c),                                    \
+                            THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY,     \
+                            ThriftZlibTransportFactoryClass))
+#define THRIFT_IS_ZLIB_TRANSPORT_FACTORY_CLASS(c)                   \
+  (G_TYPE_CHECK_CLASS_TYPE ((c),                                    \
+                            THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY)
+#define THRIFT_ZLIB_TRANSPORT_FACTORY_GET_CLASS(obj)                \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj),                                \
+                              THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY,   \
+                              ThriftZlibTransportFactoryClass))
+
+typedef struct _ThriftZlibTransportFactory ThriftZlibTransportFactory;
+
+/* Thrift Zlib-Transport Factory instance */
+struct _ThriftZlibTransportFactory
+{
+  ThriftTransportFactory parent;
+};
+
+typedef struct _ThriftZlibTransportFactoryClass ThriftZlibTransportFactoryClass;
+
+/* Thrift Zlib-Transport Factory class */
+struct _ThriftZlibTransportFactoryClass
+{
+  ThriftTransportFactoryClass parent;
+
+  /* vtable */
+  ThriftTransport *(*get_transport) (ThriftTransportFactory *factory,
+                                     ThriftTransport *transport);
+};
+
+/* USED BY THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY */
+GType thrift_zlib_transport_factory_get_type (void);
+
+/* virtual public methods */
+ThriftTransport *
+thrift_zlib_transport_factory_get_transport (ThriftTransportFactory *factory,
+                                             ThriftTransport *transport);
+
+G_END_DECLS
+
+#endif /* _THRIFT_ZLIB_TANSPORT_FACTORY_H */
diff --git a/lib/c_glib/test/CMakeLists.txt b/lib/c_glib/test/CMakeLists.txt
index cae8e51..c46014d 100644
--- a/lib/c_glib/test/CMakeLists.txt
+++ b/lib/c_glib/test/CMakeLists.txt
@@ -20,9 +20,7 @@
 
 set(TEST_PREFIX "c_glib")
 
-# include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
-
-#Make sure gen-cpp and gen-c_glib files can be included
+# Make sure gen-cpp and gen-c_glib files can be included
 include_directories("${CMAKE_CURRENT_BINARY_DIR}")
 
 # Create the thrift C test library
@@ -130,6 +128,14 @@
 target_link_libraries(testthriftmemorybufferreadcheck testgenc)
 add_test(NAME testthriftmemorybufferreadcheck COMMAND testthriftmemorybufferreadcheck)
 
+if(WITH_ZLIB)
+  include_directories(SYSTEM "${ZLIB_INCLUDE_DIRS}")
+  add_executable(testzlibtransport testzlibtransport.c)
+  target_link_libraries(testzlibtransport testgenc ${ZLIB_LIBRARIES})
+  LINK_AGAINST_THRIFT_LIBRARY(testzlibtransport thrift_c_glib_zlib)
+  add_test(NAME testzlibtransport COMMAND testzlibtransport)
+endif(WITH_ZLIB)
+
 include_directories("${PROJECT_SOURCE_DIR}/test/c_glib/src" "${CMAKE_CURRENT_BINARY_DIR}/gen-c_glib")
 
 add_executable(testthrifttest testthrifttest.c
@@ -143,7 +149,6 @@
 
 
 if(BUILD_CPP)
-
     include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src")
 
     # Create the thrift C++ test library
@@ -167,6 +172,12 @@
     target_link_libraries(testthrifttestclient testgenc testgenc_cpp ${ZLIB_LIBRARIES})
     add_test(NAME testthrifttestclient COMMAND testthrifttestclient)
 
+ if(WITH_ZLIB)
+    add_executable(testthrifttestzlibclient testthrifttestzlibclient.cpp)
+    target_link_libraries(testthrifttestzlibclient testgenc testgenc_cpp thriftz thrift_c_glib_zlib ${ZLIB_LIBRARIES})
+    add_test(NAME testthrifttestzlibclient COMMAND testthrifttestzlibclient)
+endif(WITH_ZLIB)
+
 endif(BUILD_CPP)
 
 #
diff --git a/lib/c_glib/test/Makefile.am b/lib/c_glib/test/Makefile.am
index 3ff48a3..023165a 100755
--- a/lib/c_glib/test/Makefile.am
+++ b/lib/c_glib/test/Makefile.am
@@ -40,7 +40,7 @@
 AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) \
 	@GCOV_CFLAGS@
 AM_CXXFLAGS = $(AM_CFLAGS)
-AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LIBS) @GCOV_LDFLAGS@
+AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LIBS) $(ZLIB_LIBS) @GCOV_LDFLAGS@
 
 check_PROGRAMS = \
   testserialization \
@@ -52,6 +52,7 @@
   testcompactprotocol \
   testbufferedtransport \
   testframedtransport \
+  testzlibtransport \
   testfdtransport \
   testmemorybuffer \
   teststruct \
@@ -68,7 +69,8 @@
 
 if WITH_CPP
   BUILT_SOURCES += gen-cpp/ThriftTest_types.cpp
-  check_PROGRAMS += testthrifttestclient
+  check_PROGRAMS += testthrifttestclient \
+                    testthrifttestzlibclient
 endif
 
 testserialization_SOURCES = testserialization.c
@@ -158,6 +160,14 @@
     $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \
     $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o 
 
+testzlibtransport_SOURCES = testzlibtransport.c
+testzlibtransport_LDADD = \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_socket.o \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_transport.o \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_server_socket.o \
+    $(top_builddir)/lib/c_glib/src/thrift/c_glib/libthrift_c_glib_la-thrift_configuration.o 
+
 testfdtransport_SOURCES = testfdtransport.c
 testfdtransport_LDADD = \
     $(top_builddir)/lib/c_glib/src/thrift/c_glib/transport/libthrift_c_glib_la-thrift_transport.o \
@@ -258,6 +268,11 @@
 testthrifttestclient_LDADD = ../../cpp/.libs/libthrift.la ../libthrift_c_glib.la libtestgenc.la libtestgencpp.la
 testthrifttestclient_LDFLAGS = -L../.libs -L../../cpp/.libs $(GLIB_LIBS) $(GOBJECT_LIBS)
 
+testthrifttestzlibclient_SOURCES = testthrifttestzlibclient.cpp
+testthrifttestzlibclient_CPPFLAGS = -I../../cpp/src $(BOOST_CPPFLAGS) -I./gen-cpp -I../src -I./gen-c_glib $(GLIB_CFLAGS)
+testthrifttestzlibclient_LDADD = ../../cpp/.libs/libthrift.la ../../cpp/.libs/libthriftz.la ../libthrift_c_glib.la libtestgenc.la libtestgencpp.la
+testthrifttestzlibclient_LDFLAGS = -L../.libs -L../../cpp/.libs $(GLIB_LIBS) $(GOBJECT_LIBS)
+
 check_LTLIBRARIES = libtestgenc.la
 
 if WITH_CPP
diff --git a/lib/c_glib/test/testthrifttestclient.cpp b/lib/c_glib/test/testthrifttestclient.cpp
index 5732996..b8d9309 100644
--- a/lib/c_glib/test/testthrifttestclient.cpp
+++ b/lib/c_glib/test/testthrifttestclient.cpp
@@ -291,7 +291,7 @@
   }
 
   void testException(const std::string &arg)
-    throw(Xception, apache::thrift::TException) override
+    noexcept(false)  override
   {
     cout << "[C -> C++] testException(" << arg << ")" << endl;
     if (arg.compare("Xception") == 0) {
@@ -309,7 +309,7 @@
     }
   }
 
-  void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) override {
+  void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) noexcept(false) override {
 
     cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << endl;
 
diff --git a/lib/c_glib/test/testthrifttestzlibclient.cpp b/lib/c_glib/test/testthrifttestzlibclient.cpp
new file mode 100644
index 0000000..5c4b931
--- /dev/null
+++ b/lib/c_glib/test/testthrifttestzlibclient.cpp
@@ -0,0 +1,645 @@
+/*
+ * 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.
+ */
+
+/* test a C client with a C++ server  (that makes sense...) */
+
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <thrift/protocol/TBinaryProtocol.h>
+#include <thrift/protocol/TDebugProtocol.h>
+#include <thrift/server/TSimpleServer.h>
+#include <memory>
+#include <thrift/transport/TServerSocket.h>
+#include <thrift/transport/TZlibTransport.h>
+#include "ThriftTest.h"
+#include "ThriftTest_types.h"
+
+#include <iostream>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+using namespace apache::thrift;
+using namespace apache::thrift::concurrency;
+using namespace apache::thrift::protocol;
+using namespace apache::thrift::server;
+using namespace apache::thrift::transport;
+
+using namespace thrift::test;
+
+using std::cout;
+using std::endl;
+using std::fixed;
+using std::make_pair;
+using std::map;
+using std::set;
+using std::string;
+using std::vector;
+
+#define TEST_PORT 9980
+
+// Extra functions required for ThriftTest_types to work
+namespace thrift { namespace test {
+
+bool Insanity::operator<(thrift::test::Insanity const& other) const {
+  using apache::thrift::ThriftDebugString;
+  return ThriftDebugString(*this) < ThriftDebugString(other);
+}
+
+}}
+
+class TestHandler : public ThriftTestIf {
+  public:
+  TestHandler() = default;
+
+  void testVoid() override {
+    cout << "[C -> C++] testVoid()" << endl;
+  }
+
+  void testString(string& out, const string &thing) override {
+    cout << "[C -> C++] testString(\"" << thing << "\")" << endl;
+    out = thing;
+  }
+
+  bool testBool(const bool thing) override {
+    cout << "[C -> C++] testBool(" << (thing ? "true" : "false") << ")" << endl;
+    return thing;
+  }
+  int8_t testByte(const int8_t thing) override {
+    cout << "[C -> C++] testByte(" << (int)thing << ")" << endl;
+    return thing;
+  }
+  int32_t testI32(const int32_t thing) override {
+    cout << "[C -> C++] testI32(" << thing << ")" << endl;
+    return thing;
+  }
+
+  int64_t testI64(const int64_t thing) override {
+    cout << "[C -> C++] testI64(" << thing << ")" << endl;
+    return thing;
+  }
+
+  double testDouble(const double thing) override {
+    cout.precision(6);
+    cout << "[C -> C++] testDouble(" << fixed << thing << ")" << endl;
+    return thing;
+  }
+
+  void testBinary(string& out, const string &thing) override {
+    cout << "[C -> C++] testBinary(\"" << thing << "\")" << endl;
+    out = thing;
+  }
+
+  void testStruct(Xtruct& out, const Xtruct &thing) override {
+    cout << "[C -> C++] testStruct({\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "})" << endl;
+    out = thing;
+  }
+
+  void testNest(Xtruct2& out, const Xtruct2& nest) override {
+    const Xtruct &thing = nest.struct_thing;
+    cout << "[C -> C++] testNest({" << (int)nest.byte_thing << ", {\"" << thing.string_thing << "\", " << (int)thing.byte_thing << ", " << thing.i32_thing << ", " << thing.i64_thing << "}, " << nest.i32_thing << "})" << endl;
+    out = nest;
+  }
+
+  void testMap(map<int32_t, int32_t> &out, const map<int32_t, int32_t> &thing) override {
+    cout << "[C -> C++] testMap({";
+    map<int32_t, int32_t>::const_iterator m_iter;
+    bool first = true;
+    for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
+      if (first) {
+        first = false;
+      } else {
+        cout << ", ";
+      }
+      cout << m_iter->first << " => " << m_iter->second;
+    }
+    cout << "})" << endl;
+    out = thing;
+  }
+
+  void testStringMap(map<std::string, std::string> &out, const map<std::string, std::string> &thing) override {
+    cout << "[C -> C++] testStringMap({";
+    map<std::string, std::string>::const_iterator m_iter;
+    bool first = true;
+    for (m_iter = thing.begin(); m_iter != thing.end(); ++m_iter) {
+      if (first) {
+        first = false;
+      } else {
+        cout << ", ";
+      }
+      cout << "\"" << m_iter->first << "\" => \"" << m_iter->second << "\"";
+    }
+    cout << "})" << endl;
+    out = thing;
+  }
+
+
+  void testSet(set<int32_t> &out, const set<int32_t> &thing) override {
+    cout << "[C -> C++] testSet({";
+    set<int32_t>::const_iterator s_iter;
+    bool first = true;
+    for (s_iter = thing.begin(); s_iter != thing.end(); ++s_iter) {
+      if (first) {
+        first = false;
+      } else {
+        cout << ", ";
+      }
+      cout << *s_iter;
+    }
+    cout << "})" << endl;
+    out = thing;
+  }
+
+  void testList(vector<int32_t> &out, const vector<int32_t> &thing) override {
+    cout << "[C -> C++] testList({";
+    vector<int32_t>::const_iterator l_iter;
+    bool first = true;
+    for (l_iter = thing.begin(); l_iter != thing.end(); ++l_iter) {
+      if (first) {
+        first = false;
+      } else {
+        cout << ", ";
+      }
+      cout << *l_iter;
+    }
+    cout << "})" << endl;
+    out = thing;
+  }
+
+  Numberz::type testEnum(const Numberz::type thing) override {
+    cout << "[C -> C++] testEnum(" << thing << ")" << endl;
+    return thing;
+  }
+
+  UserId testTypedef(const UserId thing) override {
+    cout << "[C -> C++] testTypedef(" << thing << ")" << endl;
+    return thing;  }
+
+  void testMapMap(map<int32_t, map<int32_t,int32_t> > &mapmap, const int32_t hello) override {
+    cout << "[C -> C++] testMapMap(" << hello << ")" << endl;
+
+    map<int32_t,int32_t> pos;
+    map<int32_t,int32_t> neg;
+    for (int i = 1; i < 5; i++) {
+      pos.insert(make_pair(i,i));
+      neg.insert(make_pair(-i,-i));
+    }
+
+    mapmap.insert(make_pair(4, pos));
+    mapmap.insert(make_pair(-4, neg));
+
+  }
+
+  void testInsanity(map<UserId, map<Numberz::type,Insanity> > &insane, const Insanity &argument) override {
+    THRIFT_UNUSED_VARIABLE (argument);
+
+    cout << "[C -> C++] testInsanity()" << endl;
+
+    Xtruct hello;
+    hello.string_thing = "Hello2";
+    hello.byte_thing = 2;
+    hello.i32_thing = 2;
+    hello.i64_thing = 2;
+
+    Xtruct goodbye;
+    goodbye.string_thing = "Goodbye4";
+    goodbye.byte_thing = 4;
+    goodbye.i32_thing = 4;
+    goodbye.i64_thing = 4;
+
+    Insanity crazy;
+    crazy.userMap.insert(make_pair(Numberz::EIGHT, 8));
+    crazy.xtructs.push_back(goodbye);
+
+    Insanity looney;
+    crazy.userMap.insert(make_pair(Numberz::FIVE, 5));
+    crazy.xtructs.push_back(hello);
+
+    map<Numberz::type, Insanity> first_map;
+    map<Numberz::type, Insanity> second_map;
+
+    first_map.insert(make_pair(Numberz::TWO, crazy));
+    first_map.insert(make_pair(Numberz::THREE, crazy));
+
+    second_map.insert(make_pair(Numberz::SIX, looney));
+
+    insane.insert(make_pair(1, first_map));
+    insane.insert(make_pair(2, second_map));
+
+    cout << "return = {";
+    map<UserId, map<Numberz::type,Insanity> >::const_iterator i_iter;
+    for (i_iter = insane.begin(); i_iter != insane.end(); ++i_iter) {
+      cout << i_iter->first << " => {";
+      map<Numberz::type,Insanity>::const_iterator i2_iter;
+      for (i2_iter = i_iter->second.begin();
+           i2_iter != i_iter->second.end();
+           ++i2_iter) {
+        cout << i2_iter->first << " => {";
+        map<Numberz::type, UserId> userMap = i2_iter->second.userMap;
+        map<Numberz::type, UserId>::const_iterator um;
+        cout << "{";
+        for (um = userMap.begin(); um != userMap.end(); ++um) {
+          cout << um->first << " => " << um->second << ", ";
+        }
+        cout << "}, ";
+
+        vector<Xtruct> xtructs = i2_iter->second.xtructs;
+        vector<Xtruct>::const_iterator x;
+        cout << "{";
+        for (x = xtructs.begin(); x != xtructs.end(); ++x) {
+          cout << "{\"" << x->string_thing << "\", " << (int)x->byte_thing << ", " << x->i32_thing << ", " << x->i64_thing << "}, ";
+        }
+        cout << "}";
+
+        cout << "}, ";
+      }
+      cout << "}, ";
+    }
+    cout << "}" << endl;
+
+
+  }
+
+  void testMulti(Xtruct &hello, const int8_t arg0, const int32_t arg1, const int64_t arg2, const std::map<int16_t, std::string>  &arg3, const Numberz::type arg4, const UserId arg5) override {
+    THRIFT_UNUSED_VARIABLE (arg3);
+    THRIFT_UNUSED_VARIABLE (arg4);
+    THRIFT_UNUSED_VARIABLE (arg5);
+
+    cout << "[C -> C++] testMulti()" << endl;
+
+    hello.string_thing = "Hello2";
+    hello.byte_thing = arg0;
+    hello.i32_thing = arg1;
+    hello.i64_thing = (int64_t)arg2;
+  }
+
+  void testException(const std::string &arg)
+    throw(Xception, apache::thrift::TException) override
+  {
+    cout << "[C -> C++] testException(" << arg << ")" << endl;
+    if (arg.compare("Xception") == 0) {
+      Xception e;
+      e.errorCode = 1001;
+      e.message = arg;
+      throw e;
+    } else if (arg.compare("ApplicationException") == 0) {
+      apache::thrift::TException e;
+      throw e;
+    } else {
+      Xtruct result;
+      result.string_thing = arg;
+      return;
+    }
+  }
+
+  void testMultiException(Xtruct &result, const std::string &arg0, const std::string &arg1) throw(Xception, Xception2) override {
+
+    cout << "[C -> C++] testMultiException(" << arg0 << ", " << arg1 << ")" << endl;
+
+    if (arg0.compare("Xception") == 0) {
+      Xception e;
+      e.errorCode = 1001;
+      e.message = "This is an Xception";
+      throw e;
+    } else if (arg0.compare("Xception2") == 0) {
+      Xception2 e;
+      e.errorCode = 2002;
+      e.struct_thing.string_thing = "This is an Xception2";
+      throw e;
+    } else {
+      result.string_thing = arg1;
+      return;
+    }
+  }
+
+  void testOneway(int sleepFor) override {
+    cout << "testOneway(" << sleepFor << "): Sleeping..." << endl;
+    sleep(sleepFor);
+    cout << "testOneway(" << sleepFor << "): done sleeping!" << endl;
+  }
+};
+
+// C CLIENT
+extern "C" {
+
+#undef THRIFT_SOCKET /* from lib/cpp */
+
+#include "t_test_thrift_test.h"
+#include "t_test_thrift_test_types.h"
+#include <thrift/c_glib/transport/thrift_socket.h>
+#include <thrift/c_glib/transport/thrift_zlib_transport.h>
+#include <thrift/c_glib/protocol/thrift_protocol.h>
+#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
+
+static void
+test_thrift_client (void)
+{
+  ThriftSocket *tsocket = nullptr;
+  ThriftBinaryProtocol *protocol = nullptr;
+  ThriftZlibTransport *transport = nullptr;
+  TTestThriftTestClient *client = nullptr;
+  TTestThriftTestIf *iface = nullptr;
+  GError *error = nullptr;
+  gchar *string = nullptr;
+  gint8 byte = 0;
+  gint16 i16 = 0;
+  gint32 i32 = 0, another_i32 = 56789;
+  gint64 i64 = 0;
+  double dbl = 0.0;
+  TTestXtruct *xtruct_in, *xtruct_out;
+  TTestXtruct2 *xtruct2_in, *xtruct2_out;
+  GHashTable *map_in = nullptr, *map_out = nullptr;
+  GHashTable *set_in = nullptr, *set_out = nullptr;
+  GArray *list_in = nullptr, *list_out = nullptr;
+  TTestNumberz enum_in, enum_out;
+  TTestUserId user_id_in, user_id_out;
+  GHashTable *insanity_in = nullptr;
+  TTestXtruct *xtruct1, *xtruct2;
+  TTestInsanity *insanity_out = nullptr;
+  TTestXtruct *multi_in = nullptr;
+  GHashTable *multi_map_out = nullptr;
+  TTestXception *xception = nullptr;
+  TTestXception2 *xception2 = nullptr;
+
+#if (!GLIB_CHECK_VERSION (2, 36, 0))
+  // initialize gobject
+  g_type_init ();
+#endif
+
+  // create a C client
+  tsocket = (ThriftSocket *) g_object_new (THRIFT_TYPE_SOCKET,
+                          "hostname", "localhost",
+                          "port", TEST_PORT, nullptr);
+  transport = (ThriftZlibTransport *) g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT,
+                                   "transport", tsocket, nullptr);
+  protocol = (ThriftBinaryProtocol *) g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
+                           "transport",
+                           transport, nullptr);
+  client = (TTestThriftTestClient *) g_object_new (T_TEST_TYPE_THRIFT_TEST_CLIENT, "input_protocol", protocol, "output_protocol", protocol, nullptr);
+  iface = T_TEST_THRIFT_TEST_IF (client);
+
+  // open and send
+  thrift_transport_open (THRIFT_TRANSPORT(transport), nullptr);
+
+  assert (t_test_thrift_test_client_test_void (iface, &error) == TRUE);
+  assert (error == nullptr);
+
+  assert (t_test_thrift_test_client_test_string (iface, &string, "test123", &error) == TRUE);
+  assert (strcmp (string, "test123") == 0);
+  g_free (string);
+  assert (error == nullptr);
+
+  assert (t_test_thrift_test_client_test_byte (iface, &byte, (gint8) 5, &error) == TRUE);
+  assert (byte == 5);
+  assert (error == nullptr);
+
+  assert (t_test_thrift_test_client_test_i32 (iface, &i32, 123, &error) == TRUE);
+  assert (i32 == 123);
+  assert (error == nullptr);
+
+  assert (t_test_thrift_test_client_test_i64 (iface, &i64, 12345, &error) == TRUE);
+  assert (i64 == 12345);
+  assert (error == nullptr);
+
+  assert (t_test_thrift_test_client_test_double (iface, &dbl, 5.6, &error) == TRUE);
+  assert (dbl == 5.6);
+  assert (error == nullptr);
+
+  xtruct_out = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+  xtruct_out->byte_thing = 1;
+  xtruct_out->__isset_byte_thing = TRUE;
+  xtruct_out->i32_thing = 15;
+  xtruct_out->__isset_i32_thing = TRUE;
+  xtruct_out->i64_thing = 151;
+  xtruct_out->__isset_i64_thing = TRUE;
+  xtruct_out->string_thing = g_strdup ("abc123");
+  xtruct_out->__isset_string_thing = TRUE;
+  xtruct_in = (TTestXtruct *) g_object_new(T_TEST_TYPE_XTRUCT, nullptr);
+  assert (t_test_thrift_test_client_test_struct (iface, &xtruct_in, xtruct_out, &error) == TRUE);
+  assert (error == nullptr);
+
+  xtruct2_out = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr);
+  xtruct2_out->byte_thing = 1;
+  xtruct2_out->__isset_byte_thing = TRUE;
+  if (xtruct2_out->struct_thing != nullptr)
+    g_object_unref(xtruct2_out->struct_thing);
+  xtruct2_out->struct_thing = xtruct_out;
+  xtruct2_out->__isset_struct_thing = TRUE;
+  xtruct2_out->i32_thing = 123;
+  xtruct2_out->__isset_i32_thing = TRUE;
+  xtruct2_in = (TTestXtruct2 *) g_object_new (T_TEST_TYPE_XTRUCT2, nullptr);
+  assert (t_test_thrift_test_client_test_nest (iface, &xtruct2_in, xtruct2_out, &error) == TRUE);
+  assert (error == nullptr);
+
+  g_object_unref (xtruct2_out);
+  g_object_unref (xtruct2_in);
+  g_object_unref (xtruct_in);
+
+  map_out = g_hash_table_new (nullptr, nullptr);
+  map_in = g_hash_table_new (nullptr, nullptr);  g_hash_table_insert (map_out, &i32, &i32);
+  assert (t_test_thrift_test_client_test_map (iface, &map_in, map_out, &error) == TRUE);
+  assert (error == nullptr);
+  g_hash_table_destroy (map_out);
+  g_hash_table_destroy (map_in);
+
+  map_out = g_hash_table_new (nullptr, nullptr);
+  map_in = g_hash_table_new (nullptr, nullptr);
+  g_hash_table_insert (map_out, g_strdup ("a"), g_strdup ("123"));
+  g_hash_table_insert (map_out, g_strdup ("a b"), g_strdup ("with spaces "));
+  g_hash_table_insert (map_out, g_strdup ("same"), g_strdup ("same"));
+  g_hash_table_insert (map_out, g_strdup ("0"), g_strdup ("numeric key"));
+  assert (t_test_thrift_test_client_test_string_map (iface, &map_in, map_out, &error) == TRUE);
+  assert (error == nullptr);
+  g_hash_table_destroy (map_out);
+  g_hash_table_destroy (map_in);
+
+  set_out = g_hash_table_new (nullptr, nullptr);
+  set_in = g_hash_table_new (nullptr, nullptr);
+  g_hash_table_insert (set_out, &i32, &i32);
+  assert (t_test_thrift_test_client_test_set (iface, &set_in, set_out, &error) == TRUE);
+  assert (error == nullptr);
+  g_hash_table_destroy (set_out);
+  g_hash_table_destroy (set_in);
+
+  list_out = g_array_new(TRUE, TRUE, sizeof(gint32));
+  list_in = g_array_new(TRUE, TRUE, sizeof(gint32));
+  another_i32 = 456;
+  g_array_append_val (list_out, i32);
+  g_array_append_val (list_out, another_i32);
+  assert (t_test_thrift_test_client_test_list (iface, &list_in, list_out, &error) == TRUE);
+  assert (error == nullptr);
+  g_array_free (list_out, TRUE);
+  g_array_free (list_in, TRUE);
+
+  enum_out = T_TEST_NUMBERZ_ONE;
+  assert (t_test_thrift_test_client_test_enum (iface, &enum_in, enum_out, &error) == TRUE);
+  assert (enum_in == enum_out);
+  assert (error == nullptr);
+
+  user_id_out = 12345;
+  assert (t_test_thrift_test_client_test_typedef (iface, &user_id_in, user_id_out, &error) == TRUE);
+  assert (user_id_in == user_id_out);
+  assert (error == nullptr);
+
+  map_in = g_hash_table_new (nullptr, nullptr);
+  assert (t_test_thrift_test_client_test_map_map (iface, &map_in, i32, &error) == TRUE);
+  assert (error == nullptr);
+  g_hash_table_destroy (map_in);
+
+  // insanity
+  insanity_out = (TTestInsanity *) g_object_new (T_TEST_TYPE_INSANITY, nullptr);
+  insanity_out->userMap = g_hash_table_new (nullptr, nullptr);
+  g_hash_table_insert (insanity_out->userMap, GINT_TO_POINTER (enum_out), &user_id_out);
+
+  xtruct1 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+  xtruct1->byte_thing = 1;
+  xtruct1->__isset_byte_thing = TRUE;
+  xtruct1->i32_thing = 15;
+  xtruct1->__isset_i32_thing = TRUE;
+  xtruct1->i64_thing = 151;
+  xtruct1->__isset_i64_thing = TRUE;
+  xtruct1->string_thing = g_strdup ("abc123");
+  xtruct1->__isset_string_thing = TRUE;
+  xtruct2 = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+  xtruct2->byte_thing = 1;
+  xtruct2->__isset_byte_thing = TRUE;
+  xtruct2->i32_thing = 15;
+  xtruct2->__isset_i32_thing = TRUE;
+  xtruct2->i64_thing = 151;
+  xtruct2->__isset_i64_thing = TRUE;
+  xtruct2->string_thing = g_strdup ("abc123");
+  xtruct2->__isset_string_thing = TRUE;
+
+  insanity_in = g_hash_table_new (nullptr, nullptr);
+  g_ptr_array_add (insanity_out->xtructs, xtruct1);
+  g_ptr_array_add (insanity_out->xtructs, xtruct2);
+  assert (t_test_thrift_test_client_test_insanity (iface, &insanity_in, insanity_out, &error) == TRUE);
+
+  g_hash_table_unref (insanity_in);
+  g_ptr_array_free (insanity_out->xtructs, TRUE);
+
+  multi_map_out = g_hash_table_new (nullptr, nullptr);
+  string = g_strdup ("abc123");
+  g_hash_table_insert (multi_map_out, &i16, string);
+  multi_in = (TTestXtruct *) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+  assert (t_test_thrift_test_client_test_multi (iface, &multi_in, byte, i32, i64, multi_map_out, enum_out, user_id_out, &error) == TRUE);
+  assert (multi_in->i32_thing == i32);
+  assert (multi_in->i64_thing == i64);
+  g_object_unref (multi_in);
+  g_hash_table_unref (multi_map_out);
+  g_free (string);
+
+  assert (t_test_thrift_test_client_test_exception (iface, "Xception", &xception, &error) == FALSE);
+  assert (xception->errorCode == 1001);
+  g_error_free (error);
+  error = nullptr;
+  g_object_unref (xception);
+  xception = nullptr;
+
+  assert (t_test_thrift_test_client_test_exception (iface, "ApplicationException", &xception, &error) == FALSE);
+  g_error_free (error);
+  error = nullptr;
+  assert (xception == nullptr);
+
+  assert (t_test_thrift_test_client_test_exception (iface, "Test", &xception, &error) == TRUE);
+  assert (error == nullptr);
+
+  multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+  assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception", nullptr, &xception, &xception2, &error) == FALSE);
+  assert (xception->errorCode == 1001);
+  assert (xception2 == nullptr);
+  g_error_free (error);
+  error = nullptr;
+  g_object_unref (xception);
+  g_object_unref (multi_in);
+  xception = nullptr;
+  multi_in = nullptr;
+
+  multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+  assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, "Xception2", nullptr, &xception, &xception2, &error) == FALSE);
+  assert (xception2->errorCode == 2002);
+  assert (xception == nullptr);
+  g_error_free (error);
+  error = nullptr;
+  g_object_unref (xception2);
+  g_object_unref (multi_in);
+  xception2 = nullptr;
+  multi_in = nullptr;
+
+  multi_in = (TTestXtruct*) g_object_new (T_TEST_TYPE_XTRUCT, nullptr);
+  assert (t_test_thrift_test_client_test_multi_exception (iface, &multi_in, nullptr , nullptr, &xception, &xception2, &error) == TRUE);
+  assert (error == nullptr);
+  g_object_unref(multi_in);
+  multi_in = nullptr;
+
+  assert (t_test_thrift_test_client_test_oneway (iface, 1, &error) == TRUE);
+  assert (error == nullptr);
+
+  /* sleep to let the oneway call go through */
+  sleep (5);
+
+  thrift_transport_close (THRIFT_TRANSPORT(tsocket), nullptr);
+  g_object_unref (client);
+  g_object_unref (protocol);
+  g_object_unref (tsocket);
+}
+
+
+} /* extern "C" */
+
+
+static void
+bailout (int signum)
+{
+  THRIFT_UNUSED_VARIABLE (signum);
+
+  exit (1);
+}
+
+int
+main (void)
+{
+  int status;
+  int pid = fork ();
+  assert (pid >= 0);
+
+  if (pid == 0) /* child */
+  {
+    std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
+    std::shared_ptr<TestHandler> testHandler(new TestHandler());
+    std::shared_ptr<ThriftTestProcessor> testProcessor(new ThriftTestProcessor(testHandler));
+    std::shared_ptr<TServerSocket> serverSocket(new TServerSocket(TEST_PORT));
+    std::shared_ptr<TZlibTransportFactory> transportFactory(new TZlibTransportFactory());
+    //std::shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
+    TSimpleServer simpleServer(testProcessor, serverSocket, transportFactory, protocolFactory);
+    signal (SIGALRM, bailout);
+    alarm (60);
+    simpleServer.serve();
+  } else {
+    sleep (1);
+    test_thrift_client ();
+    kill (pid, SIGINT);
+    assert (wait (&status) == pid);
+  }
+
+  return 0;
+}
+
diff --git a/lib/c_glib/test/testzlibtransport.c b/lib/c_glib/test/testzlibtransport.c
new file mode 100644
index 0000000..04e368f
--- /dev/null
+++ b/lib/c_glib/test/testzlibtransport.c
@@ -0,0 +1,231 @@
+/*
+ * 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.
+ */
+
+#include <netdb.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#include <thrift/c_glib/transport/thrift_transport.h>
+#include <thrift/c_glib/transport/thrift_socket.h>
+#include <thrift/c_glib/transport/thrift_server_transport.h>
+#include <thrift/c_glib/transport/thrift_server_socket.h>
+
+#define TEST_DATA  \
+                    { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',  \
+                      'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',  \
+                      'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4',  \
+                      '5', '6', '7', '8', '9', '0' }
+
+#include "../src/thrift/c_glib/transport/thrift_zlib_transport.c"
+
+static void thrift_server (const int port);
+static void thrift_socket_server_open (const int port, int times);
+
+/* test object creation and destruction */
+static void
+test_create_and_destroy(void)
+{
+  ThriftTransport *transport = NULL;
+  gint urbuf_size = 0;
+  gint crbuf_size = 0;
+  gint uwbuf_size = 0;
+  gint cwbuf_size = 0;
+  gint comp_level = 0;
+
+  GObject *object = NULL;
+  object = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT, NULL);
+  g_assert (object != NULL);
+  g_object_get (G_OBJECT (object), "transport", &transport,
+                "urbuf_size", &urbuf_size,
+                "crbuf_size", &crbuf_size, 
+                "uwbuf_size", &uwbuf_size,
+                "cwbuf_size", &cwbuf_size,
+                "comp_level", &comp_level, NULL);
+  g_object_unref (object);
+}
+
+static void 
+test_open_and_close(void)
+{
+  ThriftSocket *tsocket = NULL;
+  ThriftTransport *transport = NULL;
+  GError *err = NULL;
+  pid_t pid;
+  int port = 51199;
+  int status;
+  
+  pid = fork ();
+  g_assert ( pid >= 0 );
+
+  if ( pid == 0 )
+    {
+      /* child listens */
+      thrift_socket_server_open (port,1);
+      exit (0);
+    } else {
+        /* parent connects, wait a bit for the socket to be created */
+        sleep (1);
+        /* create a ThriftSocket */
+        tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+                                "port", port, NULL);
+        
+        /* create a ZlibTransport wrapper of the Socket */
+        transport = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT,
+                                  "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+        /* this shouldn't work */
+        g_assert (thrift_zlib_transport_open (transport, NULL) == TRUE);
+        g_assert (thrift_zlib_transport_is_open (transport) == TRUE);
+        g_assert (thrift_zlib_transport_close (transport, NULL) == TRUE);
+        g_object_unref (transport);
+        g_object_unref (tsocket);
+
+        /* try and underlying socket failure */
+        tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost_broken",
+                                NULL);
+       
+        /* create a ZlibTransport wrapper of the Socket */
+        transport = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT,
+                                  "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+        g_assert (thrift_zlib_transport_open (transport, &err) == FALSE);
+        g_object_unref (transport);
+        g_object_unref (tsocket);
+        g_error_free (err);
+        err = NULL;
+       
+        g_assert ( wait (&status) == pid );
+        g_assert ( status == 0 );
+    }
+}
+
+static void
+test_read_and_write(void)
+{
+  int status;
+  pid_t pid;
+  ThriftSocket *tsocket = NULL;
+  ThriftTransport *transport = NULL;
+  int port = 51199;
+  gchar buf[36] = TEST_DATA;
+
+  pid = fork ();
+  g_assert ( pid >= 0 );
+
+  if ( pid == 0 )
+    {
+      /* child listens */
+      thrift_server (port);
+      exit (0);
+    } else {
+       /* parent connects, wait a bit for the socket to be created */
+       sleep (1);
+
+       tsocket = g_object_new (THRIFT_TYPE_SOCKET, "hostname", "localhost",
+                               "port", port, NULL);
+       transport = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT,
+                                 "transport", THRIFT_TRANSPORT (tsocket), NULL);
+
+       g_assert (thrift_zlib_transport_open (transport, NULL) == TRUE);
+       g_assert (thrift_zlib_transport_is_open (transport));
+
+       thrift_zlib_transport_write (transport, buf, 36, NULL);
+       thrift_zlib_transport_flush (transport, NULL);
+       thrift_zlib_transport_write_end (transport, NULL);
+
+       g_object_unref (transport);
+       g_object_unref (tsocket);
+
+       g_assert ( wait (&status) == pid );
+       g_assert ( status == 0 );
+    }
+}
+
+static void 
+thrift_socket_server_open (const int port, int times)
+{
+  ThriftServerTransport *transport = NULL;
+  ThriftTransport *client = NULL;
+  int i;
+
+  ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+                                              "port", port, NULL);
+
+  transport = THRIFT_SERVER_TRANSPORT (tsocket);
+  thrift_server_transport_listen (transport, NULL);
+  for(i=0;i<times;i++){
+      client = thrift_server_transport_accept (transport, NULL);
+      g_assert (client != NULL);
+      thrift_socket_close (client, NULL);
+      g_object_unref (client);
+  }
+  g_object_unref (tsocket);
+}
+
+static void
+thrift_server (const int port)
+{
+  int bytes = 0;
+  gboolean check_sum = FALSE;
+  ThriftServerTransport *transport = NULL;
+  ThriftTransport *client = NULL;
+  gchar buf[36];  /* a buffer */
+  gchar match[36] = TEST_DATA;
+  
+  ThriftServerSocket *tsocket = g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+                                              "port", port, NULL);
+
+  transport = THRIFT_SERVER_TRANSPORT (tsocket);
+  thrift_server_transport_listen (transport, NULL);
+
+  /* wrap the client in a ZlibTransport */
+  client = g_object_new (THRIFT_TYPE_ZLIB_TRANSPORT, "transport",
+                         thrift_server_transport_accept (transport, NULL),
+                         NULL);
+  g_assert (client != NULL);
+
+  /* read 36 bytes */
+  thrift_zlib_transport_read (client, buf, 36, NULL);
+  g_assert (memcmp(buf, match, 36) == 0 );
+
+  thrift_zlib_transport_read_end (client, NULL);
+
+  check_sum = thrift_zlib_transport_verify_checksum (client, NULL);
+  g_assert (!check_sum);
+
+  thrift_zlib_transport_close (client, NULL);
+  g_object_unref (client);
+  g_object_unref (tsocket);
+}
+
+int
+main(int argc, char *argv[])
+{
+#if (!GLIB_CHECK_VERSION (2, 36, 0))
+  g_type_init();
+#endif
+
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/testzlibtransport/CreateAndDestroy", test_create_and_destroy);
+  g_test_add_func ("/testzlibtransport/OpenAndClose", test_open_and_close);
+  g_test_add_func ("/testzlibtransport/ReadAndWrite", test_read_and_write);
+
+  return g_test_run ();
+}
diff --git a/lib/cpp/CMakeLists.txt b/lib/cpp/CMakeLists.txt
index b3a34d0..7a656c0 100755
--- a/lib/cpp/CMakeLists.txt
+++ b/lib/cpp/CMakeLists.txt
@@ -153,9 +153,9 @@
 
 ADD_LIBRARY_THRIFT(thrift ${thriftcpp_SOURCES} ${thriftcpp_threads_SOURCES})
 if(WIN32)
-    TARGET_LINK_LIBRARIES_THRIFT(thrift ${SYSLIBS} ws2_32)
+    TARGET_LINK_LIBRARIES_THRIFT(thrift PUBLIC ${SYSLIBS} ws2_32)
 else()
-    TARGET_LINK_LIBRARIES_THRIFT(thrift ${SYSLIBS})
+    TARGET_LINK_LIBRARIES_THRIFT(thrift PUBLIC ${SYSLIBS})
 endif()
 ADD_PKGCONFIG_THRIFT(thrift)
 
@@ -164,8 +164,13 @@
     include_directories(SYSTEM ${LIBEVENT_INCLUDE_DIRS})
 
     ADD_LIBRARY_THRIFT(thriftnb ${thriftcppnb_SOURCES})
-    LINK_AGAINST_THRIFT_LIBRARY(thriftnb thrift)
-    TARGET_LINK_LIBRARIES_THRIFT(thriftnb ${SYSLIBS} ${LIBEVENT_LIBRARIES})
+    LINK_AGAINST_THRIFT_LIBRARY(thriftnb PUBLIC thrift)
+    if(TARGET libevent::core AND TARGET libevent::extra)
+        # libevent was found via its cmake config, use modern style targets
+        TARGET_LINK_LIBRARIES_THRIFT(thriftnb PUBLIC libevent::core libevent::extra)
+    else()
+        TARGET_LINK_LIBRARIES_THRIFT(thriftnb PUBLIC ${LIBEVENT_LIBRARIES})
+    endif()
     ADD_PKGCONFIG_THRIFT(thrift-nb)
 endif()
 
@@ -174,8 +179,8 @@
     include_directories(SYSTEM ${ZLIB_INCLUDE_DIRS})
 
     ADD_LIBRARY_THRIFT(thriftz ${thriftcppz_SOURCES})
-    TARGET_LINK_LIBRARIES_THRIFT(thriftz ${SYSLIBS} ${ZLIB_LIBRARIES})
-    TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftz thrift)
+    LINK_AGAINST_THRIFT_LIBRARY(thriftz PUBLIC thrift)
+    TARGET_LINK_LIBRARIES_THRIFT(thriftz PUBLIC ${ZLIB_LIBRARIES})
     ADD_PKGCONFIG_THRIFT(thrift-z)
 endif()
 
diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am
index eab2e21..c015b0d 100755
--- a/lib/cpp/Makefile.am
+++ b/lib/cpp/Makefile.am
@@ -143,7 +143,8 @@
                          src/thrift/TLogging.h \
                          src/thrift/TToString.h \
                          src/thrift/TBase.h \
-                         src/thrift/TConfiguration.h
+                         src/thrift/TConfiguration.h \
+                         src/thrift/TNonCopyable.h
 
 include_concurrencydir = $(include_thriftdir)/concurrency
 include_concurrency_HEADERS = \
diff --git a/lib/as3/src/org/apache/thrift/meta_data/MapMetaData.as b/lib/cpp/src/thrift/TNonCopyable.h
similarity index 63%
rename from lib/as3/src/org/apache/thrift/meta_data/MapMetaData.as
rename to lib/cpp/src/thrift/TNonCopyable.h
index e7f1f9f..a60f1f0 100644
--- a/lib/as3/src/org/apache/thrift/meta_data/MapMetaData.as
+++ b/lib/cpp/src/thrift/TNonCopyable.h
@@ -17,17 +17,26 @@
  * under the License.
  */
 
-package org.apache.thrift.meta_data {
+#ifndef TNONCOPYABLE_H
+#define TNONCOPYABLE_H
 
-  public class MapMetaData extends FieldValueMetaData {
-  
-    public var keyMetaData:FieldValueMetaData;
-    public var valueMetaData:FieldValueMetaData;
-  
-    public function MapMetaData(type:int, kMetaData:FieldValueMetaData, vMetaData:FieldValueMetaData) {
-      super(type);
-      this.keyMetaData = kMetaData;
-      this.valueMetaData = vMetaData;
-    }
-  }    
-}
\ No newline at end of file
+/**
+ * @brief A simple non-copyable base class pattern. Derive from TNonCopyable to
+ * make a class non-copyable and prohibit assignment and copy-construction.
+ */
+namespace apache {
+namespace thrift {
+
+class TNonCopyable {
+protected:
+  TNonCopyable() = default;
+  ~TNonCopyable() = default;
+
+  TNonCopyable(const TNonCopyable&) = delete;
+  TNonCopyable& operator=(const TNonCopyable&) = delete;
+};
+
+}
+}
+
+#endif
diff --git a/lib/cpp/src/thrift/TToString.h b/lib/cpp/src/thrift/TToString.h
index 25780f9..79743fd 100644
--- a/lib/cpp/src/thrift/TToString.h
+++ b/lib/cpp/src/thrift/TToString.h
@@ -22,6 +22,7 @@
 
 #include <cmath>
 #include <limits>
+#include <locale>
 #include <map>
 #include <set>
 #include <sstream>
@@ -34,6 +35,7 @@
 template <typename T>
 std::string to_string(const T& t) {
   std::ostringstream o;
+  o.imbue(std::locale("C"));
   o << t;
   return o.str();
 }
@@ -42,6 +44,7 @@
 // is enabled.
 inline std::string to_string(const float& t) {
   std::ostringstream o;
+  o.imbue(std::locale("C"));
   o.precision(static_cast<std::streamsize>(std::ceil(static_cast<double>(std::numeric_limits<float>::digits * std::log10(2.0f) + 1))));
   o << t;
   return o.str();
@@ -49,6 +52,7 @@
 
 inline std::string to_string(const double& t) {
   std::ostringstream o;
+  o.imbue(std::locale("C"));
   o.precision(static_cast<std::streamsize>(std::ceil(static_cast<double>(std::numeric_limits<double>::digits * std::log10(2.0f) + 1))));
   o << t;
   return o.str();
@@ -56,6 +60,7 @@
 
 inline std::string to_string(const long double& t) {
   std::ostringstream o;
+  o.imbue(std::locale("C"));
   o.precision(static_cast<std::streamsize>(std::ceil(static_cast<double>(std::numeric_limits<long double>::digits * std::log10(2.0f) + 1))));
   o << t;
   return o.str();
diff --git a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp
index 0dac524..7f1b1cc 100644
--- a/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp
+++ b/lib/cpp/src/thrift/async/TConcurrentClientSyncInfo.cpp
@@ -184,7 +184,11 @@
       throw apache::thrift::TApplicationException(
         TApplicationException::BAD_SEQUENCE_ID,
         "about to repeat a seqid");
-  int32_t newSeqId = nextseqid_++;
+  int32_t newSeqId = nextseqid_;
+  if (nextseqid_ == (std::numeric_limits<int32_t>::max)())
+    nextseqid_ = (std::numeric_limits<int32_t>::min)();
+  else
+    ++nextseqid_;
   seqidToMonitorMap_[newSeqId] = newMonitor_(seqidGuard);
   return newSeqId;
 }
diff --git a/lib/cpp/src/thrift/concurrency/Monitor.h b/lib/cpp/src/thrift/concurrency/Monitor.h
index b3939cb..ada237a 100644
--- a/lib/cpp/src/thrift/concurrency/Monitor.h
+++ b/lib/cpp/src/thrift/concurrency/Monitor.h
@@ -23,6 +23,7 @@
 #include <chrono>
 #include <thrift/concurrency/Exception.h>
 #include <thrift/concurrency/Mutex.h>
+#include <thrift/TNonCopyable.h>
 
 namespace apache {
 namespace thrift {
@@ -46,7 +47,7 @@
  *
  * @version $Id:$
  */
-class Monitor : boost::noncopyable {
+class Monitor : apache::thrift::TNonCopyable {
 public:
   /** Creates a new mutex, and takes ownership of it. */
   Monitor();
diff --git a/lib/cpp/src/thrift/concurrency/Mutex.h b/lib/cpp/src/thrift/concurrency/Mutex.h
index 27e386e..1e5c3fb 100644
--- a/lib/cpp/src/thrift/concurrency/Mutex.h
+++ b/lib/cpp/src/thrift/concurrency/Mutex.h
@@ -21,7 +21,7 @@
 #define _THRIFT_CONCURRENCY_MUTEX_H_ 1
 
 #include <memory>
-#include <boost/noncopyable.hpp>
+#include <thrift/TNonCopyable.h>
 
 namespace apache {
 namespace thrift {
@@ -55,7 +55,7 @@
 };
 
 
-class Guard : boost::noncopyable {
+class Guard : apache::thrift::TNonCopyable {
 public:
   Guard(const Mutex& value, int64_t timeout = 0) : mutex_(&value) {
     if (timeout == 0) {
diff --git a/lib/cpp/src/thrift/qt/CMakeLists.txt b/lib/cpp/src/thrift/qt/CMakeLists.txt
index 04a9a31..fc1a2c2 100644
--- a/lib/cpp/src/thrift/qt/CMakeLists.txt
+++ b/lib/cpp/src/thrift/qt/CMakeLists.txt
@@ -24,5 +24,5 @@
 set(CMAKE_AUTOMOC ON)
 find_package(Qt5 REQUIRED COMPONENTS Core Network)
 ADD_LIBRARY_THRIFT(thriftqt5 ${thriftcppqt5_SOURCES})
-TARGET_LINK_LIBRARIES_THRIFT(thriftqt5 Qt5::Core Qt5::Network)
-TARGET_LINK_LIBRARIES_THRIFT_AGAINST_THRIFT_LIBRARY(thriftqt5 thrift)
+LINK_AGAINST_THRIFT_LIBRARY(thriftqt5 PUBLIC thrift)
+TARGET_LINK_LIBRARIES_THRIFT(thriftqt5 PUBLIC Qt5::Core Qt5::Network)
diff --git a/lib/cpp/src/thrift/transport/TBufferTransports.h b/lib/cpp/src/thrift/transport/TBufferTransports.h
index 179934b..8f527bb 100644
--- a/lib/cpp/src/thrift/transport/TBufferTransports.h
+++ b/lib/cpp/src/thrift/transport/TBufferTransports.h
@@ -658,6 +658,7 @@
     if (rBase_ == wBase_) {
       resetBuffer();
     }
+    resetConsumedMessageSize();
     return bytes;
   }
 
diff --git a/lib/cpp/src/thrift/transport/TPipe.cpp b/lib/cpp/src/thrift/transport/TPipe.cpp
index 953cec1..a18c4f7 100644
--- a/lib/cpp/src/thrift/transport/TPipe.cpp
+++ b/lib/cpp/src/thrift/transport/TPipe.cpp
@@ -40,7 +40,7 @@
 uint32_t pseudo_sync_read(HANDLE pipe, HANDLE event, uint8_t* buf, uint32_t len);
 void pseudo_sync_write(HANDLE pipe, HANDLE event, const uint8_t* buf, uint32_t len);
 
-class TPipeImpl : boost::noncopyable {
+class TPipeImpl : apache::thrift::TNonCopyable {
 public:
   TPipeImpl() {}
   virtual ~TPipeImpl() {}
@@ -223,7 +223,7 @@
 
 //---- Constructors ----
 TPipe::TPipe(TAutoHandle &Pipe, std::shared_ptr<TConfiguration> config)
-  : impl_(new TWaitableNamedPipeImpl(Pipe)), TimeoutSeconds_(3), 
+  : impl_(new TWaitableNamedPipeImpl(Pipe)), TimeoutSeconds_(3),
   isAnonymous_(false), TVirtualTransport(config) {
 }
 
@@ -234,12 +234,12 @@
   impl_.reset(new TWaitableNamedPipeImpl(pipeHandle));
 }
 
-TPipe::TPipe(const char* pipename, std::shared_ptr<TConfiguration> config) : TimeoutSeconds_(3), 
+TPipe::TPipe(const char* pipename, std::shared_ptr<TConfiguration> config) : TimeoutSeconds_(3),
   isAnonymous_(false), TVirtualTransport(config) {
   setPipename(pipename);
 }
 
-TPipe::TPipe(const std::string& pipename, std::shared_ptr<TConfiguration> config) : TimeoutSeconds_(3), 
+TPipe::TPipe(const std::string& pipename, std::shared_ptr<TConfiguration> config) : TimeoutSeconds_(3),
   isAnonymous_(false), TVirtualTransport(config) {
   setPipename(pipename);
 }
@@ -249,7 +249,7 @@
     TVirtualTransport(config) {
 }
 
-TPipe::TPipe(std::shared_ptr<TConfiguration> config) : TimeoutSeconds_(3), isAnonymous_(false), 
+TPipe::TPipe(std::shared_ptr<TConfiguration> config) : TimeoutSeconds_(3), isAnonymous_(false),
                                                        TVirtualTransport(config) {
 }
 
diff --git a/lib/cpp/src/thrift/transport/TPipe.h b/lib/cpp/src/thrift/transport/TPipe.h
index 7795151..ec0c442 100644
--- a/lib/cpp/src/thrift/transport/TPipe.h
+++ b/lib/cpp/src/thrift/transport/TPipe.h
@@ -28,7 +28,7 @@
 #ifdef _WIN32
 #include <thrift/windows/Sync.h>
 #endif
-#include <boost/noncopyable.hpp>
+#include <thrift/TNonCopyable.h>
 #ifdef _WIN32
 #include <thrift/windows/Sync.h>
 #endif
diff --git a/lib/cpp/src/thrift/transport/TPipeServer.cpp b/lib/cpp/src/thrift/transport/TPipeServer.cpp
index 2763551..1d7577f 100644
--- a/lib/cpp/src/thrift/transport/TPipeServer.cpp
+++ b/lib/cpp/src/thrift/transport/TPipeServer.cpp
@@ -22,7 +22,7 @@
 
 #include <thrift/transport/TPipe.h>
 #include <thrift/transport/TPipeServer.h>
-#include <boost/noncopyable.hpp>
+#include <thrift/TNonCopyable.h>
 
 #ifdef _WIN32
 #include <thrift/windows/OverlappedSubmissionThread.h>
@@ -39,7 +39,7 @@
 
 using std::shared_ptr;
 
-class TPipeServerImpl : boost::noncopyable {
+class TPipeServerImpl : apache::thrift::TNonCopyable {
 public:
   TPipeServerImpl() {}
   virtual ~TPipeServerImpl() {}
diff --git a/lib/cpp/src/thrift/transport/TSSLSocket.cpp b/lib/cpp/src/thrift/transport/TSSLSocket.cpp
index 9efc5fc..665f8f6 100644
--- a/lib/cpp/src/thrift/transport/TSSLSocket.cpp
+++ b/lib/cpp/src/thrift/transport/TSSLSocket.cpp
@@ -489,7 +489,7 @@
               && (errno_copy != THRIFT_EAGAIN)) {
             break;
           }
-        // fallthrough        
+        // fallthrough
         case SSL_ERROR_WANT_READ:
         case SSL_ERROR_WANT_WRITE:
           if (isLibeventSafe()) {
@@ -970,10 +970,12 @@
   if (strcmp(format, "PEM") == 0) {
     BIO* mem = BIO_new(BIO_s_mem());
     BIO_puts(mem, aCertificate);
-    X509* cert = PEM_read_bio_X509(mem, nullptr, 0, nullptr);
+    X509* cert = PEM_read_bio_X509(mem, nullptr, nullptr, nullptr);
     BIO_free(mem);
+    const int status = SSL_CTX_use_certificate(ctx_->get(), cert);
+    X509_free(cert);
 
-    if (SSL_CTX_use_certificate(ctx_->get(), cert) == 0) {
+    if (status != 1) {
       int errno_copy = THRIFT_GET_SOCKET_ERROR;
       string errors;
       buildErrors(errors, errno_copy);
@@ -1005,12 +1007,18 @@
                               "loadPrivateKey: either <path> or <format> is nullptr");
   }
   if (strcmp(format, "PEM") == 0) {
-    BIO* mem = BIO_new(BIO_s_mem());
+    EVP_PKEY* cert;
+    BIO* mem;
+
+    mem = BIO_new(BIO_s_mem());
     BIO_puts(mem, aPrivateKey);
-    EVP_PKEY* cert = PEM_read_bio_PrivateKey(mem, nullptr, nullptr, nullptr);
+    cert = PEM_read_bio_PrivateKey(mem, nullptr, nullptr, nullptr);
 
     BIO_free(mem);
-    if (SSL_CTX_use_PrivateKey(ctx_->get(), cert) == 0) {
+    const int status = SSL_CTX_use_PrivateKey(ctx_->get(), cert);
+    EVP_PKEY_free(cert);
+
+    if (status == 0) {
       int errno_copy = THRIFT_GET_SOCKET_ERROR;
       string errors;
       buildErrors(errors, errno_copy);
@@ -1040,12 +1048,15 @@
                               "loadTrustedCertificates: aCertificate is empty");
   }
   X509_STORE* vX509Store = SSL_CTX_get_cert_store(ctx_->get());
+
   BIO* mem = BIO_new(BIO_s_mem());
   BIO_puts(mem, aCertificate);
-  X509* cert = PEM_read_bio_X509(mem, nullptr, 0, nullptr);
+  X509* cert = PEM_read_bio_X509(mem, nullptr, nullptr, nullptr);
   BIO_free(mem);
+  const int status = X509_STORE_add_cert(vX509Store, cert);
+  X509_free(cert);
 
-  if (X509_STORE_add_cert(vX509Store, cert) == 0) {
+  if (status != 1) {
     int errno_copy = THRIFT_GET_SOCKET_ERROR;
     string errors;
     buildErrors(errors, errno_copy);
@@ -1055,10 +1066,14 @@
   if (aChain) {
     mem = BIO_new(BIO_s_mem());
     BIO_puts(mem, aChain);
-    cert = PEM_read_bio_X509(mem, nullptr, 0, nullptr);
+    cert = PEM_read_bio_X509(mem, nullptr, nullptr, nullptr);
     BIO_free(mem);
 
+    // NOTE: The x509 certificate provided to SSL_CTX_add_extra_chain_cert()
+    // will be freed by the library when the SSL_CTX is destroyed. Do not free
+    // the x509 object manually here.
     if (SSL_CTX_add_extra_chain_cert(ctx_->get(), cert) == 0) {
+      X509_free(cert);
       int errno_copy = THRIFT_GET_SOCKET_ERROR;
       string errors;
       buildErrors(errors, errno_copy);
diff --git a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp
index 5ac6fe0..02beec7 100644
--- a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp
+++ b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.cpp
@@ -19,7 +19,7 @@
 
 #include <thrift/windows/OverlappedSubmissionThread.h>
 #include <thrift/transport/TTransportException.h>
-#include <boost/noncopyable.hpp>
+#include <thrift/TNonCopyable.h>
 #include <boost/scope_exit.hpp>
 #include <process.h>
 
diff --git a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h
index dd0c5c9..6cecfc3 100644
--- a/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h
+++ b/lib/cpp/src/thrift/windows/OverlappedSubmissionThread.h
@@ -25,7 +25,7 @@
 #endif
 
 #include <thrift/windows/Sync.h>
-#include <boost/noncopyable.hpp>
+#include <thrift/TNonCopyable.h>
 #include <Windows.h>
 
 /*
@@ -89,7 +89,7 @@
   bool process();
 };
 
-class TOverlappedSubmissionThread : boost::noncopyable {
+class TOverlappedSubmissionThread : apache::thrift::TNonCopyable {
 public:
   void addWorkItem(TOverlappedWorkItem* item);
 
@@ -117,7 +117,7 @@
   HANDLE thread_;
 };
 
-class TAutoOverlapThread : boost::noncopyable {
+class TAutoOverlapThread : apache::thrift::TNonCopyable {
 private:
   TOverlappedSubmissionThread* p;
 
diff --git a/lib/cpp/src/thrift/windows/Sync.h b/lib/cpp/src/thrift/windows/Sync.h
index a296d7e..b1c83ee 100644
--- a/lib/cpp/src/thrift/windows/Sync.h
+++ b/lib/cpp/src/thrift/windows/Sync.h
@@ -25,7 +25,8 @@
 #endif
 
 #include <thrift/concurrency/Exception.h>
-#include <boost/noncopyable.hpp>
+#include <thrift/TNonCopyable.h>
+
 #include <Windows.h>
 
 /*
@@ -36,13 +37,13 @@
 namespace apache {
 namespace thrift {
 
-struct TCriticalSection : boost::noncopyable {
+struct TCriticalSection : apache::thrift::TNonCopyable {
   CRITICAL_SECTION cs;
   TCriticalSection() { InitializeCriticalSection(&cs); }
   ~TCriticalSection() { DeleteCriticalSection(&cs); }
 };
 
-class TAutoCrit : boost::noncopyable {
+class TAutoCrit : apache::thrift::TNonCopyable {
 private:
   CRITICAL_SECTION* cs_;
 
@@ -51,7 +52,7 @@
   ~TAutoCrit() { LeaveCriticalSection(cs_); }
 };
 
-struct TAutoResetEvent : boost::noncopyable {
+struct TAutoResetEvent : apache::thrift::TNonCopyable {
   HANDLE h;
 
   TAutoResetEvent() {
@@ -64,7 +65,7 @@
   ~TAutoResetEvent() { CloseHandle(h); }
 };
 
-struct TManualResetEvent : boost::noncopyable {
+struct TManualResetEvent : apache::thrift::TNonCopyable {
   HANDLE h;
 
   TManualResetEvent() {
@@ -77,7 +78,7 @@
   ~TManualResetEvent() { CloseHandle(h); }
 };
 
-struct TAutoHandle : boost::noncopyable {
+struct TAutoHandle : apache::thrift::TNonCopyable {
   HANDLE h;
   explicit TAutoHandle(HANDLE h_ = INVALID_HANDLE_VALUE) : h(h_) {}
   ~TAutoHandle() {
diff --git a/lib/cpp/src/thrift/windows/TWinsockSingleton.h b/lib/cpp/src/thrift/windows/TWinsockSingleton.h
index a30806b..a098d2c 100644
--- a/lib/cpp/src/thrift/windows/TWinsockSingleton.h
+++ b/lib/cpp/src/thrift/windows/TWinsockSingleton.h
@@ -31,7 +31,7 @@
 #include <thrift/thrift-config.h>
 
 // boost
-#include <boost/noncopyable.hpp>
+#include <thrift/TNonCopyable.h>
 
 #include <memory>
 #include <mutex>
@@ -45,7 +45,7 @@
  * Winsock2 must be intialised once only in order to create sockets. This class
  * performs a one time initialisation when create is called.
  */
-class TWinsockSingleton : private boost::noncopyable {
+class TWinsockSingleton : private apache::thrift::TNonCopyable {
 
 public:
   typedef std::shared_ptr<TWinsockSingleton> instance_ptr;
diff --git a/lib/cpp/test/CMakeLists.txt b/lib/cpp/test/CMakeLists.txt
index ced78a2..07c178d 100644
--- a/lib/cpp/test/CMakeLists.txt
+++ b/lib/cpp/test/CMakeLists.txt
@@ -20,7 +20,7 @@
 # Unit tests still require boost
 include(BoostMacros)
 REQUIRE_BOOST_HEADERS()
-set(BOOST_COMPONENTS chrono date_time filesystem random thread unit_test_framework)
+set(BOOST_COMPONENTS filesystem thread unit_test_framework)
 REQUIRE_BOOST_LIBRARIES(BOOST_COMPONENTS)
 
 include(ThriftMacros)
@@ -88,11 +88,11 @@
 target_link_libraries(UnitTests testgencpp ${Boost_LIBRARIES})
 LINK_AGAINST_THRIFT_LIBRARY(UnitTests thrift)
 add_test(NAME UnitTests COMMAND UnitTests)
-if ( MSVC )
+if(MSVC)
     # Disable C4503: decorated name length exceeded, name was truncated
     # 'insanity' results in very long decorated names
     set_property( TARGET UnitTests APPEND_STRING PROPERTY COMPILE_FLAGS /wd4503 )
-endif ( MSVC )
+endif()
 
 
 set( TInterruptTest_SOURCES
@@ -111,7 +111,7 @@
 )
 LINK_AGAINST_THRIFT_LIBRARY(TInterruptTest thrift)
 if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
-target_link_libraries(TInterruptTest -lrt)
+    target_link_libraries(TInterruptTest -lrt)
 endif ()
 add_test(NAME TInterruptTest COMMAND TInterruptTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
 
@@ -122,7 +122,7 @@
 )
 LINK_AGAINST_THRIFT_LIBRARY(TServerIntegrationTest thrift)
 if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
-target_link_libraries(TServerIntegrationTest -lrt)
+    target_link_libraries(TServerIntegrationTest -lrt)
 endif ()
 add_test(NAME TServerIntegrationTest COMMAND TServerIntegrationTest)
 
@@ -205,13 +205,13 @@
 
 # The debug run-time in Windows asserts on isprint() with negative inputs
 if (NOT MSVC OR (MSVC AND CMAKE_BUILD_TYPE EQUAL "DEBUG"))
-add_executable(DebugProtoTest DebugProtoTest.cpp)
-target_link_libraries(DebugProtoTest
-    testgencpp
-    ${Boost_LIBRARIES}
-)
-LINK_AGAINST_THRIFT_LIBRARY(DebugProtoTest thrift)
-add_test(NAME DebugProtoTest COMMAND DebugProtoTest)
+    add_executable(DebugProtoTest DebugProtoTest.cpp)
+    target_link_libraries(DebugProtoTest
+        testgencpp
+        ${Boost_LIBRARIES}
+    )
+    LINK_AGAINST_THRIFT_LIBRARY(DebugProtoTest thrift)
+    add_test(NAME DebugProtoTest COMMAND DebugProtoTest)
 endif()
 
 add_executable(JSONProtoTest JSONProtoTest.cpp)
@@ -270,49 +270,44 @@
 add_test(NAME link_test COMMAND link_test)
 
 if(WITH_LIBEVENT)
-set(processor_test_SOURCES
-    processor/ProcessorTest.cpp
-    processor/EventLog.cpp
-    processor/ServerThread.cpp
-    processor/EventLog.h
-    processor/Handlers.h
-    processor/ServerThread.h
-)
-add_executable(processor_test ${processor_test_SOURCES})
-target_link_libraries(processor_test
-    testgencpp_cob
-    ${Boost_LIBRARIES}
-)
-LINK_AGAINST_THRIFT_LIBRARY(processor_test thrift)
-LINK_AGAINST_THRIFT_LIBRARY(processor_test thriftnb)
-add_test(NAME processor_test COMMAND processor_test)
+    set(processor_test_SOURCES
+        processor/ProcessorTest.cpp
+        processor/EventLog.cpp
+        processor/ServerThread.cpp
+        processor/EventLog.h
+        processor/Handlers.h
+        processor/ServerThread.h
+    )
+    add_executable(processor_test ${processor_test_SOURCES})
+    target_link_libraries(processor_test
+        testgencpp_cob
+        ${Boost_LIBRARIES}
+    )
+    LINK_AGAINST_THRIFT_LIBRARY(processor_test thriftnb)
+    add_test(NAME processor_test COMMAND processor_test)
 
-set(TNonblockingServerTest_SOURCES TNonblockingServerTest.cpp)
-add_executable(TNonblockingServerTest ${TNonblockingServerTest_SOURCES})
-include_directories(${LIBEVENT_INCLUDE_DIRS})
-target_link_libraries(TNonblockingServerTest
-    testgencpp_cob
-    ${LIBEVENT_LIBRARIES}
-    ${Boost_LIBRARIES}
-)
-LINK_AGAINST_THRIFT_LIBRARY(TNonblockingServerTest thrift)
-LINK_AGAINST_THRIFT_LIBRARY(TNonblockingServerTest thriftnb)
-add_test(NAME TNonblockingServerTest COMMAND TNonblockingServerTest)
+    set(TNonblockingServerTest_SOURCES TNonblockingServerTest.cpp)
+    add_executable(TNonblockingServerTest ${TNonblockingServerTest_SOURCES})
+    include_directories(${LIBEVENT_INCLUDE_DIRS})
+    target_link_libraries(TNonblockingServerTest
+        testgencpp_cob
+        ${Boost_LIBRARIES}
+    )
+    LINK_AGAINST_THRIFT_LIBRARY(TNonblockingServerTest thriftnb)
+    add_test(NAME TNonblockingServerTest COMMAND TNonblockingServerTest)
 
-if(OPENSSL_FOUND AND WITH_OPENSSL)
-  set(TNonblockingSSLServerTest_SOURCES TNonblockingSSLServerTest.cpp)
-  add_executable(TNonblockingSSLServerTest ${TNonblockingSSLServerTest_SOURCES})
-  include_directories(${LIBEVENT_INCLUDE_DIRS})
-  target_link_libraries(TNonblockingSSLServerTest
-    testgencpp_cob
-    ${LIBEVENT_LIBRARIES}
-    ${Boost_LIBRARIES}
-  )
-  LINK_AGAINST_THRIFT_LIBRARY(TNonblockingSSLServerTest thrift)
-  LINK_AGAINST_THRIFT_LIBRARY(TNonblockingSSLServerTest thriftnb)
-  add_test(NAME TNonblockingSSLServerTest COMMAND TNonblockingSSLServerTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
-endif(OPENSSL_FOUND AND WITH_OPENSSL)
-endif(WITH_LIBEVENT)
+    if(OPENSSL_FOUND AND WITH_OPENSSL)
+      set(TNonblockingSSLServerTest_SOURCES TNonblockingSSLServerTest.cpp)
+      add_executable(TNonblockingSSLServerTest ${TNonblockingSSLServerTest_SOURCES})
+      include_directories(${LIBEVENT_INCLUDE_DIRS})
+      target_link_libraries(TNonblockingSSLServerTest
+        testgencpp_cob
+        ${Boost_LIBRARIES}
+      )
+      LINK_AGAINST_THRIFT_LIBRARY(TNonblockingSSLServerTest thriftnb)
+      add_test(NAME TNonblockingSSLServerTest COMMAND TNonblockingSSLServerTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
+    endif(OPENSSL_FOUND AND WITH_OPENSSL)
+endif()
 
 if(OPENSSL_FOUND AND WITH_OPENSSL)
 add_executable(OpenSSLManualInitTest OpenSSLManualInitTest.cpp)
@@ -330,7 +325,7 @@
 )
 LINK_AGAINST_THRIFT_LIBRARY(SecurityTest thrift)
 if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
-target_link_libraries(SecurityTest -lrt)
+    target_link_libraries(SecurityTest -lrt)
 endif ()
 add_test(NAME SecurityTest COMMAND SecurityTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
 
@@ -341,14 +336,14 @@
 )
 LINK_AGAINST_THRIFT_LIBRARY(SecurityFromBufferTest thrift)
 if (NOT MSVC AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND NOT MINGW)
-target_link_libraries(SecurityFromBufferTest -lrt)
+    target_link_libraries(SecurityFromBufferTest -lrt)
 endif ()
 add_test(NAME SecurityFromBufferTest COMMAND SecurityFromBufferTest -- "${CMAKE_CURRENT_SOURCE_DIR}/../../../test/keys")
 
 endif()
 
 if(WITH_QT5)
-add_subdirectory(qt)
+    add_subdirectory(qt)
 endif()
 
 #
diff --git a/lib/cpp/test/SecurityTest.cpp b/lib/cpp/test/SecurityTest.cpp
index 982a4f3..b70729c 100644
--- a/lib/cpp/test/SecurityTest.cpp
+++ b/lib/cpp/test/SecurityTest.cpp
@@ -219,6 +219,7 @@
     try
     {
         // matrix of connection success between client and server with different SSLProtocol selections
+        static_assert(apache::thrift::transport::LATEST == 5, "Mismatch in assumed number of ssl protocols");
         bool matrix[apache::thrift::transport::LATEST + 1][apache::thrift::transport::LATEST + 1] =
         {
     //   server    = SSLTLS   SSLv2    SSLv3    TLSv1_0  TLSv1_1  TLSv1_2
diff --git a/lib/cpp/test/ToStringTest.cpp b/lib/cpp/test/ToStringTest.cpp
index 5a05ed7..722e590 100644
--- a/lib/cpp/test/ToStringTest.cpp
+++ b/lib/cpp/test/ToStringTest.cpp
@@ -19,6 +19,7 @@
 
 #include <vector>
 #include <map>
+#include <locale>
 
 #include <boost/test/unit_test.hpp>
 
@@ -40,6 +41,26 @@
   BOOST_CHECK_EQUAL(to_string("abc"), "abc");
 }
 
+BOOST_AUTO_TEST_CASE(locale_en_US_int_to_string) {
+#if _WIN32
+  std::locale::global(std::locale("en-US.UTF-8"));
+#else
+  std::locale::global(std::locale("en_US.UTF-8"));
+#endif
+  BOOST_CHECK_EQUAL(to_string(1000000), "1000000");
+}
+
+BOOST_AUTO_TEST_CASE(locale_de_DE_floating_point_to_string) {
+#if _WIN32
+  std::locale::global(std::locale("de-DE.UTF-8"));
+#else
+  std::locale::global(std::locale("de_DE.UTF-8"));
+#endif
+  BOOST_CHECK_EQUAL(to_string(1.5), "1.5");
+  BOOST_CHECK_EQUAL(to_string(1.5f), "1.5");
+  BOOST_CHECK_EQUAL(to_string(1.5L), "1.5");
+}
+
 BOOST_AUTO_TEST_CASE(empty_vector_to_string) {
   std::vector<int> l;
   BOOST_CHECK_EQUAL(to_string(l), "[]");
diff --git a/lib/d/Makefile.am b/lib/d/Makefile.am
index 4787e0a..0137217 100644
--- a/lib/d/Makefile.am
+++ b/lib/d/Makefile.am
@@ -97,7 +97,7 @@
 	$(d_openssl_dependent_modules),$(d_modules))
 
 
-d_lib_flags = -w -wi -Isrc -lib
+d_lib_flags = -w -wi -Isrc -lib -version=use_openssl_1_0_x
 all_targets =
 
 #
@@ -153,7 +153,7 @@
 #
 # Unit tests (built both in debug and release mode).
 #
-d_test_flags = -unittest -w -wi -I$(top_srcdir)/lib/d/src
+d_test_flags = -unittest -w -wi -I$(top_srcdir)/lib/d/src -version=use_openssl_1_0_x
 
 # There just must be some way to reassign a variable without warnings in
 # Automake...
diff --git a/lib/d/src/thrift/base.d b/lib/d/src/thrift/base.d
index 4c1d0c3..6c49afe 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.14.2";
+enum VERSION = "0.15.0";
 
 /**
  * Functions used for logging inside Thrift.
diff --git a/lib/d/src/thrift/internal/ssl.d b/lib/d/src/thrift/internal/ssl.d
index 3af54b5..29cc6d0 100644
--- a/lib/d/src/thrift/internal/ssl.d
+++ b/lib/d/src/thrift/internal/ssl.d
@@ -89,6 +89,20 @@
   // Check subjectAltName(s), if present.
   auto alternatives = cast(STACK_OF!(GENERAL_NAME)*)
     X509_get_ext_d2i(cert, NID_subject_alt_name, null, null);
+
+  version(use_openssl_1_0_x) {
+    enum _GEN_DNS = GENERAL_NAME.GEN_DNS;
+    enum _GEN_IPADD = GENERAL_NAME.GEN_IPADD;
+  } else version(use_openssl_1_1_x) {
+    enum _GEN_DNS = GEN_DNS;
+    enum _GEN_IPADD = GEN_IPADD;
+  } else {
+    static assert(false, `Must have version either use_openssl_1_0_x or use_openssl_1_1_x defined, e.g.
+	"subConfigurations": {
+		"apache-thrift": "use_openssl_1_0"
+	}`);
+  }
+
   if (alternatives != null) {
     auto count = sk_GENERAL_NAME_num(alternatives);
     for (int i = 0; decision == Decision.SKIP && i < count; i++) {
@@ -98,11 +112,12 @@
       }
       auto data = ASN1_STRING_data(name.d.ia5);
       auto length = ASN1_STRING_length(name.d.ia5);
+
       switch (name.type) {
-        case GENERAL_NAME.GEN_DNS:
+        case _GEN_DNS:
           decision = accessManager.verify(hostName, cast(char[])data[0 .. length]);
           break;
-        case GENERAL_NAME.GEN_IPADD:
+        case _GEN_IPADD:
           decision = accessManager.verify(peerAddress, data[0 .. length]);
           break;
         default:
diff --git a/lib/d/test/thrift_test_client.d b/lib/d/test/thrift_test_client.d
index c9911e2..e7b644c 100644
--- a/lib/d/test/thrift_test_client.d
+++ b/lib/d/test/thrift_test_client.d
@@ -19,7 +19,7 @@
 module thrift_test_client;
 
 import std.conv;
-import std.datetime;
+import std.datetime.stopwatch;
 import std.exception : enforce;
 import std.getopt;
 import std.stdio;
@@ -348,14 +348,14 @@
       auto onewayWatch = StopWatch(AutoStart.yes);
       client.testOneway(3);
       onewayWatch.stop();
-      if (onewayWatch.peek().msecs > 200) {
+      if (onewayWatch.peek.total!"msecs" > 200) {
         if (trace) {
-          writefln("  FAILURE - took %s ms", onewayWatch.peek().usecs / 1000.0);
+          writefln("  FAILURE - took %s ms", onewayWatch.peek.total!"usecs" / 1000.0);
         }
         throw new Exception("testOneway failed.");
       } else {
         if (trace) {
-          writefln("  success - took %s ms", onewayWatch.peek().usecs / 1000.0);
+          writefln("  success - took %s ms", onewayWatch.peek.total!"usecs"  / 1000.0);
         }
       }
 
@@ -370,7 +370,7 @@
     // Time metering.
     sw.stop();
 
-    immutable tot = sw.peek().usecs;
+    immutable tot = sw.peek.total!"usecs" ;
     if (trace) writefln("Total time: %s us\n", tot);
 
     time_tot += tot;
diff --git a/lib/dart/.analysis_options b/lib/dart/.analysis_options
deleted file mode 100644
index a10d4c5..0000000
--- a/lib/dart/.analysis_options
+++ /dev/null
@@ -1,2 +0,0 @@
-analyzer:
-  strong-mode: true
diff --git a/lib/dart/Makefile.am b/lib/dart/Makefile.am
index 373a883..bd12a92 100644
--- a/lib/dart/Makefile.am
+++ b/lib/dart/Makefile.am
@@ -34,6 +34,3 @@
 	find $(distdir) -type f -name ".packages" | xargs $(RM)
 	find $(distdir) -type d -name "packages" | xargs $(RM) -r
 
-EXTRA_DIST = \
-	.analysis_options
-
diff --git a/build/cmake/FindCabal.cmake b/lib/dart/analysis_options.yaml
similarity index 69%
copy from build/cmake/FindCabal.cmake
copy to lib/dart/analysis_options.yaml
index fed337b..6a8a33c 100644
--- a/build/cmake/FindCabal.cmake
+++ b/lib/dart/analysis_options.yaml
@@ -17,14 +17,4 @@
 # under the License.
 #
 
-
-#  Cabal_FOUND - system has Cabal
-#  Cabal - the Cabal executable
-#
-# It will search the environment variable CABAL_HOME if it is set
-
-include(FindPackageHandleStandardArgs)
-
-find_program(CABAL NAMES cabal PATHS $ENV{HOME}/.cabal/bin $ENV{CABAL_HOME}/bin)
-find_package_handle_standard_args(CABAL DEFAULT_MSG CABAL)
-mark_as_advanced(CABAL)
+include: package:workiva_analysis_options/v1.yaml
diff --git a/lib/dart/lib/src/browser/t_web_socket.dart b/lib/dart/lib/src/browser/t_web_socket.dart
index dac9ffd..1d0bfeb 100644
--- a/lib/dart/lib/src/browser/t_web_socket.dart
+++ b/lib/dart/lib/src/browser/t_web_socket.dart
@@ -18,7 +18,7 @@
 library thrift.src.browser;
 
 import 'dart:async';
-import 'package:dart2_constant/convert.dart' show base64;
+import 'dart:convert' show base64;
 import 'dart:html' show CloseEvent;
 import 'dart:html' show Event;
 import 'dart:html' show MessageEvent;
@@ -32,39 +32,45 @@
   final Uri url;
 
   final StreamController<TSocketState> _onStateController;
+  @override
   Stream<TSocketState> get onState => _onStateController.stream;
 
   final StreamController<Object> _onErrorController;
+  @override
   Stream<Object> get onError => _onErrorController.stream;
 
   final StreamController<Uint8List> _onMessageController;
+  @override
   Stream<Uint8List> get onMessage => _onMessageController.stream;
 
   final List<Uint8List> _requests = [];
 
   TWebSocket(this.url)
-      : _onStateController = new StreamController.broadcast(),
-        _onErrorController = new StreamController.broadcast(),
-        _onMessageController = new StreamController.broadcast() {
+      : _onStateController = StreamController.broadcast(),
+        _onErrorController = StreamController.broadcast(),
+        _onMessageController = StreamController.broadcast() {
     if (url == null || !url.hasAuthority || !url.hasPort) {
-      throw new ArgumentError('Invalid url');
+      throw ArgumentError('Invalid url');
     }
   }
 
   WebSocket _socket;
 
+  @override
   bool get isOpen => _socket != null && _socket.readyState == WebSocket.OPEN;
 
+  @override
   bool get isClosed =>
       _socket == null || _socket.readyState == WebSocket.CLOSED;
 
+  @override
   Future open() {
     if (!isClosed) {
-      throw new TTransportError(
+      throw TTransportError(
           TTransportErrorType.ALREADY_OPEN, 'Socket already connected');
     }
 
-    _socket = new WebSocket(url.toString());
+    _socket = WebSocket(url.toString());
     _socket.onError.listen(_onError);
     _socket.onOpen.listen(_onOpen);
     _socket.onClose.listen(_onClose);
@@ -73,15 +79,17 @@
     return _socket.onOpen.first;
   }
 
+  @override
   Future close() {
     if (_socket != null) {
       _socket.close();
       return _socket.onClose.first;
     } else {
-      return new Future.value();
+      return Future.value();
     }
   }
 
+  @override
   void send(Uint8List data) {
     _requests.add(data);
     _sendRequests();
@@ -104,7 +112,7 @@
 
     if (_requests.isNotEmpty) {
       _onErrorController
-          .add(new StateError('Socket was closed with pending requests'));
+          .add(StateError('Socket was closed with pending requests'));
     }
     _requests.clear();
 
@@ -113,10 +121,10 @@
 
   void _onMessage(MessageEvent message) {
     try {
-      Uint8List data = new Uint8List.fromList(base64.decode(message.data));
+      Uint8List data = Uint8List.fromList(base64.decode(message.data));
       _onMessageController.add(data);
     } on FormatException catch (_) {
-      var error = new TProtocolError(TProtocolErrorType.INVALID_DATA,
+      var error = TProtocolError(TProtocolErrorType.INVALID_DATA,
           "Expected a Base 64 encoded string.");
       _onErrorController.add(error);
     }
diff --git a/lib/dart/lib/src/console/t_tcp_socket.dart b/lib/dart/lib/src/console/t_tcp_socket.dart
index b714803..610d633 100644
--- a/lib/dart/lib/src/console/t_tcp_socket.dart
+++ b/lib/dart/lib/src/console/t_tcp_socket.dart
@@ -26,20 +26,23 @@
 /// A [TSocket] backed by a [Socket] from dart:io
 class TTcpSocket implements TSocket {
   final StreamController<TSocketState> _onStateController;
+  @override
   Stream<TSocketState> get onState => _onStateController.stream;
 
   final StreamController<Object> _onErrorController;
+  @override
   Stream<Object> get onError => _onErrorController.stream;
 
   final StreamController<Uint8List> _onMessageController;
+  @override
   Stream<Uint8List> get onMessage => _onMessageController.stream;
 
   TTcpSocket(Socket socket)
-      : _onStateController = new StreamController.broadcast(),
-        _onErrorController = new StreamController.broadcast(),
-        _onMessageController = new StreamController.broadcast() {
+      : _onStateController = StreamController.broadcast(),
+        _onErrorController = StreamController.broadcast(),
+        _onMessageController = StreamController.broadcast() {
     if (socket == null) {
-      throw new ArgumentError.notNull('socket');
+      throw ArgumentError.notNull('socket');
     }
 
     _socket = socket;
@@ -48,14 +51,18 @@
 
   Socket _socket;
 
+  @override
   bool get isOpen => _socket != null;
 
+  @override
   bool get isClosed => _socket == null;
 
+  @override
   Future open() async {
     _onStateController.add(TSocketState.OPEN);
   }
 
+  @override
   Future close() async {
     if (_socket != null) {
       await _socket.close();
@@ -65,12 +72,13 @@
     _onStateController.add(TSocketState.CLOSED);
   }
 
+  @override
   void send(Uint8List data) {
     _socket.add(data);
   }
 
   void _onMessage(List<int> message) {
-    Uint8List data = new Uint8List.fromList(message);
+    Uint8List data = Uint8List.fromList(message);
     _onMessageController.add(data);
   }
 
diff --git a/lib/dart/lib/src/console/t_web_socket.dart b/lib/dart/lib/src/console/t_web_socket.dart
index c938a96..d69cafe 100644
--- a/lib/dart/lib/src/console/t_web_socket.dart
+++ b/lib/dart/lib/src/console/t_web_socket.dart
@@ -18,7 +18,7 @@
 library thrift.src.console.t_web_socket;
 
 import 'dart:async';
-import 'package:dart2_constant/convert.dart' show base64;
+import 'dart:convert' show base64;
 import 'dart:io';
 import 'dart:typed_data' show Uint8List;
 
@@ -27,20 +27,23 @@
 /// A [TSocket] backed by a [WebSocket] from dart:io
 class TWebSocket implements TSocket {
   final StreamController<TSocketState> _onStateController;
+  @override
   Stream<TSocketState> get onState => _onStateController.stream;
 
   final StreamController<Object> _onErrorController;
+  @override
   Stream<Object> get onError => _onErrorController.stream;
 
   final StreamController<Uint8List> _onMessageController;
+  @override
   Stream<Uint8List> get onMessage => _onMessageController.stream;
 
   TWebSocket(WebSocket socket)
-      : _onStateController = new StreamController.broadcast(),
-        _onErrorController = new StreamController.broadcast(),
-        _onMessageController = new StreamController.broadcast() {
+      : _onStateController = StreamController.broadcast(),
+        _onErrorController = StreamController.broadcast(),
+        _onMessageController = StreamController.broadcast() {
     if (socket == null) {
-      throw new ArgumentError.notNull('socket');
+      throw ArgumentError.notNull('socket');
     }
 
     _socket = socket;
@@ -49,14 +52,18 @@
 
   WebSocket _socket;
 
+  @override
   bool get isOpen => _socket != null;
 
+  @override
   bool get isClosed => _socket == null;
 
+  @override
   Future open() async {
     _onStateController.add(TSocketState.OPEN);
   }
 
+  @override
   Future close() async {
     if (_socket != null) {
       await _socket.close();
@@ -66,16 +73,17 @@
     _onStateController.add(TSocketState.CLOSED);
   }
 
+  @override
   void send(Uint8List data) {
     _socket.add(base64.encode(data));
   }
 
   void _onMessage(String message) {
     try {
-      Uint8List data = new Uint8List.fromList(base64.decode(message));
+      Uint8List data = Uint8List.fromList(base64.decode(message));
       _onMessageController.add(data);
     } on FormatException catch (_) {
-      var error = new TProtocolError(TProtocolErrorType.INVALID_DATA,
+      var error = TProtocolError(TProtocolErrorType.INVALID_DATA,
           "Expected a Base 64 encoded string.");
       _onErrorController.add(error);
     }
diff --git a/lib/dart/lib/src/protocol/t_binary_protocol.dart b/lib/dart/lib/src/protocol/t_binary_protocol.dart
index a785d81..9f8f3bf 100644
--- a/lib/dart/lib/src/protocol/t_binary_protocol.dart
+++ b/lib/dart/lib/src/protocol/t_binary_protocol.dart
@@ -18,13 +18,14 @@
 part of thrift;
 
 class TBinaryProtocolFactory implements TProtocolFactory<TBinaryProtocol> {
-  TBinaryProtocolFactory({this.strictRead: false, this.strictWrite: true});
+  TBinaryProtocolFactory({this.strictRead = false, this.strictWrite = true});
 
   final bool strictRead;
   final bool strictWrite;
 
+  @override
   TBinaryProtocol getProtocol(TTransport transport) {
-    return new TBinaryProtocol(transport,
+    return TBinaryProtocol(transport,
         strictRead: strictRead, strictWrite: strictWrite);
   }
 }
@@ -36,16 +37,17 @@
   static const int VERSION_MASK = 0xffff0000;
   static const int VERSION_1 = 0x80010000;
 
-  static const Utf8Codec _utf8Codec = const Utf8Codec();
+  static const Utf8Codec _utf8Codec = Utf8Codec();
 
   final bool strictRead;
   final bool strictWrite;
 
   TBinaryProtocol(TTransport transport,
-      {this.strictRead: false, this.strictWrite: true})
+      {this.strictRead = false, this.strictWrite = true})
       : super(transport);
 
   /// write
+  @override
   void writeMessageBegin(TMessage message) {
     if (strictWrite) {
       int version = VERSION_1 | message.type;
@@ -59,75 +61,96 @@
     }
   }
 
+  @override
   void writeMessageEnd() {}
 
+  @override
   void writeStructBegin(TStruct struct) {}
 
+  @override
   void writeStructEnd() {}
 
+  @override
   void writeFieldBegin(TField field) {
     writeByte(field.type);
     writeI16(field.id);
   }
 
+  @override
   void writeFieldEnd() {}
 
+  @override
   void writeFieldStop() {
     writeByte(TType.STOP);
   }
 
+  @override
   void writeMapBegin(TMap map) {
     writeByte(map.keyType);
     writeByte(map.valueType);
     writeI32(map.length);
   }
 
+  @override
   void writeMapEnd() {}
 
+  @override
   void writeListBegin(TList list) {
     writeByte(list.elementType);
     writeI32(list.length);
   }
 
+  @override
   void writeListEnd() {}
 
+  @override
   void writeSetBegin(TSet set) {
     writeByte(set.elementType);
     writeI32(set.length);
   }
 
+  @override
   void writeSetEnd() {}
 
+  @override
   void writeBool(bool b) {
     if (b == null) b = false;
     writeByte(b ? 1 : 0);
   }
 
-  final ByteData _byteOut = new ByteData(1);
+  final ByteData _byteOut = ByteData(1);
+
+  @override
   void writeByte(int byte) {
     if (byte == null) byte = 0;
     _byteOut.setUint8(0, byte);
     transport.write(_byteOut.buffer.asUint8List(), 0, 1);
   }
 
-  final ByteData _i16Out = new ByteData(2);
+  final ByteData _i16Out = ByteData(2);
+
+  @override
   void writeI16(int i16) {
     if (i16 == null) i16 = 0;
     _i16Out.setInt16(0, i16);
     transport.write(_i16Out.buffer.asUint8List(), 0, 2);
   }
 
-  final ByteData _i32Out = new ByteData(4);
+  final ByteData _i32Out = ByteData(4);
+
+  @override
   void writeI32(int i32) {
     if (i32 == null) i32 = 0;
     _i32Out.setInt32(0, i32);
     transport.write(_i32Out.buffer.asUint8List(), 0, 4);
   }
 
-  final Uint8List _i64Out = new Uint8List(8);
+  final Uint8List _i64Out = Uint8List(8);
+
+  @override
   void writeI64(int i64) {
     if (i64 == null) i64 = 0;
-    var i = new Int64(i64);
+    var i = Int64(i64);
     var bts = i.toBytes();
     for (var j = 0; j < 8; j++) {
       _i64Out[j] = bts[8 - j - 1];
@@ -135,19 +158,23 @@
     transport.write(_i64Out, 0, 8);
   }
 
+  @override
   void writeString(String s) {
-    var bytes = s != null ? _utf8Codec.encode(s) : new Uint8List.fromList([]);
+    var bytes = s != null ? _utf8Codec.encode(s) : Uint8List.fromList([]);
     writeI32(bytes.length);
     transport.write(bytes, 0, bytes.length);
   }
 
-  final ByteData _doubleOut = new ByteData(8);
+  final ByteData _doubleOut = ByteData(8);
+
+  @override
   void writeDouble(double d) {
     if (d == null) d = 0.0;
     _doubleOut.setFloat64(0, d);
     transport.write(_doubleOut.buffer.asUint8List(), 0, 8);
   }
 
+  @override
   void writeBinary(Uint8List bytes) {
     var length = bytes.length;
     writeI32(length);
@@ -155,6 +182,7 @@
   }
 
   /// read
+  @override
   TMessage readMessageBegin() {
     String name;
     int type;
@@ -164,7 +192,7 @@
     if (size < 0) {
       int version = size & VERSION_MASK;
       if (version != VERSION_1) {
-        throw new TProtocolError(TProtocolErrorType.BAD_VERSION,
+        throw TProtocolError(TProtocolErrorType.BAD_VERSION,
             "Bad version in readMessageBegin: $version");
       }
       type = size & 0x000000ff;
@@ -172,109 +200,133 @@
       seqid = readI32();
     } else {
       if (strictRead) {
-        throw new TProtocolError(TProtocolErrorType.BAD_VERSION,
+        throw TProtocolError(TProtocolErrorType.BAD_VERSION,
             "Missing version in readMessageBegin");
       }
       name = _readString(size);
       type = readByte();
       seqid = readI32();
     }
-    return new TMessage(name, type, seqid);
+    return TMessage(name, type, seqid);
   }
 
+  @override
   void readMessageEnd() {}
 
+  @override
   TStruct readStructBegin() {
-    return new TStruct();
+    return TStruct();
   }
 
+  @override
   void readStructEnd() {}
 
+  @override
   TField readFieldBegin() {
     String name = "";
     int type = readByte();
     int id = type != TType.STOP ? readI16() : 0;
 
-    return new TField(name, type, id);
+    return TField(name, type, id);
   }
 
+  @override
   void readFieldEnd() {}
 
+  @override
   TMap readMapBegin() {
     int keyType = readByte();
     int valueType = readByte();
     int length = readI32();
 
-    return new TMap(keyType, valueType, length);
+    return TMap(keyType, valueType, length);
   }
 
+  @override
   void readMapEnd() {}
 
+  @override
   TList readListBegin() {
     int elementType = readByte();
     int length = readI32();
 
-    return new TList(elementType, length);
+    return TList(elementType, length);
   }
 
+  @override
   void readListEnd() {}
 
+  @override
   TSet readSetBegin() {
     int elementType = readByte();
     int length = readI32();
 
-    return new TSet(elementType, length);
+    return TSet(elementType, length);
   }
 
+  @override
   void readSetEnd() {}
 
+  @override
   bool readBool() => readByte() == 1;
 
-  final Uint8List _byteIn = new Uint8List(1);
+  final Uint8List _byteIn = Uint8List(1);
+
+  @override
   int readByte() {
     transport.readAll(_byteIn, 0, 1);
     return _byteIn.buffer.asByteData().getUint8(0);
   }
 
-  final Uint8List _i16In = new Uint8List(2);
+  final Uint8List _i16In = Uint8List(2);
+
+  @override
   int readI16() {
     transport.readAll(_i16In, 0, 2);
     return _i16In.buffer.asByteData().getInt16(0);
   }
 
-  final Uint8List _i32In = new Uint8List(4);
+  final Uint8List _i32In = Uint8List(4);
+
+  @override
   int readI32() {
     transport.readAll(_i32In, 0, 4);
     return _i32In.buffer.asByteData().getInt32(0);
   }
 
-  final Uint8List _i64In = new Uint8List(8);
+  final Uint8List _i64In = Uint8List(8);
+
+  @override
   int readI64() {
     transport.readAll(_i64In, 0, 8);
-    var i = new Int64.fromBytesBigEndian(_i64In);
+    var i = Int64.fromBytesBigEndian(_i64In);
     return i.toInt();
   }
 
-  final Uint8List _doubleIn = new Uint8List(8);
+  final Uint8List _doubleIn = Uint8List(8);
+
+  @override
   double readDouble() {
     transport.readAll(_doubleIn, 0, 8);
     return _doubleIn.buffer.asByteData().getFloat64(0);
   }
 
+  @override
   String readString() {
     int size = readI32();
     return _readString(size);
   }
 
   String _readString(int size) {
-    Uint8List stringIn = new Uint8List(size);
+    Uint8List stringIn = Uint8List(size);
     transport.readAll(stringIn, 0, size);
     return _utf8Codec.decode(stringIn);
   }
 
+  @override
   Uint8List readBinary() {
     int length = readI32();
-    Uint8List binaryIn = new Uint8List(length);
+    Uint8List binaryIn = Uint8List(length);
     transport.readAll(binaryIn, 0, length);
     return binaryIn;
   }
diff --git a/lib/dart/lib/src/protocol/t_compact_protocol.dart b/lib/dart/lib/src/protocol/t_compact_protocol.dart
index ee8094f..dc26722 100644
--- a/lib/dart/lib/src/protocol/t_compact_protocol.dart
+++ b/lib/dart/lib/src/protocol/t_compact_protocol.dart
@@ -20,8 +20,9 @@
 class TCompactProtocolFactory implements TProtocolFactory<TCompactProtocol> {
   TCompactProtocolFactory();
 
+  @override
   TCompactProtocol getProtocol(TTransport transport) {
-    return new TCompactProtocol(transport);
+    return TCompactProtocol(transport);
   }
 }
 
@@ -38,7 +39,7 @@
   static const int TYPE_MASK = 0xE0;
   static const int TYPE_BITS = 0x07;
   static const int TYPE_SHIFT_AMOUNT = 5;
-  static final TField TSTOP = new TField("", TType.STOP, 0);
+  static final TField TSTOP = TField("", TType.STOP, 0);
 
   static const int TYPE_BOOLEAN_TRUE = 0x01;
   static const int TYPE_BOOLEAN_FALSE = 0x02;
@@ -53,7 +54,7 @@
   static const int TYPE_MAP = 0x0B;
   static const int TYPE_STRUCT = 0x0C;
 
-  static final List<int> _typeMap = new List.unmodifiable(new List(16)
+  static final List<int> _typeMap = List.unmodifiable(List(16)
     ..[TType.STOP] = TType.STOP
     ..[TType.BOOL] = TYPE_BOOLEAN_TRUE
     ..[TType.BYTE] = TYPE_BYTE
@@ -67,40 +68,45 @@
     ..[TType.MAP] = TYPE_MAP
     ..[TType.STRUCT] = TYPE_STRUCT);
 
-  static const Utf8Codec _utf8Codec = const Utf8Codec();
+  static const Utf8Codec _utf8Codec = Utf8Codec();
 
   // Pretend this is a stack
-  DoubleLinkedQueue<int> _lastField = new DoubleLinkedQueue<int>();
+  DoubleLinkedQueue<int> _lastField = DoubleLinkedQueue<int>();
   int _lastFieldId = 0;
 
-  TField _booleanField = null;
-  bool _boolValue = null;
+  TField _booleanField;
+  bool _boolValue;
 
-  final Uint8List tempList = new Uint8List(10);
-  final ByteData tempBD = new ByteData(10);
+  final Uint8List tempList = Uint8List(10);
+  final ByteData tempBD = ByteData(10);
 
   TCompactProtocol(TTransport transport) : super(transport);
 
   /// Write
+  @override
   void writeMessageBegin(TMessage message) {
     writeByte(PROTOCOL_ID);
     writeByte((VERSION & VERSION_MASK) |
         ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK));
-    _writeVarInt32(new Int32(message.seqid));
+    _writeVarInt32(Int32(message.seqid));
     writeString(message.name);
   }
 
+  @override
   void writeMessageEnd() {}
 
+  @override
   void writeStructBegin(TStruct struct) {
     _lastField.addLast(_lastFieldId);
     _lastFieldId = 0;
   }
 
+  @override
   void writeStructEnd() {
     _lastFieldId = _lastField.removeLast();
   }
 
+  @override
   void writeFieldBegin(TField field) {
     if (field.type == TType.BOOL) {
       _booleanField = field;
@@ -123,36 +129,45 @@
     _lastFieldId = field.id;
   }
 
+  @override
   void writeFieldEnd() {}
 
+  @override
   void writeFieldStop() {
     writeByte(TType.STOP);
   }
 
+  @override
   void writeMapBegin(TMap map) {
     if (map.length == 0) {
       writeByte(0);
     } else {
-      _writeVarInt32(new Int32(map.length));
+      _writeVarInt32(Int32(map.length));
       writeByte(
           _getCompactType(map.keyType) << 4 | _getCompactType(map.valueType));
     }
   }
 
+  @override
   void writeMapEnd() {}
 
+  @override
   void writeListBegin(TList list) {
     _writeCollectionBegin(list.elementType, list.length);
   }
 
+  @override
   void writeListEnd() {}
 
+  @override
   void writeSetBegin(TSet set) {
     _writeCollectionBegin(set.elementType, set.length);
   }
 
+  @override
   void writeSetEnd() {}
 
+  @override
   void writeBool(bool b) {
     if (b == null) b = false;
     if (_booleanField != null) {
@@ -164,41 +179,48 @@
     }
   }
 
+  @override
   void writeByte(int b) {
     if (b == null) b = 0;
     tempList[0] = b;
     transport.write(tempList, 0, 1);
   }
 
+  @override
   void writeI16(int i16) {
     if (i16 == null) i16 = 0;
-    _writeVarInt32(_int32ToZigZag(new Int32(i16)));
+    _writeVarInt32(_int32ToZigZag(Int32(i16)));
   }
 
+  @override
   void writeI32(int i32) {
     if (i32 == null) i32 = 0;
-    _writeVarInt32(_int32ToZigZag(new Int32(i32)));
+    _writeVarInt32(_int32ToZigZag(Int32(i32)));
   }
 
+  @override
   void writeI64(int i64) {
     if (i64 == null) i64 = 0;
-    _writeVarInt64(_int64ToZigZag(new Int64(i64)));
+    _writeVarInt64(_int64ToZigZag(Int64(i64)));
   }
 
+  @override
   void writeDouble(double d) {
     if (d == null) d = 0.0;
-    tempBD.setFloat64(0, d, Endianness.little);
+    tempBD.setFloat64(0, d, Endian.little);
     transport.write(tempBD.buffer.asUint8List(), 0, 8);
   }
 
+  @override
   void writeString(String str) {
     Uint8List bytes =
-        str != null ? _utf8Codec.encode(str) : new Uint8List.fromList([]);
+        str != null ? _utf8Codec.encode(str) : Uint8List.fromList([]);
     writeBinary(bytes);
   }
 
+  @override
   void writeBinary(Uint8List bytes) {
-    _writeVarInt32(new Int32(bytes.length));
+    _writeVarInt32(Int32(bytes.length));
     transport.write(bytes, 0, bytes.length);
   }
 
@@ -235,7 +257,7 @@
       writeByte(length << 4 | _getCompactType(elemType));
     } else {
       writeByte(0xF0 | _getCompactType(elemType));
-      _writeVarInt32(new Int32(length));
+      _writeVarInt32(Int32(length));
     }
   }
 
@@ -247,38 +269,44 @@
     return (n << 1) ^ (n >> 63);
   }
 
-  /// Read
+
+  // Read
+  @override
   TMessage readMessageBegin() {
     int protocolId = readByte();
     if (protocolId != PROTOCOL_ID) {
-      throw new TProtocolError(TProtocolErrorType.BAD_VERSION,
+      throw TProtocolError(TProtocolErrorType.BAD_VERSION,
           'Expected protocol id $PROTOCOL_ID but got $protocolId');
     }
     int versionAndType = readByte();
     int version = versionAndType & VERSION_MASK;
     if (version != VERSION) {
-      throw new TProtocolError(TProtocolErrorType.BAD_VERSION,
+      throw TProtocolError(TProtocolErrorType.BAD_VERSION,
           'Expected version $VERSION but got $version');
     }
     int type = (versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS;
     int seqId = _readVarInt32().toInt();
     String messageName = readString();
-    return new TMessage(messageName, type, seqId);
+    return TMessage(messageName, type, seqId);
   }
 
+  @override
   void readMessageEnd() {}
 
+  @override
   TStruct readStructBegin() {
     _lastField.addLast(_lastFieldId);
     _lastFieldId = 0;
     // TODO make this a constant?
-    return new TStruct();
+    return TStruct();
   }
 
+  @override
   void readStructEnd() {
     _lastFieldId = _lastField.removeLast();
   }
 
+  @override
   TField readFieldBegin() {
     int type = readByte();
     if (type == TType.STOP) {
@@ -293,7 +321,7 @@
       fieldId = _lastFieldId + modifier;
     }
 
-    TField field = new TField('', _getTType(type & 0x0F), fieldId);
+    TField field = TField('', _getTType(type & 0x0F), fieldId);
     if (_isBoolType(type)) {
       _boolValue = (type & 0x0F) == TYPE_BOOLEAN_TRUE;
     }
@@ -302,8 +330,10 @@
     return field;
   }
 
+  @override
   void readFieldEnd() {}
 
+  @override
   TMap readMapBegin() {
     int length = _readVarInt32().toInt();
     _checkNegReadLength(length);
@@ -311,11 +341,13 @@
     int keyAndValueType = length == 0 ? 0 : readByte();
     int keyType = _getTType(keyAndValueType >> 4);
     int valueType = _getTType(keyAndValueType & 0x0F);
-    return new TMap(keyType, valueType, length);
+    return TMap(keyType, valueType, length);
   }
 
+  @override
   void readMapEnd() {}
 
+  @override
   TList readListBegin() {
     int lengthAndType = readByte();
     int length = (lengthAndType >> 4) & 0x0F;
@@ -324,18 +356,22 @@
     }
     _checkNegReadLength(length);
     int type = _getTType(lengthAndType);
-    return new TList(type, length);
+    return TList(type, length);
   }
 
+  @override
   void readListEnd() {}
 
+  @override
   TSet readSetBegin() {
     TList tlist = readListBegin();
-    return new TSet(tlist.elementType, tlist.length);
+    return TSet(tlist.elementType, tlist.length);
   }
 
+  @override
   void readSetEnd() {}
 
+  @override
   bool readBool() {
     if (_boolValue != null) {
       bool result = _boolValue;
@@ -345,43 +381,50 @@
     return readByte() == TYPE_BOOLEAN_TRUE;
   }
 
+  @override
   int readByte() {
     transport.readAll(tempList, 0, 1);
     return tempList.buffer.asByteData().getUint8(0);
   }
 
+  @override
   int readI16() {
     return _zigzagToInt32(_readVarInt32()).toInt();
   }
 
+  @override
   int readI32() {
     return _zigzagToInt32(_readVarInt32()).toInt();
   }
 
+  @override
   int readI64() {
     return _zigzagToInt64(_readVarInt64()).toInt();
   }
 
+  @override
   double readDouble() {
     transport.readAll(tempList, 0, 8);
-    return tempList.buffer.asByteData().getFloat64(0, Endianness.little);
+    return tempList.buffer.asByteData().getFloat64(0, Endian.little);
   }
 
+  @override
   String readString() {
     int length = _readVarInt32().toInt();
     _checkNegReadLength(length);
 
     // TODO look at using temp for small strings?
-    Uint8List buff = new Uint8List(length);
+    Uint8List buff = Uint8List(length);
     transport.readAll(buff, 0, length);
     return _utf8Codec.decode(buff);
   }
 
+  @override
   Uint8List readBinary() {
     int length = _readVarInt32().toInt();
     _checkNegReadLength(length);
 
-    Uint8List buff = new Uint8List(length);
+    Uint8List buff = Uint8List(length);
     transport.readAll(buff, 0, length);
     return buff;
   }
@@ -390,7 +433,7 @@
     Int32 result = Int32.ZERO;
     int shift = 0;
     while (true) {
-      Int32 b = new Int32(readByte());
+      Int32 b = Int32(readByte());
       result |= (b & 0x7f) << shift;
       if ((b & 0x80) != 0x80) break;
       shift += 7;
@@ -402,7 +445,7 @@
     Int64 result = Int64.ZERO;
     int shift = 0;
     while (true) {
-      Int64 b = new Int64(readByte());
+      Int64 b = Int64(readByte());
       result |= (b & 0x7f) << shift;
       if ((b & 0x80) != 0x80) break;
       shift += 7;
@@ -420,7 +463,7 @@
 
   void _checkNegReadLength(int length) {
     if (length < 0) {
-      throw new TProtocolError(
+      throw TProtocolError(
           TProtocolErrorType.NEGATIVE_SIZE, 'Negative length: $length');
     }
   }
@@ -457,7 +500,7 @@
       case TYPE_STRUCT:
         return TType.STRUCT;
       default:
-        throw new TProtocolError(
+        throw TProtocolError(
             TProtocolErrorType.INVALID_DATA, "Unknown type: ${type & 0x0F}");
     }
   }
diff --git a/lib/dart/lib/src/protocol/t_json_protocol.dart b/lib/dart/lib/src/protocol/t_json_protocol.dart
index 180568d..4aaf20c 100644
--- a/lib/dart/lib/src/protocol/t_json_protocol.dart
+++ b/lib/dart/lib/src/protocol/t_json_protocol.dart
@@ -18,8 +18,9 @@
 part of thrift;
 
 class TJsonProtocolFactory implements TProtocolFactory<TJsonProtocol> {
+  @override
   TJsonProtocol getProtocol(TTransport transport) {
-    return new TJsonProtocol(transport);
+    return TJsonProtocol(transport);
   }
 }
 
@@ -29,18 +30,18 @@
 class TJsonProtocol extends TProtocol {
   static const int VERSION_1 = 1;
 
-  static const Utf8Codec utf8Codec = const Utf8Codec();
+  static const Utf8Codec utf8Codec = Utf8Codec();
 
   _BaseContext _context;
   _BaseContext _rootContext;
   _LookaheadReader _reader;
 
   final List<_BaseContext> _contextStack = [];
-  final Uint8List _tempBuffer = new Uint8List(4);
+  final Uint8List _tempBuffer = Uint8List(4);
 
   TJsonProtocol(TTransport transport) : super(transport) {
-    _rootContext = new _BaseContext(this);
-    _reader = new _LookaheadReader(this);
+    _rootContext = _BaseContext(this);
+    _reader = _LookaheadReader(this);
     _resetContext();
   }
 
@@ -63,8 +64,8 @@
   void _readJsonSyntaxChar(int charByte) {
     int byte = _reader.read();
     if (byte != charByte) {
-      throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
-          "Expected character ${new String.fromCharCode(charByte)} but found: ${new String.fromCharCode(byte)}");
+      throw TProtocolError(TProtocolErrorType.INVALID_DATA,
+          "Expected character ${String.fromCharCode(charByte)} but found: ${String.fromCharCode(byte)}");
     }
   }
 
@@ -77,7 +78,7 @@
       byte += 10;
       return byte - _Constants.HEX_A_BYTES[0];
     } else {
-      throw new TProtocolError(
+      throw TProtocolError(
           TProtocolErrorType.INVALID_DATA, "Expected hex character");
     }
   }
@@ -164,7 +165,7 @@
   void _writeJsonObjectStart() {
     _context.write();
     transport.writeAll(_Constants.LBRACE_BYTES);
-    _pushContext(new _PairContext(this));
+    _pushContext(_PairContext(this));
   }
 
   void _writeJsonObjectEnd() {
@@ -175,7 +176,7 @@
   void _writeJsonArrayStart() {
     _context.write();
     transport.writeAll(_Constants.LBRACKET_BYTES);
-    _pushContext(new _ListContext(this));
+    _pushContext(_ListContext(this));
   }
 
   void _writeJsonArrayEnd() {
@@ -183,6 +184,7 @@
     transport.writeAll(_Constants.RBRACKET_BYTES);
   }
 
+  @override
   void writeMessageBegin(TMessage message) {
     _resetContext();
 
@@ -194,30 +196,37 @@
     _writeJsonInteger(message.seqid);
   }
 
+  @override
   void writeMessageEnd() {
     _writeJsonArrayEnd();
   }
 
+  @override
   void writeStructBegin(TStruct struct) {
     _writeJsonObjectStart();
   }
 
+  @override
   void writeStructEnd() {
     _writeJsonObjectEnd();
   }
 
+  @override
   void writeFieldBegin(TField field) {
     _writeJsonInteger(field.id);
     _writeJsonObjectStart();
     _writeJsonString(_Constants.getTypeNameBytesForTypeId(field.type));
   }
 
+  @override
   void writeFieldEnd() {
     _writeJsonObjectEnd();
   }
 
+  @override
   void writeFieldStop() {}
 
+  @override
   void writeMapBegin(TMap map) {
     _writeJsonArrayStart();
     _writeJsonString(_Constants.getTypeNameBytesForTypeId(map.keyType));
@@ -226,61 +235,74 @@
     _writeJsonObjectStart();
   }
 
+  @override
   void writeMapEnd() {
     _writeJsonObjectEnd();
     _writeJsonArrayEnd();
   }
 
+  @override
   void writeListBegin(TList list) {
     _writeJsonArrayStart();
     _writeJsonString(_Constants.getTypeNameBytesForTypeId(list.elementType));
     _writeJsonInteger(list.length);
   }
 
+  @override
   void writeListEnd() {
     _writeJsonArrayEnd();
   }
 
+  @override
   void writeSetBegin(TSet set) {
     _writeJsonArrayStart();
     _writeJsonString(_Constants.getTypeNameBytesForTypeId(set.elementType));
     _writeJsonInteger(set.length);
   }
 
+  @override
   void writeSetEnd() {
     _writeJsonArrayEnd();
   }
 
+  @override
   void writeBool(bool b) {
     if (b == null) b = false;
     _writeJsonInteger(b ? 1 : 0);
   }
 
+  @override
   void writeByte(int b) {
     _writeJsonInteger(b);
   }
 
+  @override
   void writeI16(int i16) {
     _writeJsonInteger(i16);
   }
 
+  @override
   void writeI32(int i32) {
     _writeJsonInteger(i32);
   }
 
+  @override
   void writeI64(int i64) {
     _writeJsonInteger(i64);
   }
 
+  @override
   void writeDouble(double d) {
     _writeJsonDouble(d);
   }
 
+  @override
   void writeString(String s) {
-    var bytes = s != null ? utf8Codec.encode(s) : new Uint8List.fromList([]);
+    var bytes = s != null ? utf8Codec.encode(s) : Uint8List.fromList([]);
     _writeJsonString(bytes);
   }
 
+  @override
   void writeBinary(Uint8List bytes) {
     _writeJsonBase64(bytes);
   }
@@ -290,8 +312,7 @@
   bool _isLowSurrogate(int b) => b >= 0xDC00 && b <= 0xDFFF;
 
   /// read
-
-  Uint8List _readJsonString({bool skipContext: false}) {
+  Uint8List _readJsonString({bool skipContext = false}) {
     List<int> bytes = [];
     List<int> codeunits = [];
 
@@ -316,10 +337,10 @@
 
       // distinguish between \uXXXX and control chars like \n
       if (byte != _Constants.ESCSEQ_BYTES[1]) {
-        String char = new String.fromCharCode(byte);
+        String char = String.fromCharCode(byte);
         int offset = _Constants.ESCAPE_CHARS.indexOf(char);
         if (offset == -1) {
-          throw new TProtocolError(
+          throw TProtocolError(
               TProtocolErrorType.INVALID_DATA, "Expected control char");
         }
         byte = _Constants.ESCAPE_CHAR_VALS.codeUnitAt(offset);
@@ -329,46 +350,44 @@
 
       // it's \uXXXX
       transport.readAll(_tempBuffer, 0, 4);
-      byte = (_hexVal(_tempBuffer[0]) << 12)
-        + (_hexVal(_tempBuffer[1]) << 8)
-        + (_hexVal(_tempBuffer[2]) << 4)
-        + _hexVal(_tempBuffer[3]);
+      byte = (_hexVal(_tempBuffer[0]) << 12) +
+          (_hexVal(_tempBuffer[1]) << 8) +
+          (_hexVal(_tempBuffer[2]) << 4) +
+          _hexVal(_tempBuffer[3]);
       if (_isHighSurrogate(byte)) {
         if (codeunits.isNotEmpty) {
-          throw new TProtocolError(
+          throw TProtocolError(
               TProtocolErrorType.INVALID_DATA, "Expected low surrogate");
         }
         codeunits.add(byte);
-      }
-      else if (_isLowSurrogate(byte)) {
+      } else if (_isLowSurrogate(byte)) {
         if (codeunits.isEmpty) {
-          throw new TProtocolError(
+          throw TProtocolError(
               TProtocolErrorType.INVALID_DATA, "Expected high surrogate");
         }
         codeunits.add(byte);
-        bytes.addAll(utf8Codec.encode(new String.fromCharCodes(codeunits)));
+        bytes.addAll(utf8Codec.encode(String.fromCharCodes(codeunits)));
         codeunits.clear();
-      }
-      else {
-        bytes.addAll(utf8Codec.encode(new String.fromCharCode(byte)));
+      } else {
+        bytes.addAll(utf8Codec.encode(String.fromCharCode(byte)));
       }
     }
 
     if (codeunits.isNotEmpty) {
-      throw new TProtocolError(
+      throw TProtocolError(
           TProtocolErrorType.INVALID_DATA, "Expected low surrogate");
     }
 
-    return new Uint8List.fromList(bytes);
+    return Uint8List.fromList(bytes);
   }
 
   String _readJsonNumericChars() {
-    StringBuffer buffer = new StringBuffer();
+    StringBuffer buffer = StringBuffer();
     while (true) {
       if (!_Constants.isJsonNumeric(_reader.peek())) {
         break;
       }
-      buffer.write(new String.fromCharCode(_reader.read()));
+      buffer.write(String.fromCharCode(_reader.read()));
     }
     return buffer.toString();
   }
@@ -387,7 +406,7 @@
     try {
       return int.parse(str);
     } on FormatException catch (_) {
-      throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
+      throw TProtocolError(TProtocolErrorType.INVALID_DATA,
           "Bad data encounted in numeric data");
     }
   }
@@ -397,12 +416,15 @@
 
     if (_reader.peek() == _Constants.QUOTE_BYTES[0]) {
       Uint8List bytes = _readJsonString(skipContext: true);
-      double d = double.parse(utf8Codec.decode(bytes), (_) {
-        throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
+      double d;
+      try {
+        d = double.tryParse(utf8Codec.decode(bytes));
+      } catch (_) {
+        throw TProtocolError(TProtocolErrorType.INVALID_DATA,
             "Bad data encounted in numeric data");
-      });
+      }
       if (!_context.escapeNumbers && !d.isNaN && !d.isInfinite) {
-        throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
+        throw TProtocolError(TProtocolErrorType.INVALID_DATA,
             "Numeric data unexpectedly quoted");
       }
       return d;
@@ -411,10 +433,12 @@
         // This will throw - we should have had a quote if escapeNumbers == true
         _readJsonSyntaxChar(_Constants.QUOTE_BYTES[0]);
       }
-      return double.parse(_readJsonNumericChars(), (_) {
-        throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
+      try {
+        return double.parse(_readJsonNumericChars());
+      } on FormatException catch (_) {
+        throw TProtocolError(TProtocolErrorType.INVALID_DATA,
             "Bad data encounted in numeric data");
-      });
+      }
     }
   }
 
@@ -423,13 +447,13 @@
     Uint8List base64Bytes = _readJsonString();
     String base64text = utf8Codec.decode(base64Bytes);
 
-    return new Uint8List.fromList(base64.decode(base64text));
+    return Uint8List.fromList(base64.decode(base64text));
   }
 
   void _readJsonObjectStart() {
     _context.read();
     _readJsonSyntaxChar(_Constants.LBRACE_BYTES[0]);
-    _pushContext(new _PairContext(this));
+    _pushContext(_PairContext(this));
   }
 
   void _readJsonObjectEnd() {
@@ -440,7 +464,7 @@
   void _readJsonArrayStart() {
     _context.read();
     _readJsonSyntaxChar(_Constants.LBRACKET_BYTES[0]);
-    _pushContext(new _ListContext(this));
+    _pushContext(_ListContext(this));
   }
 
   void _readJsonArrayEnd() {
@@ -448,12 +472,13 @@
     _popContext();
   }
 
+  @override
   TMessage readMessageBegin() {
     _resetContext();
 
     _readJsonArrayStart();
     if (_readJsonInteger() != VERSION_1) {
-      throw new TProtocolError(
+      throw TProtocolError(
           TProtocolErrorType.BAD_VERSION, "Message contained bad version.");
     }
 
@@ -462,22 +487,26 @@
     int type = _readJsonInteger();
     int seqid = _readJsonInteger();
 
-    return new TMessage(name, type, seqid);
+    return TMessage(name, type, seqid);
   }
 
+  @override
   void readMessageEnd() {
     _readJsonArrayEnd();
   }
 
+  @override
   TStruct readStructBegin() {
     _readJsonObjectStart();
-    return new TStruct();
+    return TStruct();
   }
 
+  @override
   void readStructEnd() {
     _readJsonObjectEnd();
   }
 
+  @override
   TField readFieldBegin() {
     String name = "";
     int type = TType.STOP;
@@ -489,13 +518,15 @@
       type = _Constants.getTypeIdForTypeName(_readJsonString());
     }
 
-    return new TField(name, type, id);
+    return TField(name, type, id);
   }
 
+  @override
   void readFieldEnd() {
     _readJsonObjectEnd();
   }
 
+  @override
   TMap readMapBegin() {
     _readJsonArrayStart();
     int keyType = _Constants.getTypeIdForTypeName(_readJsonString());
@@ -503,91 +534,103 @@
     int length = _readJsonInteger();
     _readJsonObjectStart();
 
-    return new TMap(keyType, valueType, length);
+    return TMap(keyType, valueType, length);
   }
 
+  @override
   void readMapEnd() {
     _readJsonObjectEnd();
     _readJsonArrayEnd();
   }
 
+  @override
   TList readListBegin() {
     _readJsonArrayStart();
     int elementType = _Constants.getTypeIdForTypeName(_readJsonString());
     int length = _readJsonInteger();
 
-    return new TList(elementType, length);
+    return TList(elementType, length);
   }
 
+  @override
   void readListEnd() {
     _readJsonArrayEnd();
   }
 
+  @override
   TSet readSetBegin() {
     _readJsonArrayStart();
     int elementType = _Constants.getTypeIdForTypeName(_readJsonString());
     int length = _readJsonInteger();
 
-    return new TSet(elementType, length);
+    return TSet(elementType, length);
   }
 
+  @override
   void readSetEnd() {
     _readJsonArrayEnd();
   }
 
+  @override
   bool readBool() {
     return _readJsonInteger() == 0 ? false : true;
   }
 
+  @override
   int readByte() {
     return _readJsonInteger();
   }
 
+  @override
   int readI16() {
     return _readJsonInteger();
   }
 
+  @override
   int readI32() {
     return _readJsonInteger();
   }
 
+  @override
   int readI64() {
     return _readJsonInteger();
   }
 
+  @override
   double readDouble() {
     return _readJsonDouble();
   }
 
+  @override
   String readString() {
     return utf8Codec.decode(_readJsonString());
   }
 
+  @override
   Uint8List readBinary() {
-    return new Uint8List.fromList(_readJsonBase64());
+    return Uint8List.fromList(_readJsonBase64());
   }
 }
 
 class _Constants {
-  static const utf8codec = const Utf8Codec();
+  static const utf8codec = Utf8Codec();
 
-  static final Uint8List HEX_0_BYTES = new Uint8List.fromList('0'.codeUnits);
-  static final Uint8List HEX_9_BYTES = new Uint8List.fromList('9'.codeUnits);
-  static final Uint8List HEX_A_BYTES = new Uint8List.fromList('a'.codeUnits);
-  static final Uint8List HEX_F_BYTES = new Uint8List.fromList('f'.codeUnits);
-  static final Uint8List COMMA_BYTES = new Uint8List.fromList(','.codeUnits);
-  static final Uint8List COLON_BYTES = new Uint8List.fromList(':'.codeUnits);
-  static final Uint8List LBRACE_BYTES = new Uint8List.fromList('{'.codeUnits);
-  static final Uint8List RBRACE_BYTES = new Uint8List.fromList('}'.codeUnits);
-  static final Uint8List LBRACKET_BYTES = new Uint8List.fromList('['.codeUnits);
-  static final Uint8List RBRACKET_BYTES = new Uint8List.fromList(']'.codeUnits);
-  static final Uint8List QUOTE_BYTES = new Uint8List.fromList('"'.codeUnits);
-  static final Uint8List BACKSLASH_BYTES =
-      new Uint8List.fromList(r'\'.codeUnits);
+  static final Uint8List HEX_0_BYTES = Uint8List.fromList('0'.codeUnits);
+  static final Uint8List HEX_9_BYTES = Uint8List.fromList('9'.codeUnits);
+  static final Uint8List HEX_A_BYTES = Uint8List.fromList('a'.codeUnits);
+  static final Uint8List HEX_F_BYTES = Uint8List.fromList('f'.codeUnits);
+  static final Uint8List COMMA_BYTES = Uint8List.fromList(','.codeUnits);
+  static final Uint8List COLON_BYTES = Uint8List.fromList(':'.codeUnits);
+  static final Uint8List LBRACE_BYTES = Uint8List.fromList('{'.codeUnits);
+  static final Uint8List RBRACE_BYTES = Uint8List.fromList('}'.codeUnits);
+  static final Uint8List LBRACKET_BYTES = Uint8List.fromList('['.codeUnits);
+  static final Uint8List RBRACKET_BYTES = Uint8List.fromList(']'.codeUnits);
+  static final Uint8List QUOTE_BYTES = Uint8List.fromList('"'.codeUnits);
+  static final Uint8List BACKSLASH_BYTES = Uint8List.fromList(r'\'.codeUnits);
 
-  static final ESCSEQ_BYTES = new Uint8List.fromList(r'\u00'.codeUnits);
+  static final ESCSEQ_BYTES = Uint8List.fromList(r'\u00'.codeUnits);
 
-  static final Uint8List JSON_CHAR_TABLE = new Uint8List.fromList([
+  static final Uint8List JSON_CHAR_TABLE = Uint8List.fromList([
     0, 0, 0, 0, 0, 0, 0, 0, // 8 bytes
     'b'.codeUnitAt(0), 't'.codeUnitAt(0), 'n'.codeUnitAt(0), 0, // 4 bytes
     'f'.codeUnitAt(0), 'r'.codeUnitAt(0), 0, 0, // 4 bytes
@@ -612,31 +655,30 @@
   static const String NAME_LIST = 'lst';
   static const String NAME_SET = 'set';
 
-  static final Map<int, Uint8List> _TYPE_ID_TO_NAME_BYTES =
-      new Map.unmodifiable({
-    TType.BOOL: new Uint8List.fromList(NAME_BOOL.codeUnits),
-    TType.BYTE: new Uint8List.fromList(NAME_BYTE.codeUnits),
-    TType.I16: new Uint8List.fromList(NAME_I16.codeUnits),
-    TType.I32: new Uint8List.fromList(NAME_I32.codeUnits),
-    TType.I64: new Uint8List.fromList(NAME_I64.codeUnits),
-    TType.DOUBLE: new Uint8List.fromList(NAME_DOUBLE.codeUnits),
-    TType.STRING: new Uint8List.fromList(NAME_STRING.codeUnits),
-    TType.STRUCT: new Uint8List.fromList(NAME_STRUCT.codeUnits),
-    TType.MAP: new Uint8List.fromList(NAME_MAP.codeUnits),
-    TType.SET: new Uint8List.fromList(NAME_SET.codeUnits),
-    TType.LIST: new Uint8List.fromList(NAME_LIST.codeUnits)
+  static final Map<int, Uint8List> _TYPE_ID_TO_NAME_BYTES = Map.unmodifiable({
+    TType.BOOL: Uint8List.fromList(NAME_BOOL.codeUnits),
+    TType.BYTE: Uint8List.fromList(NAME_BYTE.codeUnits),
+    TType.I16: Uint8List.fromList(NAME_I16.codeUnits),
+    TType.I32: Uint8List.fromList(NAME_I32.codeUnits),
+    TType.I64: Uint8List.fromList(NAME_I64.codeUnits),
+    TType.DOUBLE: Uint8List.fromList(NAME_DOUBLE.codeUnits),
+    TType.STRING: Uint8List.fromList(NAME_STRING.codeUnits),
+    TType.STRUCT: Uint8List.fromList(NAME_STRUCT.codeUnits),
+    TType.MAP: Uint8List.fromList(NAME_MAP.codeUnits),
+    TType.SET: Uint8List.fromList(NAME_SET.codeUnits),
+    TType.LIST: Uint8List.fromList(NAME_LIST.codeUnits)
   });
 
   static Uint8List getTypeNameBytesForTypeId(int typeId) {
     if (!_TYPE_ID_TO_NAME_BYTES.containsKey(typeId)) {
-      throw new TProtocolError(
+      throw TProtocolError(
           TProtocolErrorType.NOT_IMPLEMENTED, "Unrecognized type");
     }
 
     return _TYPE_ID_TO_NAME_BYTES[typeId];
   }
 
-  static final Map<String, int> _NAME_TO_TYPE_ID = new Map.unmodifiable({
+  static final Map<String, int> _NAME_TO_TYPE_ID = Map.unmodifiable({
     NAME_BOOL: TType.BOOL,
     NAME_BYTE: TType.BYTE,
     NAME_I16: TType.I16,
@@ -653,14 +695,14 @@
   static int getTypeIdForTypeName(Uint8List bytes) {
     String name = utf8codec.decode(bytes);
     if (!_NAME_TO_TYPE_ID.containsKey(name)) {
-      throw new TProtocolError(
+      throw TProtocolError(
           TProtocolErrorType.NOT_IMPLEMENTED, "Unrecognized type");
     }
 
     return _NAME_TO_TYPE_ID[name];
   }
 
-  static final Set<int> _JSON_NUMERICS = new Set.from([
+  static final Set<int> _JSON_NUMERICS = Set.from([
     '+'.codeUnitAt(0),
     '-'.codeUnitAt(0),
     '.'.codeUnitAt(0),
@@ -689,7 +731,7 @@
   _LookaheadReader(this.protocol);
 
   bool _hasData = false;
-  final Uint8List _data = new Uint8List(1);
+  final Uint8List _data = Uint8List(1);
 
   int read() {
     if (_hasData) {
@@ -722,6 +764,7 @@
 
   bool get escapeNumbers => false;
 
+  @override
   String toString() => 'BaseContext';
 }
 
@@ -730,6 +773,7 @@
 
   bool _first = true;
 
+  @override
   void write() {
     if (_first) {
       _first = false;
@@ -738,6 +782,7 @@
     }
   }
 
+  @override
   void read() {
     if (_first) {
       _first = false;
@@ -746,6 +791,7 @@
     }
   }
 
+  @override
   String toString() => 'ListContext';
 }
 
@@ -758,6 +804,7 @@
   Uint8List get symbolBytes =>
       _colon ? _Constants.COLON_BYTES : _Constants.COMMA_BYTES;
 
+  @override
   void write() {
     if (_first) {
       _first = false;
@@ -768,6 +815,7 @@
     }
   }
 
+  @override
   void read() {
     if (_first) {
       _first = false;
@@ -778,7 +826,9 @@
     }
   }
 
+  @override
   bool get escapeNumbers => _colon;
 
+  @override
   String toString() => 'PairContext';
 }
diff --git a/lib/dart/lib/src/protocol/t_message.dart b/lib/dart/lib/src/protocol/t_message.dart
index cc7b886..b985deb 100644
--- a/lib/dart/lib/src/protocol/t_message.dart
+++ b/lib/dart/lib/src/protocol/t_message.dart
@@ -31,5 +31,6 @@
 
   TMessage(this.name, this.type, this.seqid);
 
+  @override
   String toString() => "<TMessage name: '$name' type: $type seqid: $seqid>";
 }
diff --git a/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart b/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart
index 078a6d7..693e58b 100644
--- a/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart
+++ b/lib/dart/lib/src/protocol/t_multiplexed_protocol.dart
@@ -27,15 +27,16 @@
       : _serviceName = serviceName,
         super(protocol) {
     if (serviceName == null) {
-      throw new ArgumentError.notNull("serviceName");
+      throw ArgumentError.notNull("serviceName");
     }
   }
 
+  @override
   void writeMessageBegin(TMessage message) {
     if (message.type == TMessageType.CALL ||
         message.type == TMessageType.ONEWAY) {
       String name = _serviceName + SEPARATOR + message.name;
-      message = new TMessage(name, message.type, message.seqid);
+      message = TMessage(name, message.type, message.seqid);
     }
 
     super.writeMessageBegin(message);
diff --git a/lib/dart/lib/src/protocol/t_protocol_decorator.dart b/lib/dart/lib/src/protocol/t_protocol_decorator.dart
index 9cd02f6..9389ec7 100644
--- a/lib/dart/lib/src/protocol/t_protocol_decorator.dart
+++ b/lib/dart/lib/src/protocol/t_protocol_decorator.dart
@@ -29,122 +29,163 @@
 
   /// Write
 
+  @override
   void writeMessageBegin(TMessage message) {
     _protocol.writeMessageBegin(message);
   }
 
+  @override
   void writeMessageEnd() {
     _protocol.writeMessageEnd();
   }
 
+  @override
   void writeStructBegin(TStruct struct) {
     _protocol.writeStructBegin(struct);
   }
 
+  @override
   void writeStructEnd() {
     _protocol.writeStructEnd();
   }
 
+  @override
   void writeFieldBegin(TField field) {
     _protocol.writeFieldBegin(field);
   }
 
+  @override
   void writeFieldEnd() {
     _protocol.writeFieldEnd();
   }
 
+  @override
   void writeFieldStop() {
     _protocol.writeFieldStop();
   }
 
+  @override
   void writeMapBegin(TMap map) {
     _protocol.writeMapBegin(map);
   }
 
+  @override
   void writeMapEnd() {
     _protocol.writeMapEnd();
   }
 
+  @override
   void writeListBegin(TList list) {
     _protocol.writeListBegin(list);
   }
 
+  @override
   void writeListEnd() {
     _protocol.writeListEnd();
   }
 
+  @override
   void writeSetBegin(TSet set) {
     _protocol.writeSetBegin(set);
   }
 
+  @override
   void writeSetEnd() {
     _protocol.writeSetEnd();
   }
 
+  @override
   void writeBool(bool b) {
     _protocol.writeBool(b);
   }
 
+  @override
   void writeByte(int b) {
     _protocol.writeByte(b);
   }
 
+  @override
   void writeI16(int i16) {
     _protocol.writeI16(i16);
   }
 
+  @override
   void writeI32(int i32) {
     _protocol.writeI32(i32);
   }
 
+  @override
   void writeI64(int i64) {
     _protocol.writeI64(i64);
   }
 
+  @override
   void writeDouble(double d) {
     _protocol.writeDouble(d);
   }
 
+  @override
   void writeString(String str) {
     _protocol.writeString(str);
   }
 
+  @override
   void writeBinary(Uint8List bytes) {
     _protocol.writeBinary(bytes);
   }
 
   /// Read
+  @override
   TMessage readMessageBegin() => _protocol.readMessageBegin();
+  @override
   void readMessageEnd() => _protocol.readMessageEnd();
 
+  @override
   TStruct readStructBegin() => _protocol.readStructBegin();
+  @override
   void readStructEnd() => _protocol.readStructEnd();
 
+  @override
   TField readFieldBegin() => _protocol.readFieldBegin();
+  @override
   void readFieldEnd() => _protocol.readFieldEnd();
 
+  @override
   TMap readMapBegin() => _protocol.readMapBegin();
+  @override
   void readMapEnd() => _protocol.readMapEnd();
 
+  @override
   TList readListBegin() => _protocol.readListBegin();
+  @override
   void readListEnd() => _protocol.readListEnd();
 
+  @override
   TSet readSetBegin() => _protocol.readSetBegin();
+  @override
   void readSetEnd() => _protocol.readSetEnd();
 
+  @override
   bool readBool() => _protocol.readBool();
 
+  @override
   int readByte() => _protocol.readByte();
 
+  @override
   int readI16() => _protocol.readI16();
 
+  @override
   int readI32() => _protocol.readI32();
 
+  @override
   int readI64() => _protocol.readI64();
 
+  @override
   double readDouble() => _protocol.readDouble();
 
+  @override
   String readString() => _protocol.readString();
 
+  @override
   Uint8List readBinary() => _protocol.readBinary();
 }
diff --git a/lib/dart/lib/src/protocol/t_protocol_util.dart b/lib/dart/lib/src/protocol/t_protocol_util.dart
index 841ea82..b57b2c6 100644
--- a/lib/dart/lib/src/protocol/t_protocol_util.dart
+++ b/lib/dart/lib/src/protocol/t_protocol_util.dart
@@ -29,7 +29,7 @@
 
   static _skip(TProtocol prot, int type, int recursionLimit) {
     if (recursionLimit <= 0) {
-      throw new TProtocolError(
+      throw TProtocolError(
           TProtocolErrorType.DEPTH_LIMIT, "Depth limit exceeded");
     }
 
@@ -101,7 +101,7 @@
         break;
 
       default:
-        throw new TProtocolError(TProtocolErrorType.INVALID_DATA, "Invalid data");
+        throw TProtocolError(TProtocolErrorType.INVALID_DATA, "Invalid data");
     }
   }
 }
diff --git a/lib/dart/lib/src/serializer/t_deserializer.dart b/lib/dart/lib/src/serializer/t_deserializer.dart
index aefbee2..c01ab6b 100644
--- a/lib/dart/lib/src/serializer/t_deserializer.dart
+++ b/lib/dart/lib/src/serializer/t_deserializer.dart
@@ -18,30 +18,29 @@
 part of thrift;
 
 class TDeserializer {
-  final message = new TMessage('Deserializer', TMessageType.ONEWAY, 1);
+  final message = TMessage('Deserializer', TMessageType.ONEWAY, 1);
   TBufferedTransport transport;
   TProtocol protocol;
 
   TDeserializer({TProtocolFactory protocolFactory}) {
-    this.transport = new TBufferedTransport();
-    
+    this.transport = TBufferedTransport();
+
     if (protocolFactory == null) {
-      protocolFactory = new TBinaryProtocolFactory();
+      protocolFactory = TBinaryProtocolFactory();
     }
-    
+
     this.protocol = protocolFactory.getProtocol(this.transport);
   }
 
   void read(TBase base, Uint8List data) {
     transport.writeAll(data);
-    
+
     transport.flush();
-    
+
     base.read(protocol);
   }
 
   void readString(TBase base, String data) {
-    
     transport.writeAll(base64.decode(data));
     transport.flush();
 
diff --git a/lib/dart/lib/src/serializer/t_serializer.dart b/lib/dart/lib/src/serializer/t_serializer.dart
index feec822..fb89789 100644
--- a/lib/dart/lib/src/serializer/t_serializer.dart
+++ b/lib/dart/lib/src/serializer/t_serializer.dart
@@ -18,15 +18,15 @@
 part of thrift;
 
 class TSerializer {
-  final message = new TMessage('Serializer', TMessageType.ONEWAY, 1);
+  final message = TMessage('Serializer', TMessageType.ONEWAY, 1);
   TBufferedTransport transport;
   TProtocol protocol;
 
   TSerializer({TProtocolFactory protocolFactory}) {
-    this.transport = new TBufferedTransport();
-    
+    this.transport = TBufferedTransport();
+
     if (protocolFactory == null) {
-      protocolFactory = new TBinaryProtocolFactory();
+      protocolFactory = TBinaryProtocolFactory();
     }
 
     this.protocol = protocolFactory.getProtocol(this.transport);
@@ -34,15 +34,15 @@
 
   Uint8List write(TBase base) {
     base.write(protocol);
-    
+
     return transport.consumeWriteBuffer();
   }
 
   String writeString(TBase base) {
     base.write(protocol);
-    
+
     Uint8List bytes = transport.consumeWriteBuffer();
-    
+
     return base64.encode(bytes);
   }
 }
diff --git a/lib/dart/lib/src/t_application_error.dart b/lib/dart/lib/src/t_application_error.dart
index 6f8abd4..38449a9 100644
--- a/lib/dart/lib/src/t_application_error.dart
+++ b/lib/dart/lib/src/t_application_error.dart
@@ -32,12 +32,11 @@
 }
 
 class TApplicationError extends TError {
-  static final TStruct _struct = new TStruct("TApplicationError");
+  static final TStruct _struct = TStruct("TApplicationError");
   static const int MESSAGE = 1;
-  static final TField _messageField =
-      new TField("message", TType.STRING, MESSAGE);
+  static final TField _messageField = TField("message", TType.STRING, MESSAGE);
   static const int TYPE = 2;
-  static final TField _typeField = new TField("type", TType.I32, TYPE);
+  static final TField _typeField = TField("type", TType.I32, TYPE);
 
   TApplicationError(
       [int type = TApplicationErrorType.UNKNOWN, String message = ""])
@@ -46,7 +45,7 @@
   static TApplicationError read(TProtocol iprot) {
     TField field;
 
-    String message = null;
+    String message;
     int type = TApplicationErrorType.UNKNOWN;
 
     iprot.readStructBegin();
@@ -82,13 +81,13 @@
     }
     iprot.readStructEnd();
 
-    return new TApplicationError(type, message);
+    return TApplicationError(type, message);
   }
 
   write(TProtocol oprot) {
     oprot.writeStructBegin(_struct);
 
-    if (message != null && !message.isEmpty) {
+    if (message != null && message.isNotEmpty) {
       oprot.writeFieldBegin(_messageField);
       oprot.writeString(message);
       oprot.writeFieldEnd();
diff --git a/lib/dart/lib/src/t_error.dart b/lib/dart/lib/src/t_error.dart
index 93ab732..df15791 100644
--- a/lib/dart/lib/src/t_error.dart
+++ b/lib/dart/lib/src/t_error.dart
@@ -23,5 +23,6 @@
 
   TError(this.type, this.message);
 
+  @override
   String toString() => "<TError type: $type message: '$message'>";
 }
diff --git a/lib/dart/lib/src/transport/t_buffered_transport.dart b/lib/dart/lib/src/transport/t_buffered_transport.dart
index b73a30c..f17b2ee 100644
--- a/lib/dart/lib/src/transport/t_buffered_transport.dart
+++ b/lib/dart/lib/src/transport/t_buffered_transport.dart
@@ -23,7 +23,7 @@
   Iterator<int> _readIterator;
 
   Uint8List consumeWriteBuffer() {
-    Uint8List buffer = new Uint8List.fromList(_writeBuffer);
+    Uint8List buffer = Uint8List.fromList(_writeBuffer);
     _writeBuffer.clear();
     return buffer;
   }
@@ -32,7 +32,7 @@
     _readIterator = readBuffer != null ? readBuffer.iterator : null;
   }
 
-  void _reset({bool isOpen: false}) {
+  void _reset({bool isOpen = false}) {
     _isOpen = isOpen;
     _writeBuffer.clear();
     _readIterator = null;
@@ -41,23 +41,27 @@
   bool get hasReadData => _readIterator != null;
 
   bool _isOpen;
+  @override
   bool get isOpen => _isOpen;
 
+  @override
   Future open() async {
     _reset(isOpen: true);
   }
 
+  @override
   Future close() async {
     _reset(isOpen: false);
   }
 
+  @override
   int read(Uint8List buffer, int offset, int length) {
     if (buffer == null) {
-      throw new ArgumentError.notNull("buffer");
+      throw ArgumentError.notNull("buffer");
     }
 
     if (offset + length > buffer.length) {
-      throw new ArgumentError("The range exceeds the buffer length");
+      throw ArgumentError("The range exceeds the buffer length");
     }
 
     if (_readIterator == null || length <= 0) {
@@ -78,21 +82,23 @@
     return i;
   }
 
+  @override
   void write(Uint8List buffer, int offset, int length) {
     if (buffer == null) {
-      throw new ArgumentError.notNull("buffer");
+      throw ArgumentError.notNull("buffer");
     }
 
     if (offset + length > buffer.length) {
-      throw new ArgumentError("The range exceeds the buffer length");
+      throw ArgumentError("The range exceeds the buffer length");
     }
 
     _writeBuffer.addAll(buffer.sublist(offset, offset + length));
   }
 
+  @override
   Future flush() {
     _readIterator = consumeWriteBuffer().iterator;
 
-    return new Future.value();
+    return Future.value();
   }
 }
diff --git a/lib/dart/lib/src/transport/t_framed_transport.dart b/lib/dart/lib/src/transport/t_framed_transport.dart
index 2ef03f7..3fc55fa 100644
--- a/lib/dart/lib/src/transport/t_framed_transport.dart
+++ b/lib/dart/lib/src/transport/t_framed_transport.dart
@@ -25,33 +25,37 @@
 
   final TTransport _transport;
 
-  final Uint8List _headerBytes = new Uint8List(headerByteCount);
+  final Uint8List _headerBytes = Uint8List(headerByteCount);
   int _receivedHeaderBytes = 0;
 
   int _bodySize = 0;
-  Uint8List _body = null;
+  Uint8List _body;
   int _receivedBodyBytes = 0;
 
-  Completer<Uint8List> _frameCompleter = null;
+  Completer<Uint8List> _frameCompleter;
 
   TFramedTransport(TTransport transport) : _transport = transport {
     if (transport == null) {
-      throw new ArgumentError.notNull("transport");
+      throw ArgumentError.notNull("transport");
     }
   }
 
+  @override
   bool get isOpen => _transport.isOpen;
 
+  @override
   Future open() {
     _reset(isOpen: true);
     return _transport.open();
   }
 
+  @override
   Future close() {
     _reset(isOpen: false);
     return _transport.close();
   }
 
+  @override
   int read(Uint8List buffer, int offset, int length) {
     if (hasReadData) {
       int got = super.read(buffer, offset, length);
@@ -78,10 +82,11 @@
   bool _readFrameHeader() {
     var remainingHeaderBytes = headerByteCount - _receivedHeaderBytes;
 
-    int got = _transport.read(_headerBytes, _receivedHeaderBytes, remainingHeaderBytes);
+    int got = _transport.read(
+        _headerBytes, _receivedHeaderBytes, remainingHeaderBytes);
     if (got < 0) {
-      throw new TTransportError(
-          TTransportErrorType.UNKNOWN, "Socket closed during frame header read");
+      throw TTransportError(TTransportErrorType.UNKNOWN,
+          "Socket closed during frame header read");
     }
 
     _receivedHeaderBytes += got;
@@ -92,12 +97,12 @@
       _receivedHeaderBytes = 0;
 
       if (size < 0) {
-        throw new TTransportError(
+        throw TTransportError(
             TTransportErrorType.UNKNOWN, "Read a negative frame size: $size");
       }
 
       _bodySize = size;
-      _body = new Uint8List(_bodySize);
+      _body = Uint8List(_bodySize);
       _receivedBodyBytes = 0;
 
       return true;
@@ -112,7 +117,7 @@
 
     int got = _transport.read(_body, _receivedBodyBytes, remainingBodyBytes);
     if (got < 0) {
-      throw new TTransportError(
+      throw TTransportError(
           TTransportErrorType.UNKNOWN, "Socket closed during frame body read");
     }
 
@@ -129,12 +134,13 @@
 
       var completer = _frameCompleter;
       _frameCompleter = null;
-      completer.complete(new Uint8List(0));
+      completer.complete(Uint8List(0));
     } else {
       _registerForReadableBytes();
     }
   }
 
+  @override
   Future flush() {
     if (_frameCompleter == null) {
       Uint8List buffer = consumeWriteBuffer();
@@ -144,7 +150,7 @@
       _transport.write(_headerBytes, 0, headerByteCount);
       _transport.write(buffer, 0, length);
 
-      _frameCompleter  = new Completer<Uint8List>();
+      _frameCompleter = Completer<Uint8List>();
       _registerForReadableBytes();
     }
 
diff --git a/lib/dart/lib/src/transport/t_http_transport.dart b/lib/dart/lib/src/transport/t_http_transport.dart
index 630213f..71fdb3c 100644
--- a/lib/dart/lib/src/transport/t_http_transport.dart
+++ b/lib/dart/lib/src/transport/t_http_transport.dart
@@ -34,31 +34,33 @@
 
   THttpClientTransport(this.httpClient, this.config) {
     if (httpClient == null) {
-      throw new ArgumentError.notNull("httpClient");
+      throw ArgumentError.notNull("httpClient");
     }
   }
 
+  @override
   Future close() async {
     _reset(isOpen: false);
     httpClient.close();
   }
 
+  @override
   Future flush() {
     var requestBody = base64.encode(consumeWriteBuffer());
 
     // Use a sync completer to ensure that the buffer can be read immediately
     // after the read buffer is set, and avoid a race condition where another
     // response could overwrite the read buffer.
-    var completer = new Completer.sync();
+    var completer = Completer.sync();
 
     httpClient
         .post(config.url, headers: config.headers, body: requestBody)
         .then((response) {
       Uint8List data;
       try {
-        data = new Uint8List.fromList(base64.decode(response.body));
+        data = Uint8List.fromList(base64.decode(response.body));
       } on FormatException catch (_) {
-        throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
+        throw TProtocolError(TProtocolErrorType.INVALID_DATA,
             "Expected a Base 64 encoded string.");
       }
 
@@ -78,7 +80,7 @@
 
   THttpConfig(this.url, Map<String, String> headers) {
     if (url == null || !url.hasAuthority) {
-      throw new ArgumentError("Invalid url");
+      throw ArgumentError("Invalid url");
     }
 
     _initHeaders(headers);
@@ -94,6 +96,6 @@
     h['Content-Type'] = 'application/x-thrift';
     h['Accept'] = 'application/x-thrift';
 
-    _headers = new Map.unmodifiable(h);
+    _headers = Map.unmodifiable(h);
   }
 }
diff --git a/lib/dart/lib/src/transport/t_message_reader.dart b/lib/dart/lib/src/transport/t_message_reader.dart
index 8ca0708..620a27a 100644
--- a/lib/dart/lib/src/transport/t_message_reader.dart
+++ b/lib/dart/lib/src/transport/t_message_reader.dart
@@ -27,8 +27,8 @@
 
   /// Construct a [MessageReader].  The optional [byteOffset] specifies the
   /// number of bytes to skip before reading the [TMessage].
-  TMessageReader(this.protocolFactory, {int byteOffset: 0})
-      : _transport = new _TMessageReaderTransport(),
+  TMessageReader(this.protocolFactory, {int byteOffset = 0})
+      : _transport = _TMessageReaderTransport(),
         this.byteOffset = byteOffset;
 
   TMessage readMessage(Uint8List bytes) {
@@ -54,7 +54,7 @@
     }
 
     if (offset > bytes.length) {
-      throw new ArgumentError("The offset exceeds the bytes length");
+      throw ArgumentError("The offset exceeds the bytes length");
     }
 
     _readIterator = bytes.iterator;
@@ -64,19 +64,23 @@
     }
   }
 
+  @override
   get isOpen => true;
 
-  Future open() => throw new UnsupportedError("Unsupported in MessageReader");
+  @override
+  Future open() => throw UnsupportedError("Unsupported in MessageReader");
 
-  Future close() => throw new UnsupportedError("Unsupported in MessageReader");
+  @override
+  Future close() => throw UnsupportedError("Unsupported in MessageReader");
 
+  @override
   int read(Uint8List buffer, int offset, int length) {
     if (buffer == null) {
-      throw new ArgumentError.notNull("buffer");
+      throw ArgumentError.notNull("buffer");
     }
 
     if (offset + length > buffer.length) {
-      throw new ArgumentError("The range exceeds the buffer length");
+      throw ArgumentError("The range exceeds the buffer length");
     }
 
     if (_readIterator == null || length <= 0) {
@@ -92,8 +96,10 @@
     return i;
   }
 
+  @override
   void write(Uint8List buffer, int offset, int length) =>
-      throw new UnsupportedError("Unsupported in MessageReader");
+      throw UnsupportedError("Unsupported in MessageReader");
 
-  Future flush() => throw new UnsupportedError("Unsupported in MessageReader");
+  @override
+  Future flush() => throw UnsupportedError("Unsupported in MessageReader");
 }
diff --git a/lib/dart/lib/src/transport/t_socket_transport.dart b/lib/dart/lib/src/transport/t_socket_transport.dart
index c41374a..d9929c8 100644
--- a/lib/dart/lib/src/transport/t_socket_transport.dart
+++ b/lib/dart/lib/src/transport/t_socket_transport.dart
@@ -28,27 +28,30 @@
 ///
 /// Adapted from the JS WebSocket transport.
 abstract class TSocketTransport extends TBufferedTransport {
-  final Logger logger = new Logger('thrift.TSocketTransport');
+  final Logger logger = Logger('thrift.TSocketTransport');
 
   final TSocket socket;
 
   /// A transport using the provided [socket].
   TSocketTransport(this.socket) {
     if (socket == null) {
-      throw new ArgumentError.notNull('socket');
+      throw ArgumentError.notNull('socket');
     }
 
     socket.onError.listen((e) => logger.warning(e));
     socket.onMessage.listen(handleIncomingMessage);
   }
 
+  @override
   bool get isOpen => socket.isOpen;
 
+  @override
   Future open() {
     _reset(isOpen: true);
     return socket.open();
   }
 
+  @override
   Future close() {
     _reset(isOpen: false);
     return socket.close();
@@ -70,13 +73,14 @@
 
   TClientSocketTransport(TSocket socket) : super(socket);
 
+  @override
   Future flush() {
     Uint8List bytes = consumeWriteBuffer();
 
     // Use a sync completer to ensure that the buffer can be read immediately
     // after the read buffer is set, and avoid a race condition where another
     // response could overwrite the read buffer.
-    var completer = new Completer<Uint8List>.sync();
+    var completer = Completer<Uint8List>.sync();
     _completers.add(completer);
 
     if (bytes.lengthInBytes > 0) {
@@ -86,6 +90,7 @@
     return completer.future;
   }
 
+  @override
   void handleIncomingMessage(Uint8List messageBytes) {
     super.handleIncomingMessage(messageBytes);
 
@@ -103,7 +108,7 @@
 /// incoming message arrives to correlate a response to a request, using the
 /// seqid.
 class TAsyncClientSocketTransport extends TSocketTransport {
-  static const defaultTimeout = const Duration(seconds: 30);
+  static const defaultTimeout = Duration(seconds: 30);
 
   final Map<int, Completer<Uint8List>> _completers = {};
 
@@ -112,11 +117,12 @@
   final Duration responseTimeout;
 
   TAsyncClientSocketTransport(TSocket socket, TMessageReader messageReader,
-      {Duration responseTimeout: defaultTimeout})
+      {Duration responseTimeout = defaultTimeout})
       : this.messageReader = messageReader,
         this.responseTimeout = responseTimeout,
         super(socket);
 
+  @override
   Future flush() {
     Uint8List bytes = consumeWriteBuffer();
     TMessage message = messageReader.readMessage(bytes);
@@ -125,15 +131,15 @@
     // Use a sync completer to ensure that the buffer can be read immediately
     // after the read buffer is set, and avoid a race condition where another
     // response could overwrite the read buffer.
-    var completer = new Completer<Uint8List>.sync();
+    var completer = Completer<Uint8List>.sync();
     _completers[seqid] = completer;
 
     if (responseTimeout != null) {
-      new Future.delayed(responseTimeout, () {
+      Future.delayed(responseTimeout, () {
         var completer = _completers.remove(seqid);
         if (completer != null) {
           completer.completeError(
-              new TimeoutException("Response timed out.", responseTimeout));
+              TimeoutException("Response timed out.", responseTimeout));
         }
       });
     }
@@ -143,6 +149,7 @@
     return completer.future;
   }
 
+  @override
   void handleIncomingMessage(Uint8List messageBytes) {
     super.handleIncomingMessage(messageBytes);
 
@@ -161,14 +168,16 @@
   Stream get onIncomingMessage => _onIncomingMessageController.stream;
 
   TServerSocketTransport(TSocket socket)
-      : _onIncomingMessageController = new StreamController.broadcast(),
+      : _onIncomingMessageController = StreamController.broadcast(),
         super(socket);
 
+  @override
   Future flush() async {
     Uint8List message = consumeWriteBuffer();
     socket.send(message);
   }
 
+  @override
   void handleIncomingMessage(Uint8List messageBytes) {
     super.handleIncomingMessage(messageBytes);
 
diff --git a/lib/dart/lib/src/transport/t_transport.dart b/lib/dart/lib/src/transport/t_transport.dart
index 563d5eb..ec9a4e8 100644
--- a/lib/dart/lib/src/transport/t_transport.dart
+++ b/lib/dart/lib/src/transport/t_transport.dart
@@ -44,7 +44,7 @@
     while (got < length) {
       ret = read(buffer, offset + got, length - got);
       if (ret <= 0) {
-        throw new TTransportError(
+        throw TTransportError(
             TTransportErrorType.UNKNOWN,
             "Cannot read. Remote side has closed. Tried to read $length "
             "bytes, but only got $got bytes.");
diff --git a/lib/dart/lib/src/transport/t_transport_factory.dart b/lib/dart/lib/src/transport/t_transport_factory.dart
index 7a10461..bbd95bf 100644
--- a/lib/dart/lib/src/transport/t_transport_factory.dart
+++ b/lib/dart/lib/src/transport/t_transport_factory.dart
@@ -23,5 +23,5 @@
 /// Adapted from the Java version.
 class TTransportFactory {
   Future<TTransport> getTransport(TTransport transport) =>
-      new Future.value(transport);
+      Future.value(transport);
 }
diff --git a/lib/dart/lib/thrift.dart b/lib/dart/lib/thrift.dart
index c429d77..dd89ebd 100644
--- a/lib/dart/lib/thrift.dart
+++ b/lib/dart/lib/thrift.dart
@@ -19,12 +19,9 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:convert' show Utf8Codec;
-import 'dart:typed_data' show ByteData;
-import 'dart:typed_data' show Uint8List;
+import 'dart:convert' show Utf8Codec, base64;
+import 'dart:typed_data' show ByteData, Uint8List, Endian;
 
-import 'package:dart2_constant/convert.dart' show base64;
-import 'package:dart2_constant/typed_data.dart' show Endianness;
 import 'package:fixnum/fixnum.dart';
 import 'package:http/http.dart' show Client;
 import 'package:logging/logging.dart';
diff --git a/lib/dart/pubspec.yaml b/lib/dart/pubspec.yaml
index 956d89b..28407e2 100644
--- a/lib/dart/pubspec.yaml
+++ b/lib/dart/pubspec.yaml
@@ -16,7 +16,7 @@
 # under the License.
 
 name: thrift
-version: 0.14.2
+version: 0.15.0
 description: >
   A Dart library for Apache Thrift
 author: Apache Thrift Developers <dev@thrift.apache.org>
@@ -24,15 +24,20 @@
 documentation: http://thrift.apache.org
 
 environment:
-  sdk: ">=1.24.3 <3.0.0"
+  sdk: ">=2.0.0 <3.0.0"
 
 dependencies:
-  dart2_constant: ^1.0.0
   fixnum: ^0.10.2
-  http: ^0.11.3
+  http: ">=0.11.3 <0.13.0"
   logging: ^0.11.0
 
 dev_dependencies:
-  dart_dev: ^2.0.0
-  mockito: ">=2.2.2 <4.0.0"
-  test: ">=0.12.30 <2.0.0"
+  build_runner: ^1.7.1
+  build_test: ^0.10.9
+  build_vm_compilers: ^1.0.3
+  build_web_compilers: ^2.7.1
+  dart_dev: ^3.0.0
+  dart_style: ^1.3.1
+  mockito: ^4.1.1
+  test: ^1.9.1
+  workiva_analysis_options: ^1.0.0
\ No newline at end of file
diff --git a/lib/dart/test/protocol/t_protocol_test.dart b/lib/dart/test/protocol/t_protocol_test.dart
index dc63dbb..15d973c 100644
--- a/lib/dart/test/protocol/t_protocol_test.dart
+++ b/lib/dart/test/protocol/t_protocol_test.dart
@@ -18,42 +18,42 @@
 library thrift.test.transport.t_json_protocol_test;
 
 import 'dart:async';
+import 'dart:convert' show utf8;
 import 'dart:typed_data' show Uint8List;
 
-import 'package:dart2_constant/convert.dart' show utf8;
 import 'package:test/test.dart';
 import 'package:thrift/thrift.dart';
 
 void main() {
-  final message = new TMessage('my message', TMessageType.ONEWAY, 123);
+  final message = TMessage('my message', TMessageType.ONEWAY, 123);
 
   TProtocol protocol;
 
   Primitive getPrimitive(int tType) {
     switch (tType) {
       case TType.BOOL:
-        return new Primitive(protocol.readBool, protocol.writeBool, false);
+        return Primitive(protocol.readBool, protocol.writeBool, false);
 
       case TType.BYTE:
-        return new Primitive(protocol.readByte, protocol.writeByte, 0);
+        return Primitive(protocol.readByte, protocol.writeByte, 0);
 
       case TType.I16:
-        return new Primitive(protocol.readI16, protocol.writeI16, 0);
+        return Primitive(protocol.readI16, protocol.writeI16, 0);
 
       case TType.I32:
-        return new Primitive(protocol.readI32, protocol.writeI32, 0);
+        return Primitive(protocol.readI32, protocol.writeI32, 0);
 
       case TType.I64:
-        return new Primitive(protocol.readI64, protocol.writeI64, 0);
+        return Primitive(protocol.readI64, protocol.writeI64, 0);
 
       case TType.DOUBLE:
-        return new Primitive(protocol.readDouble, protocol.writeDouble, 0);
+        return Primitive(protocol.readDouble, protocol.writeDouble, 0);
 
       case TType.STRING:
-        return new Primitive(protocol.readString, protocol.writeString, '');
+        return Primitive(protocol.readString, protocol.writeString, '');
 
       default:
-        throw new UnsupportedError("Unsupported TType $tType");
+        throw UnsupportedError("Unsupported TType $tType");
     }
   }
 
@@ -95,7 +95,7 @@
     });
 
     test('Test struct', () async {
-      var input = new TStruct();
+      var input = TStruct();
 
       protocol.writeStructBegin(input);
       protocol.writeStructEnd();
@@ -111,7 +111,7 @@
     });
 
     test('Test field', () async {
-      var input = new TField('my field', TType.MAP, 123);
+      var input = TField('my field', TType.MAP, 123);
 
       protocol.writeFieldBegin(input);
       protocol.writeFieldEnd();
@@ -128,7 +128,7 @@
     });
 
     test('Test map', () async {
-      var input = new TMap(TType.STRING, TType.STRUCT, 123);
+      var input = TMap(TType.STRING, TType.STRUCT, 123);
 
       protocol.writeMapBegin(input);
       protocol.writeMapEnd();
@@ -145,7 +145,7 @@
     });
 
     test('Test list', () async {
-      var input = new TList(TType.STRING, 123);
+      var input = TList(TType.STRING, 123);
 
       protocol.writeListBegin(input);
       protocol.writeListEnd();
@@ -161,7 +161,7 @@
     });
 
     test('Test set', () async {
-      var input = new TSet(TType.STRING, 123);
+      var input = TSet(TType.STRING, 123);
 
       protocol.writeSetBegin(input);
       protocol.writeSetEnd();
@@ -235,7 +235,7 @@
     });
 
     test('Test binary', () async {
-      var input = new Uint8List.fromList(new List.filled(100, 123));
+      var input = Uint8List.fromList(List.filled(100, 123));
 
       protocol.writeBinary(input);
       protocol.writeMessageEnd();
@@ -251,18 +251,18 @@
 
     test('Test complex struct', () async {
       // {1: {10: 20}, 2: {30: 40}}
-      protocol.writeStructBegin(new TStruct());
-      protocol.writeFieldBegin(new TField('success', TType.MAP, 0));
-      protocol.writeMapBegin(new TMap(TType.I32, TType.MAP, 2));
+      protocol.writeStructBegin(TStruct());
+      protocol.writeFieldBegin(TField('success', TType.MAP, 0));
+      protocol.writeMapBegin(TMap(TType.I32, TType.MAP, 2));
 
       protocol.writeI32(1); // key
-      protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1));
+      protocol.writeMapBegin(TMap(TType.I32, TType.I32, 1));
       protocol.writeI32(10); // key
       protocol.writeI32(20); // value
       protocol.writeMapEnd();
 
       protocol.writeI32(2); // key
-      protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1));
+      protocol.writeMapBegin(TMap(TType.I32, TType.I32, 1));
       protocol.writeI32(30); // key
       protocol.writeI32(40); // value
       protocol.writeMapEnd();
@@ -300,19 +300,19 @@
 
     test('Test nested maps and lists', () async {
       // {1: [{10: 20}], 2: [{30: 40}]}
-      protocol.writeMapBegin(new TMap(TType.I32, TType.LIST, 2));
+      protocol.writeMapBegin(TMap(TType.I32, TType.LIST, 2));
 
       protocol.writeI32(1); // key
-      protocol.writeListBegin(new TList(TType.MAP, 1));
-      protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1));
+      protocol.writeListBegin(TList(TType.MAP, 1));
+      protocol.writeMapBegin(TMap(TType.I32, TType.I32, 1));
       protocol.writeI32(10); // key
       protocol.writeI32(20); // value
       protocol.writeMapEnd();
       protocol.writeListEnd();
 
       protocol.writeI32(2); // key
-      protocol.writeListBegin(new TList(TType.MAP, 1));
-      protocol.writeMapBegin(new TMap(TType.I32, TType.I32, 1));
+      protocol.writeListBegin(TList(TType.MAP, 1));
+      protocol.writeMapBegin(TMap(TType.I32, TType.I32, 1));
       protocol.writeI32(30); // key
       protocol.writeI32(40); // value
       protocol.writeMapEnd();
@@ -349,7 +349,7 @@
 
   group('JSON', () {
     setUp(() {
-      protocol = new TJsonProtocol(new TBufferedTransport());
+      protocol = TJsonProtocol(TBufferedTransport());
       protocol.writeMessageBegin(message);
     });
 
@@ -363,10 +363,10 @@
            UTF-16: 0xD834 0xDD1E
        */
       var buffer = utf8.encode(r'"\u0001\u0e01 \ud834\udd1e"');
-      var transport = new TBufferedTransport();
+      var transport = TBufferedTransport();
       transport.writeAll(buffer);
 
-      var protocol = new TJsonProtocol(transport);
+      var protocol = TJsonProtocol(transport);
 
       await protocol.transport.flush();
 
@@ -380,7 +380,7 @@
 
   group('binary', () {
     setUp(() {
-      protocol = new TBinaryProtocol(new TBufferedTransport());
+      protocol = TBinaryProtocol(TBufferedTransport());
       protocol.writeMessageBegin(message);
     });
 
@@ -389,7 +389,7 @@
 
   group('compact', () {
     setUp(() {
-      protocol = new TCompactProtocol(new TBufferedTransport());
+      protocol = TCompactProtocol(TBufferedTransport());
       protocol.writeMessageBegin(message);
     });
 
diff --git a/lib/dart/test/serializer/serializer_test.dart b/lib/dart/test/serializer/serializer_test.dart
index 2f76503..89883cb 100644
--- a/lib/dart/test/serializer/serializer_test.dart
+++ b/lib/dart/test/serializer/serializer_test.dart
@@ -30,22 +30,22 @@
     TestTObject testTObject;
 
     setUp(() {
-      serializer = new TSerializer();
-      deserializer = new TDeserializer();
-      
-      testTObject = new TestTObject();
+      serializer = TSerializer();
+      deserializer = TDeserializer();
+
+      testTObject = TestTObject();
       testTObject.b = true;
       testTObject.s = "TEST";
       testTObject.d = 15.25;
       testTObject.i = 10;
-      
-      var testList = new List<String>();
+
+      var testList = List<String>();
       testList.add("TEST 1");
       testList.add("TEST 2");
-      
+
       testTObject.l = testList;
     });
-    
+
     assertNewObjectEqualsTObject(TestTObject newObject) {
       expect(newObject.l, equals(testTObject.l));
       expect(newObject.b, equals(testTObject.b));
@@ -53,63 +53,63 @@
       expect(newObject.d, equals(testTObject.d));
       expect(newObject.s, equals(testTObject.s));
     }
-    
+
     runWriteStringTest() {
       var s = serializer.writeString(testTObject);
 
-      var newObject = new TestTObject();
+      var newObject = TestTObject();
       deserializer.readString(newObject, s);
 
       assertNewObjectEqualsTObject(newObject);
-    };
+    }
 
     runWriteTest() {
       var s = serializer.write(testTObject);
 
-      var newObject = new TestTObject();
+      var newObject = TestTObject();
       deserializer.read(newObject, s);
 
       assertNewObjectEqualsTObject(newObject);
-    };
+    }
 
     test('JSON Protocol String', () {
-      serializer.protocol = new TJsonProtocol(serializer.transport);
-      deserializer.protocol = new TJsonProtocol(deserializer.transport);
-      
+      serializer.protocol = TJsonProtocol(serializer.transport);
+      deserializer.protocol = TJsonProtocol(deserializer.transport);
+
       runWriteStringTest();
     });
 
     test('JSON Protocol', () {
-      serializer.protocol = new TJsonProtocol(serializer.transport);
-      deserializer.protocol = new TJsonProtocol(deserializer.transport);
+      serializer.protocol = TJsonProtocol(serializer.transport);
+      deserializer.protocol = TJsonProtocol(deserializer.transport);
 
       runWriteTest();
     });
 
     test('Binary Protocol String', () {
-      serializer.protocol = new TBinaryProtocol(serializer.transport);
-      deserializer.protocol = new TBinaryProtocol(deserializer.transport);
+      serializer.protocol = TBinaryProtocol(serializer.transport);
+      deserializer.protocol = TBinaryProtocol(deserializer.transport);
 
       runWriteStringTest();
     });
 
     test('Binary Protocol', () {
-      serializer.protocol = new TBinaryProtocol(serializer.transport);
-      deserializer.protocol = new TBinaryProtocol(deserializer.transport);
+      serializer.protocol = TBinaryProtocol(serializer.transport);
+      deserializer.protocol = TBinaryProtocol(deserializer.transport);
 
       runWriteTest();
     });
 
     test('Compact Protocol String', () {
-      serializer.protocol = new TCompactProtocol(serializer.transport);
-      deserializer.protocol = new TCompactProtocol(deserializer.transport);
+      serializer.protocol = TCompactProtocol(serializer.transport);
+      deserializer.protocol = TCompactProtocol(deserializer.transport);
 
       runWriteStringTest();
     });
 
     test('Compact Protocol', () {
-      serializer.protocol = new TCompactProtocol(serializer.transport);
-      deserializer.protocol = new TCompactProtocol(deserializer.transport);
+      serializer.protocol = TCompactProtocol(serializer.transport);
+      deserializer.protocol = TCompactProtocol(deserializer.transport);
 
       runWriteTest();
     });
diff --git a/lib/dart/test/serializer/serializer_test_data.dart b/lib/dart/test/serializer/serializer_test_data.dart
index 3586f08..fc488f4 100644
--- a/lib/dart/test/serializer/serializer_test_data.dart
+++ b/lib/dart/test/serializer/serializer_test_data.dart
@@ -23,12 +23,12 @@
 
 /// TestTObject is a simple test struct
 class TestTObject implements TBase {
-  static final TStruct _STRUCT_DESC = new TStruct("TestTObject");
-  static final TField _I_FIELD_DESC = new TField("i", TType.I32, 1);
-  static final TField _D_FIELD_DESC = new TField("d", TType.DOUBLE, 2);
-  static final TField _S_FIELD_DESC = new TField("s", TType.STRING, 3);
-  static final TField _L_FIELD_DESC = new TField("l", TType.LIST, 4);
-  static final TField _B_FIELD_DESC = new TField("b", TType.BOOL, 5);
+  static final TStruct _STRUCT_DESC = TStruct("TestTObject");
+  static final TField _I_FIELD_DESC = TField("i", TType.I32, 1);
+  static final TField _D_FIELD_DESC = TField("d", TType.DOUBLE, 2);
+  static final TField _S_FIELD_DESC = TField("s", TType.STRING, 3);
+  static final TField _L_FIELD_DESC = TField("l", TType.LIST, 4);
+  static final TField _B_FIELD_DESC = TField("b", TType.BOOL, 5);
 
   int _i;
   static const int I = 1;
@@ -45,8 +45,7 @@
   bool __isset_d = false;
   bool __isset_b = false;
 
-  TestTObject() {
-  }
+  TestTObject();
 
   // i
   int get i => this._i;
@@ -116,6 +115,7 @@
     this.__isset_b = false;
   }
 
+  @override
   getFieldValue(int fieldID) {
     switch (fieldID) {
       case I:
@@ -129,10 +129,11 @@
       case B:
         return this.b;
       default:
-        throw new ArgumentError("Field $fieldID doesn't exist!");
+        throw ArgumentError("Field $fieldID doesn't exist!");
     }
   }
 
+  @override
   setFieldValue(int fieldID, Object value) {
     switch (fieldID) {
       case I:
@@ -176,11 +177,12 @@
         break;
 
       default:
-        throw new ArgumentError("Field $fieldID doesn't exist!");
+        throw ArgumentError("Field $fieldID doesn't exist!");
     }
   }
 
   // Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise
+  @override
   bool isSet(int fieldID) {
     switch (fieldID) {
       case I:
@@ -194,10 +196,11 @@
       case B:
         return isSetB();
       default:
-        throw new ArgumentError("Field $fieldID doesn't exist!");
+        throw ArgumentError("Field $fieldID doesn't exist!");
     }
   }
 
+  @override
   read(TProtocol iprot) {
     TField field;
     iprot.readStructBegin();
@@ -234,7 +237,7 @@
           if (field.type == TType.LIST) {
             {
               TList _list74 = iprot.readListBegin();
-              this.l = new List<String>();
+              this.l = List<String>();
               for (int _i75 = 0; _i75 < _list74.length; ++_i75) {
                 String _elem76;
                 _elem76 = iprot.readString();
@@ -266,6 +269,7 @@
     validate();
   }
 
+  @override
   write(TProtocol oprot) {
     validate();
 
@@ -284,7 +288,7 @@
     if (this.l != null) {
       oprot.writeFieldBegin(_L_FIELD_DESC);
       {
-        oprot.writeListBegin(new TList(TType.STRING, this.l.length));
+        oprot.writeListBegin(TList(TType.STRING, this.l.length));
         for (var elem77 in this.l) {
           oprot.writeString(elem77);
         }
@@ -299,8 +303,9 @@
     oprot.writeStructEnd();
   }
 
+  @override
   String toString() {
-    StringBuffer ret = new StringBuffer("TestTObject(");
+    StringBuffer ret = StringBuffer("TestTObject(");
 
     ret.write("i:");
     ret.write(this.i);
@@ -338,5 +343,4 @@
     // check for required fields
     // check that fields of type enum have valid values
   }
-
 }
diff --git a/lib/dart/test/t_application_error_test.dart b/lib/dart/test/t_application_error_test.dart
index 511d8d6..848ce56 100644
--- a/lib/dart/test/t_application_error_test.dart
+++ b/lib/dart/test/t_application_error_test.dart
@@ -24,15 +24,14 @@
   TProtocol protocol;
 
   setUp(() {
-    protocol = new TBinaryProtocol(new TBufferedTransport());
+    protocol = TBinaryProtocol(TBufferedTransport());
   });
 
   test('Write and read an application error', () {
     var expectedType = TApplicationErrorType.INTERNAL_ERROR;
     var expectedMessage = 'test error message';
 
-    TApplicationError error =
-        new TApplicationError(expectedType, expectedMessage);
+    TApplicationError error = TApplicationError(expectedType, expectedMessage);
     error.write(protocol);
 
     protocol.transport.flush();
diff --git a/lib/dart/test/transport/t_framed_transport_test.dart b/lib/dart/test/transport/t_framed_transport_test.dart
index 7ab4905..d9a15a5 100644
--- a/lib/dart/test/transport/t_framed_transport_test.dart
+++ b/lib/dart/test/transport/t_framed_transport_test.dart
@@ -18,15 +18,15 @@
 library thrift.test.transport.t_framed_transport_test;
 
 import 'dart:async';
+import 'dart:convert' show utf8;
 import 'dart:typed_data' show Uint8List;
 
-import 'package:dart2_constant/convert.dart' show utf8;
 import 'package:test/test.dart';
 import 'package:thrift/thrift.dart';
 
 void main() {
   group('TFramedTransport partial reads', () {
-    final flushAwaitDuration = new Duration(seconds: 10);
+    final flushAwaitDuration = Duration(seconds: 10);
 
     FakeReadOnlySocket socket;
     TSocketTransport socketTransport;
@@ -34,22 +34,24 @@
     var messageAvailable;
 
     setUp(() {
-      socket = new FakeReadOnlySocket();
-      socketTransport = new TClientSocketTransport(socket);
-      transport = new TFramedTransport(socketTransport);
+      socket = FakeReadOnlySocket();
+      socketTransport = TClientSocketTransport(socket);
+      transport = TFramedTransport(socketTransport);
       messageAvailable = false;
     });
 
     expectNoReadableBytes() {
-      var readBuffer = new Uint8List(128);
+      var readBuffer = Uint8List(128);
       var readBytes = transport.read(readBuffer, 0, readBuffer.lengthInBytes);
       expect(readBytes, 0);
       expect(messageAvailable, false);
     }
 
-    test('Test transport reads messages where header and body are sent separately', () async {
+    test(
+        'Test transport reads messages where header and body are sent separately',
+        () async {
       // buffer into which we'll read
-      var readBuffer = new Uint8List(10);
+      var readBuffer = Uint8List(10);
       var readBytes;
 
       // registers for readable bytes
@@ -59,21 +61,22 @@
       });
 
       // write header bytes
-      socket.messageController.add(new Uint8List.fromList([0x00, 0x00, 0x00, 0x06]));
+      socket.messageController
+          .add(Uint8List.fromList([0x00, 0x00, 0x00, 0x06]));
 
       // you shouldn't be able to get any bytes from the read,
       // because the header has been consumed internally
       expectNoReadableBytes();
 
       // write first batch of body
-      socket.messageController.add(new Uint8List.fromList(utf8.encode("He")));
+      socket.messageController.add(Uint8List.fromList(utf8.encode("He")));
 
       // you shouldn't be able to get any bytes from the read,
       // because the frame has been consumed internally
       expectNoReadableBytes();
 
       // write second batch of body
-      socket.messageController.add(new Uint8List.fromList(utf8.encode("llo!")));
+      socket.messageController.add(Uint8List.fromList(utf8.encode("llo!")));
 
       // have to wait for the flush to complete,
       // because it's only then that the frame is available for reading
@@ -86,10 +89,11 @@
       expect(readBuffer.sublist(0, 6), utf8.encode("Hello!"));
     });
 
-    test('Test transport reads messages where header is sent in pieces '
-         'and body is also sent in pieces', () async {
+    test(
+        'Test transport reads messages where header is sent in pieces '
+        'and body is also sent in pieces', () async {
       // buffer into which we'll read
-      var readBuffer = new Uint8List(10);
+      var readBuffer = Uint8List(10);
       var readBytes;
 
       // registers for readable bytes
@@ -99,27 +103,27 @@
       });
 
       // write first part of header bytes
-      socket.messageController.add(new Uint8List.fromList([0x00, 0x00]));
+      socket.messageController.add(Uint8List.fromList([0x00, 0x00]));
 
       // you shouldn't be able to get any bytes from the read
       expectNoReadableBytes();
 
       // write second part of header bytes
-      socket.messageController.add(new Uint8List.fromList([0x00, 0x03]));
+      socket.messageController.add(Uint8List.fromList([0x00, 0x03]));
 
       // you shouldn't be able to get any bytes from the read again
       // because only the header was read, and there's no frame body
       readBytes = expectNoReadableBytes();
 
       // write first batch of body
-      socket.messageController.add(new Uint8List.fromList(utf8.encode("H")));
+      socket.messageController.add(Uint8List.fromList(utf8.encode("H")));
 
       // you shouldn't be able to get any bytes from the read,
       // because the frame has been consumed internally
       expectNoReadableBytes();
 
       // write second batch of body
-      socket.messageController.add(new Uint8List.fromList(utf8.encode("i!")));
+      socket.messageController.add(Uint8List.fromList(utf8.encode("i!")));
 
       // have to wait for the flush to complete,
       // because it's only then that the frame is available for reading
@@ -134,17 +138,18 @@
   });
 }
 
-
-
 class FakeReadOnlySocket extends TSocket {
-
-  StreamController<Uint8List> messageController = new StreamController<Uint8List>(sync: true);
-  StreamController<Object> errorController = new StreamController<Object>();
-  StreamController<TSocketState> stateController = new StreamController<TSocketState>();
+  StreamController<Uint8List> messageController =
+      StreamController<Uint8List>(sync: true);
+  StreamController<Object> errorController = StreamController<Object>();
+  StreamController<TSocketState> stateController =
+      StreamController<TSocketState>();
 
   @override
-  Future close() {
-    // noop
+  Future close() async {
+    messageController.close();
+    errorController.close();
+    stateController.close();
   }
 
   @override
@@ -163,7 +168,7 @@
   Stream<TSocketState> get onState => stateController.stream;
 
   @override
-  Future open() {
+  Future open() async {
     // noop
   }
 
@@ -172,4 +177,3 @@
     // noop
   }
 }
-
diff --git a/lib/dart/test/transport/t_http_transport_test.dart b/lib/dart/test/transport/t_http_transport_test.dart
index 03ccede..13f0ee9 100644
--- a/lib/dart/test/transport/t_http_transport_test.dart
+++ b/lib/dart/test/transport/t_http_transport_test.dart
@@ -20,9 +20,9 @@
 import 'dart:async';
 import 'dart:convert' show Encoding;
 import 'dart:convert' show Utf8Codec;
+import 'dart:convert' show base64;
 import 'dart:typed_data' show Uint8List;
 
-import 'package:dart2_constant/convert.dart' show base64;
 import 'package:http/http.dart' show BaseRequest;
 import 'package:http/http.dart' show Client;
 import 'package:http/http.dart' show Response;
@@ -31,16 +31,16 @@
 import 'package:thrift/thrift.dart';
 
 void main() {
-  const utf8Codec = const Utf8Codec();
+  const utf8Codec = Utf8Codec();
 
   group('THttpClientTransport', () {
     FakeHttpClient client;
     THttpClientTransport transport;
 
     setUp(() {
-      client = new FakeHttpClient(sync: false);
-      var config = new THttpConfig(Uri.parse('http://localhost'), {});
-      transport = new THttpClientTransport(client, config);
+      client = FakeHttpClient(sync: false);
+      var config = THttpConfig(Uri.parse('http://localhost'), {});
+      transport = THttpClientTransport(client, config);
     });
 
     test('Test transport sends body', () async {
@@ -69,7 +69,7 @@
 
       expect(transport.hasReadData, isTrue);
 
-      var buffer = new Uint8List(expectedBytes.length);
+      var buffer = Uint8List(expectedBytes.length);
       transport.readAll(buffer, 0, expectedBytes.length);
 
       var bufferText = utf8Codec.decode(buffer);
@@ -82,9 +82,9 @@
     THttpClientTransport transport;
 
     setUp(() {
-      client = new FakeHttpClient(sync: true);
-      var config = new THttpConfig(Uri.parse('http://localhost'), {});
-      transport = new THttpClientTransport(client, config);
+      client = FakeHttpClient(sync: true);
+      var config = THttpConfig(Uri.parse('http://localhost'), {});
+      transport = THttpClientTransport(client, config);
     });
 
     test('Test read correct buffer after flush', () async {
@@ -97,7 +97,7 @@
       client.postResponse = base64.encode(expectedBytes);
 
       Future responseReady = transport.flush().then((_) {
-        var buffer = new Uint8List(expectedBytes.length);
+        var buffer = Uint8List(expectedBytes.length);
         transport.readAll(buffer, 0, expectedBytes.length);
         bufferText = utf8Codec.decode(buffer);
       });
@@ -120,45 +120,55 @@
 
   final bool sync;
 
-  FakeHttpClient({this.sync: false});
+  FakeHttpClient({this.sync = false});
 
+  @override
   Future<Response> post(url,
       {Map<String, String> headers, body, Encoding encoding}) {
     postRequest = body;
-    var response = new Response(postResponse, 200);
+    var response = Response(postResponse, 200);
 
     if (sync) {
-      return new Future.sync(() => response);
+      return Future.sync(() => response);
     } else {
-      return new Future.value(response);
+      return Future.value(response);
     }
   }
 
+  @override
   Future<Response> head(url, {Map<String, String> headers}) =>
-      throw new UnimplementedError();
+      throw UnimplementedError();
 
+  @override
   Future<Response> get(url, {Map<String, String> headers}) =>
-      throw new UnimplementedError();
+      throw UnimplementedError();
 
+  @override
   Future<Response> put(url,
           {Map<String, String> headers, body, Encoding encoding}) =>
-      throw new UnimplementedError();
+      throw UnimplementedError();
 
+  @override
   Future<Response> patch(url,
           {Map<String, String> headers, body, Encoding encoding}) =>
-      throw new UnimplementedError();
+      throw UnimplementedError();
 
+  @override
   Future<Response> delete(url, {Map<String, String> headers}) =>
-      throw new UnimplementedError();
+      throw UnimplementedError();
 
+  @override
   Future<String> read(url, {Map<String, String> headers}) =>
-      throw new UnimplementedError();
+      throw UnimplementedError();
 
+  @override
   Future<Uint8List> readBytes(url, {Map<String, String> headers}) =>
-      throw new UnimplementedError();
+      throw UnimplementedError();
 
+  @override
   Future<StreamedResponse> send(BaseRequest request) =>
-      throw new UnimplementedError();
+      throw UnimplementedError();
 
-  void close() => throw new UnimplementedError();
+  @override
+  void close() => throw UnimplementedError();
 }
diff --git a/lib/dart/test/transport/t_socket_transport_test.dart b/lib/dart/test/transport/t_socket_transport_test.dart
index 90bffbe..d46f5ed 100644
--- a/lib/dart/test/transport/t_socket_transport_test.dart
+++ b/lib/dart/test/transport/t_socket_transport_test.dart
@@ -18,24 +18,22 @@
 library thrift.test.transport.t_socket_transport_test;
 
 import 'dart:async';
-import 'dart:convert' show Utf8Codec;
+import 'dart:convert' show Utf8Codec, base64;
 import 'dart:typed_data' show Uint8List;
 
-import 'package:dart2_constant/convert.dart' show base64;
-import 'package:dart2_constant/core.dart' as core;
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 import 'package:thrift/thrift.dart';
 
 void main() {
-  const utf8Codec = const Utf8Codec();
+  const utf8Codec = Utf8Codec();
 
   final requestText = 'my test request';
-  final requestBytes = new Uint8List.fromList(utf8Codec.encode(requestText));
+  final requestBytes = Uint8List.fromList(utf8Codec.encode(requestText));
   final requestBase64 = base64.encode(requestBytes);
 
   final responseText = 'response 1';
-  final responseBytes = new Uint8List.fromList(utf8Codec.encode(responseText));
+  final responseBytes = Uint8List.fromList(utf8Codec.encode(responseText));
   final responseBase64 = base64.encode(responseBytes);
 
   final framedResponseBase64 = base64.encode(_getFramedResponse(responseBytes));
@@ -45,9 +43,9 @@
     TTransport transport;
 
     setUp(() async {
-      socket = new FakeSocket(sync: false);
+      socket = FakeSocket(sync: false);
       await socket.open();
-      transport = new TClientSocketTransport(socket);
+      transport = TClientSocketTransport(socket);
       await transport.open();
       transport.writeAll(requestBytes);
     });
@@ -58,7 +56,7 @@
       Future responseReady = transport.flush();
 
       // allow microtask events to finish
-      await new Future.value();
+      await Future.value();
 
       expect(socket.sendPayload, isNotNull);
       expect(socket.sendPayload, requestBytes);
@@ -67,23 +65,23 @@
       socket.receiveFakeMessage(responseBase64);
 
       await responseReady;
-      var buffer = new Uint8List(responseBytes.length);
+      var buffer = Uint8List(responseBytes.length);
       transport.readAll(buffer, 0, responseBytes.length);
       var bufferText = utf8Codec.decode(buffer);
 
       expect(bufferText, responseText);
     });
-  }, timeout: new Timeout(new Duration(seconds: 1)));
+  }, timeout: Timeout(Duration(seconds: 1)));
 
   group('TClientSocketTransport with FramedTransport', () {
     FakeSocket socket;
     TTransport transport;
 
     setUp(() async {
-      socket = new FakeSocket(sync: true);
+      socket = FakeSocket(sync: true);
       await socket.open();
 
-      transport = new TFramedTransport(new TClientSocketTransport(socket));
+      transport = TFramedTransport(TClientSocketTransport(socket));
       await transport.open();
       transport.writeAll(requestBytes);
     });
@@ -92,7 +90,7 @@
       String bufferText;
 
       Future responseReady = transport.flush().then((_) {
-        var buffer = new Uint8List(responseBytes.length);
+        var buffer = Uint8List(responseBytes.length);
         transport.readAll(buffer, 0, responseBytes.length);
         bufferText = utf8Codec.decode(buffer);
       });
@@ -103,7 +101,7 @@
       await responseReady;
       expect(bufferText, responseText);
     });
-  }, timeout: new Timeout(new Duration(seconds: 1)));
+  }, timeout: Timeout(Duration(seconds: 1)));
 
   group('TAsyncClientSocketTransport', () {
     FakeSocket socket;
@@ -111,14 +109,14 @@
     TTransport transport;
 
     setUp(() async {
-      socket = new FakeSocket(sync: true);
+      socket = FakeSocket(sync: true);
       await socket.open();
 
-      protocolFactory = new FakeProtocolFactory();
-      protocolFactory.message = new TMessage('foo', TMessageType.CALL, 123);
-      transport = new TAsyncClientSocketTransport(
-          socket, new TMessageReader(protocolFactory),
-          responseTimeout: core.Duration.zero);
+      protocolFactory = FakeProtocolFactory();
+      protocolFactory.message = TMessage('foo', TMessageType.CALL, 123);
+      transport = TAsyncClientSocketTransport(
+          socket, TMessageReader(protocolFactory),
+          responseTimeout: Duration.zero);
       await transport.open();
       transport.writeAll(requestBytes);
     });
@@ -127,21 +125,20 @@
       String bufferText;
 
       Future responseReady = transport.flush().then((_) {
-        var buffer = new Uint8List(responseBytes.length);
+        var buffer = Uint8List(responseBytes.length);
         transport.readAll(buffer, 0, responseBytes.length);
         bufferText = utf8Codec.decode(buffer);
       });
 
       // simulate a response
-      protocolFactory.message = new TMessage('foo', TMessageType.REPLY, 123);
+      protocolFactory.message = TMessage('foo', TMessageType.REPLY, 123);
       socket.receiveFakeMessage(responseBase64);
 
       // simulate a second response
       var response2Text = 'response 2';
-      var response2Bytes =
-          new Uint8List.fromList(utf8Codec.encode(response2Text));
+      var response2Bytes = Uint8List.fromList(utf8Codec.encode(response2Text));
       var response2Base64 = base64.encode(response2Bytes);
-      protocolFactory.message = new TMessage('foo2', TMessageType.REPLY, 124);
+      protocolFactory.message = TMessage('foo2', TMessageType.REPLY, 124);
       socket.receiveFakeMessage(response2Base64);
 
       await responseReady;
@@ -150,9 +147,9 @@
 
     test('Test response timeout', () async {
       Future responseReady = transport.flush();
-      expect(responseReady, throwsA(new isInstanceOf<TimeoutException>()));
+      expect(responseReady, throwsA(isA<TimeoutException>()));
     });
-  }, timeout: new Timeout(new Duration(seconds: 1)));
+  }, timeout: Timeout(Duration(seconds: 1)));
 
   group('TAsyncClientSocketTransport with TFramedTransport', () {
     FakeSocket socket;
@@ -160,17 +157,17 @@
     TTransport transport;
 
     setUp(() async {
-      socket = new FakeSocket(sync: true);
+      socket = FakeSocket(sync: true);
       await socket.open();
 
-      protocolFactory = new FakeProtocolFactory();
-      protocolFactory.message = new TMessage('foo', TMessageType.CALL, 123);
-      var messageReader = new TMessageReader(protocolFactory,
+      protocolFactory = FakeProtocolFactory();
+      protocolFactory.message = TMessage('foo', TMessageType.CALL, 123);
+      var messageReader = TMessageReader(protocolFactory,
           byteOffset: TFramedTransport.headerByteCount);
 
-      transport = new TFramedTransport(new TAsyncClientSocketTransport(
+      transport = TFramedTransport(TAsyncClientSocketTransport(
           socket, messageReader,
-          responseTimeout: core.Duration.zero));
+          responseTimeout: Duration.zero));
       await transport.open();
       transport.writeAll(requestBytes);
     });
@@ -179,37 +176,37 @@
       String bufferText;
 
       Future responseReady = transport.flush().then((_) {
-        var buffer = new Uint8List(responseBytes.length);
+        var buffer = Uint8List(responseBytes.length);
         transport.readAll(buffer, 0, responseBytes.length);
         bufferText = utf8Codec.decode(buffer);
       });
 
       // simulate a response
-      protocolFactory.message = new TMessage('foo', TMessageType.REPLY, 123);
+      protocolFactory.message = TMessage('foo', TMessageType.REPLY, 123);
       socket.receiveFakeMessage(framedResponseBase64);
 
       await responseReady;
       expect(bufferText, responseText);
     });
-  }, timeout: new Timeout(new Duration(seconds: 1)));
+  }, timeout: Timeout(Duration(seconds: 1)));
 
   group('TServerTransport', () {
     test('Test server transport listens to socket', () async {
-      var socket = new FakeSocket();
+      var socket = FakeSocket();
       await socket.open();
       expect(socket.isOpen, isTrue);
 
-      var transport = new TServerSocketTransport(socket);
+      var transport = TServerSocketTransport(socket);
       expect(transport.hasReadData, isFalse);
 
       socket.receiveFakeMessage(requestBase64);
 
       // allow microtask events to finish
-      await new Future.value();
+      await Future.value();
 
       expect(transport.hasReadData, isTrue);
 
-      var buffer = new Uint8List(requestBytes.length);
+      var buffer = Uint8List(requestBytes.length);
       transport.readAll(buffer, 0, requestBytes.length);
 
       var bufferText = utf8Codec.decode(buffer);
@@ -217,10 +214,10 @@
     });
 
     test('Test server sending data over transport', () async {
-      var socket = new FakeSocket();
+      var socket = FakeSocket();
       await socket.open();
 
-      var transport = new TServerSocketTransport(socket);
+      var transport = TServerSocketTransport(socket);
 
       transport.writeAll(responseBytes);
       expect(socket.sendPayload, isNull);
@@ -228,40 +225,47 @@
       transport.flush();
 
       // allow microtask events to finish
-      await new Future.value();
+      await Future.value();
 
       expect(socket.sendPayload, isNotNull);
       expect(socket.sendPayload, responseBytes);
     });
-  }, timeout: new Timeout(new Duration(seconds: 1)));
+  }, timeout: Timeout(Duration(seconds: 1)));
 }
 
 class FakeSocket extends TSocket {
   final StreamController<TSocketState> _onStateController;
+  @override
   Stream<TSocketState> get onState => _onStateController.stream;
 
   final StreamController<Object> _onErrorController;
+  @override
   Stream<Object> get onError => _onErrorController.stream;
 
   final StreamController<Uint8List> _onMessageController;
+  @override
   Stream<Uint8List> get onMessage => _onMessageController.stream;
 
-  FakeSocket({bool sync: false})
-      : _onStateController = new StreamController.broadcast(sync: sync),
-        _onErrorController = new StreamController.broadcast(sync: sync),
-        _onMessageController = new StreamController.broadcast(sync: sync);
+  FakeSocket({bool sync =  false})
+      : _onStateController = StreamController.broadcast(sync: sync),
+        _onErrorController = StreamController.broadcast(sync: sync),
+        _onMessageController = StreamController.broadcast(sync: sync);
 
   bool _isOpen;
 
+  @override
   bool get isOpen => _isOpen;
 
+  @override
   bool get isClosed => !isOpen;
 
+  @override
   Future open() async {
     _isOpen = true;
     _onStateController.add(TSocketState.OPEN);
   }
 
+  @override
   Future close() async {
     _isOpen = false;
     _onStateController.add(TSocketState.CLOSED);
@@ -270,16 +274,17 @@
   Uint8List _sendPayload;
   Uint8List get sendPayload => _sendPayload;
 
+  @override
   void send(Uint8List data) {
-    if (!isOpen) throw new StateError('The socket is not open');
+    if (!isOpen) throw StateError('The socket is not open');
 
     _sendPayload = data;
   }
 
   void receiveFakeMessage(String base64text) {
-    if (!isOpen) throw new StateError('The socket is not open');
+    if (!isOpen) throw StateError('The socket is not open');
 
-    var message = new Uint8List.fromList(base64.decode(base64text));
+    var message = Uint8List.fromList(base64.decode(base64text));
     _onMessageController.add(message);
   }
 }
@@ -289,7 +294,8 @@
 
   TMessage message;
 
-  getProtocol(TTransport transport) => new FakeProtocol(message);
+  @override
+  getProtocol(TTransport transport) => FakeProtocol(message);
 }
 
 class FakeProtocol extends Mock implements TProtocol {
@@ -297,12 +303,13 @@
 
   TMessage _message;
 
+  @override
   readMessageBegin() => _message;
 }
 
 Uint8List _getFramedResponse(Uint8List responseBytes) {
   var byteOffset = TFramedTransport.headerByteCount;
-  var response = new Uint8List(byteOffset + responseBytes.length);
+  var response = Uint8List(byteOffset + responseBytes.length);
 
   response.buffer.asByteData().setInt32(0, responseBytes.length);
   response.setAll(byteOffset, responseBytes);
diff --git a/lib/dart/test/transport/t_transport_test.dart b/lib/dart/test/transport/t_transport_test.dart
index 0bb381a..4758593 100644
--- a/lib/dart/test/transport/t_transport_test.dart
+++ b/lib/dart/test/transport/t_transport_test.dart
@@ -25,14 +25,14 @@
   group('TTransportFactory', () {
     test('transport is returned from base factory', () async {
       TTransport result;
-      TTransport transport = null;
+      TTransport transport;
 
-      var factory = new TTransportFactory();
+      var factory = TTransportFactory();
 
       result = await factory.getTransport(transport);
       expect(result, isNull);
 
-      transport = new TBufferedTransport();
+      transport = TBufferedTransport();
       result = await factory.getTransport(transport);
 
       expect(result, transport);
diff --git a/lib/delphi/DelphiThrift.groupproj b/lib/delphi/DelphiThrift.groupproj
index a172e49..179f680 100644
--- a/lib/delphi/DelphiThrift.groupproj
+++ b/lib/delphi/DelphiThrift.groupproj
@@ -1,8 +1,35 @@
-	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 		<PropertyGroup>
 			<ProjectGuid>{6BD327A5-7688-4263-B6A8-B15207CF4EC5}</ProjectGuid>
 		</PropertyGroup>
 		<ItemGroup>
+			<Projects Include="..\..\tutorial\delphi\DelphiServer\DelphiServer.dproj">
+				<Dependencies/>
+			</Projects>
+			<Projects Include="..\..\tutorial\delphi\DelphiClient\DelphiClient.dproj">
+				<Dependencies/>
+			</Projects>
+			<Projects Include="test\keywords\ReservedKeywords.dproj">
+				<Dependencies/>
+			</Projects>
 			<Projects Include="test\client.dproj">
 				<Dependencies/>
 			</Projects>
@@ -15,27 +42,18 @@
 			<Projects Include="test\multiplexed\Multiplex.Test.Server.dproj">
 				<Dependencies/>
 			</Projects>
-			<Projects Include="test\serializer\TestSerializer.dproj">
-				<Dependencies/>
-			</Projects>
 			<Projects Include="test\skip\skiptest_version1.dproj">
 				<Dependencies/>
 			</Projects>
 			<Projects Include="test\skip\skiptest_version2.dproj">
 				<Dependencies/>
 			</Projects>
+			<Projects Include="test\serializer\TestSerializer.dproj">
+				<Dependencies/>
+			</Projects>
 			<Projects Include="test\typeregistry\TestTypeRegistry.dproj">
 				<Dependencies/>
 			</Projects>
-			<Projects Include="..\..\tutorial\delphi\DelphiServer\DelphiServer.dproj">
-				<Dependencies/>
-			</Projects>
-			<Projects Include="..\..\tutorial\delphi\DelphiClient\DelphiClient.dproj">
-				<Dependencies/>
-			</Projects>
-			<Projects Include="test\keywords\ReservedKeywords.dproj">
-				<Dependencies/>
-			</Projects>
 		</ItemGroup>
 		<ProjectExtensions>
 			<Borland.Personality>Default.Personality.12</Borland.Personality>
@@ -44,6 +62,33 @@
 				<Default.Personality/>
 			</BorlandProject>
 		</ProjectExtensions>
+		<Target Name="DelphiServer">
+			<MSBuild Projects="..\..\tutorial\delphi\DelphiServer\DelphiServer.dproj"/>
+		</Target>
+		<Target Name="DelphiServer:Clean">
+			<MSBuild Projects="..\..\tutorial\delphi\DelphiServer\DelphiServer.dproj" Targets="Clean"/>
+		</Target>
+		<Target Name="DelphiServer:Make">
+			<MSBuild Projects="..\..\tutorial\delphi\DelphiServer\DelphiServer.dproj" Targets="Make"/>
+		</Target>
+		<Target Name="DelphiClient">
+			<MSBuild Projects="..\..\tutorial\delphi\DelphiClient\DelphiClient.dproj"/>
+		</Target>
+		<Target Name="DelphiClient:Clean">
+			<MSBuild Projects="..\..\tutorial\delphi\DelphiClient\DelphiClient.dproj" Targets="Clean"/>
+		</Target>
+		<Target Name="DelphiClient:Make">
+			<MSBuild Projects="..\..\tutorial\delphi\DelphiClient\DelphiClient.dproj" Targets="Make"/>
+		</Target>
+		<Target Name="ReservedKeywords">
+			<MSBuild Projects="test\keywords\ReservedKeywords.dproj"/>
+		</Target>
+		<Target Name="ReservedKeywords:Clean">
+			<MSBuild Projects="test\keywords\ReservedKeywords.dproj" Targets="Clean"/>
+		</Target>
+		<Target Name="ReservedKeywords:Make">
+			<MSBuild Projects="test\keywords\ReservedKeywords.dproj" Targets="Make"/>
+		</Target>
 		<Target Name="client">
 			<MSBuild Projects="test\client.dproj"/>
 		</Target>
@@ -80,15 +125,6 @@
 		<Target Name="Multiplex_Test_Server:Make">
 			<MSBuild Projects="test\multiplexed\Multiplex.Test.Server.dproj" Targets="Make"/>
 		</Target>
-		<Target Name="TestSerializer">
-			<MSBuild Projects="test\serializer\TestSerializer.dproj"/>
-		</Target>
-		<Target Name="TestSerializer:Clean">
-			<MSBuild Projects="test\serializer\TestSerializer.dproj" Targets="Clean"/>
-		</Target>
-		<Target Name="TestSerializer:Make">
-			<MSBuild Projects="test\serializer\TestSerializer.dproj" Targets="Make"/>
-		</Target>
 		<Target Name="skiptest_version1">
 			<MSBuild Projects="test\skip\skiptest_version1.dproj"/>
 		</Target>
@@ -107,6 +143,15 @@
 		<Target Name="skiptest_version2:Make">
 			<MSBuild Projects="test\skip\skiptest_version2.dproj" Targets="Make"/>
 		</Target>
+		<Target Name="TestSerializer">
+			<MSBuild Projects="test\serializer\TestSerializer.dproj"/>
+		</Target>
+		<Target Name="TestSerializer:Clean">
+			<MSBuild Projects="test\serializer\TestSerializer.dproj" Targets="Clean"/>
+		</Target>
+		<Target Name="TestSerializer:Make">
+			<MSBuild Projects="test\serializer\TestSerializer.dproj" Targets="Make"/>
+		</Target>
 		<Target Name="TestTypeRegistry">
 			<MSBuild Projects="test\typeregistry\TestTypeRegistry.dproj"/>
 		</Target>
@@ -116,41 +161,14 @@
 		<Target Name="TestTypeRegistry:Make">
 			<MSBuild Projects="test\typeregistry\TestTypeRegistry.dproj" Targets="Make"/>
 		</Target>
-		<Target Name="DelphiServer">
-			<MSBuild Projects="..\..\tutorial\delphi\DelphiServer\DelphiServer.dproj"/>
-		</Target>
-		<Target Name="DelphiServer:Clean">
-			<MSBuild Projects="..\..\tutorial\delphi\DelphiServer\DelphiServer.dproj" Targets="Clean"/>
-		</Target>
-		<Target Name="DelphiServer:Make">
-			<MSBuild Projects="..\..\tutorial\delphi\DelphiServer\DelphiServer.dproj" Targets="Make"/>
-		</Target>
-		<Target Name="DelphiClient">
-			<MSBuild Projects="..\..\tutorial\delphi\DelphiClient\DelphiClient.dproj"/>
-		</Target>
-		<Target Name="DelphiClient:Clean">
-			<MSBuild Projects="..\..\tutorial\delphi\DelphiClient\DelphiClient.dproj" Targets="Clean"/>
-		</Target>
-		<Target Name="DelphiClient:Make">
-			<MSBuild Projects="..\..\tutorial\delphi\DelphiClient\DelphiClient.dproj" Targets="Make"/>
-		</Target>
-		<Target Name="ReservedKeywords">
-			<MSBuild Projects="test\keywords\ReservedKeywords.dproj"/>
-		</Target>
-		<Target Name="ReservedKeywords:Clean">
-			<MSBuild Projects="test\keywords\ReservedKeywords.dproj" Targets="Clean"/>
-		</Target>
-		<Target Name="ReservedKeywords:Make">
-			<MSBuild Projects="test\keywords\ReservedKeywords.dproj" Targets="Make"/>
-		</Target>
 		<Target Name="Build">
-			<CallTarget Targets="client;server;Multiplex_Test_Client;Multiplex_Test_Server;TestSerializer;skiptest_version1;skiptest_version2;TestTypeRegistry;DelphiServer;DelphiClient;ReservedKeywords"/>
+			<CallTarget Targets="DelphiServer;DelphiClient;ReservedKeywords;client;server;Multiplex_Test_Client;Multiplex_Test_Server;skiptest_version1;skiptest_version2;TestSerializer;TestTypeRegistry"/>
 		</Target>
 		<Target Name="Clean">
-			<CallTarget Targets="client:Clean;server:Clean;Multiplex_Test_Client:Clean;Multiplex_Test_Server:Clean;TestSerializer:Clean;skiptest_version1:Clean;skiptest_version2:Clean;TestTypeRegistry:Clean;DelphiServer:Clean;DelphiClient:Clean;ReservedKeywords:Clean"/>
+			<CallTarget Targets="DelphiServer:Clean;DelphiClient:Clean;ReservedKeywords:Clean;client:Clean;server:Clean;Multiplex_Test_Client:Clean;Multiplex_Test_Server:Clean;skiptest_version1:Clean;skiptest_version2:Clean;TestSerializer:Clean;TestTypeRegistry:Clean"/>
 		</Target>
 		<Target Name="Make">
-			<CallTarget Targets="client:Make;server:Make;Multiplex_Test_Client:Make;Multiplex_Test_Server:Make;TestSerializer:Make;skiptest_version1:Make;skiptest_version2:Make;TestTypeRegistry:Make;DelphiServer:Make;DelphiClient:Make;ReservedKeywords:Make"/>
+			<CallTarget Targets="DelphiServer:Make;DelphiClient:Make;ReservedKeywords:Make;client:Make;server:Make;Multiplex_Test_Client:Make;Multiplex_Test_Server:Make;skiptest_version1:Make;skiptest_version2:Make;TestSerializer:Make;TestTypeRegistry:Make"/>
 		</Target>
 		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')" Project="$(BDS)\Bin\CodeGear.Group.Targets"/>
 	</Project>
diff --git a/lib/delphi/src/Thrift.Protocol.Compact.pas b/lib/delphi/src/Thrift.Protocol.Compact.pas
index 665cfc4..424b267 100644
--- a/lib/delphi/src/Thrift.Protocol.Compact.pas
+++ b/lib/delphi/src/Thrift.Protocol.Compact.pas
@@ -80,6 +80,9 @@
       STRUCT        = $0C
     );
 
+  private type
+    TEightBytesArray = packed array[0..7] of Byte;
+
   strict private const
     ttypeToCompactType : array[TType] of Types = (
       Types.STOP,           // Stop    = 0,
@@ -190,7 +193,7 @@
     class function intToZigZag( const n : Integer) : Cardinal;
 
     //Convert a Int64 into little-endian bytes in buf starting at off and going until off+7.
-    class procedure fixedLongToBytes( const n : Int64; var buf : TBytes);
+    class procedure fixedLongToBytes( const n : Int64; var buf : TEightBytesArray); inline;
 
   strict protected
     function GetMinSerializedSize( const aType : TType) : Integer;  override;
@@ -240,7 +243,7 @@
     // Note that it's important that the mask bytes are Int64 literals,
     // otherwise they'll default to ints, and when you shift an Integer left 56 bits,
     // you just get a messed up Integer.
-    class function bytesToLong( const bytes : TBytes) : Int64;
+    class function bytesToLong( const bytes : TEightBytesArray) : Int64; inline;
 
     // type testing and converting
     class function isBoolType( const b : byte) : Boolean;
@@ -319,10 +322,9 @@
 
 // Write an i32 as a varint. Results in 1-5 bytes on the wire.
 procedure TCompactProtocolImpl.WriteVarint32( n : Cardinal);
-var i32buf : TBytes;
-    idx : Integer;
+var idx : Integer;
+    i32buf : packed array[0..4] of Byte;
 begin
-  SetLength( i32buf, 5);
   idx := 0;
   while TRUE do begin
     ASSERT( idx < Length(i32buf));
@@ -339,7 +341,7 @@
     n := n shr 7;
   end;
 
-  Transport.Write( i32buf, 0, idx);
+  Transport.Write( @i32buf[0], 0, idx);
 end;
 
 
@@ -521,10 +523,10 @@
 
 // Write a double to the wire as 8 bytes.
 procedure TCompactProtocolImpl.WriteDouble( const dub: Double);
-var data : TBytes;
+var data : TEightBytesArray;
 begin
   fixedLongToBytes( DoubleToInt64Bits(dub), data);
-  Transport.Write( data);
+  Transport.Write( @data[0], 0, SizeOf(data));
 end;
 
 
@@ -580,10 +582,9 @@
 
 // Write an i64 as a varint. Results in 1-10 bytes on the wire.
 procedure TCompactProtocolImpl.WriteVarint64( n : UInt64);
-var varint64out : TBytes;
-    idx : Integer;
+var idx : Integer;
+    varint64out : packed array[0..9] of Byte;
 begin
-  SetLength( varint64out, 10);
   idx := 0;
   while TRUE do begin
     ASSERT( idx < Length(varint64out));
@@ -600,7 +601,7 @@
     n := n shr 7;
   end;
 
-  Transport.Write( varint64out, 0, idx);
+  Transport.Write( @varint64out[0], 0, idx);
 end;
 
 
@@ -627,9 +628,9 @@
 
 
 // Convert a Int64 into 8 little-endian bytes in buf
-class procedure TCompactProtocolImpl.fixedLongToBytes( const n : Int64; var buf : TBytes);
+class procedure TCompactProtocolImpl.fixedLongToBytes( const n : Int64; var buf : TEightBytesArray);
 begin
-  SetLength( buf, 8);
+  ASSERT( Length(buf) >= 8);
   buf[0] := Byte( n         and $FF);
   buf[1] := Byte((n shr 8)  and $FF);
   buf[2] := Byte((n shr 16) and $FF);
@@ -829,11 +830,11 @@
 
 
 // No magic here - just Read a double off the wire.
-function TCompactProtocolImpl.ReadDouble:Double;
-var longBits : TBytes;
+function TCompactProtocolImpl.ReadDouble : Double;
+var longBits : TEightBytesArray;
 begin
-  SetLength( longBits, 8);
-  Transport.ReadAll( longBits, 0, 8);
+  ASSERT( SizeOf(longBits) = SizeOf(result));
+  Transport.ReadAll( @longBits[0], SizeOf(longBits), 0, SizeOf(longBits));
   result := Int64BitsToDouble( bytesToLong( longBits));
 end;
 
@@ -934,7 +935,7 @@
 // Note that it's important that the mask bytes are Int64 literals,
 // otherwise they'll default to ints, and when you shift an Integer left 56 bits,
 // you just get a messed up Integer.
-class function TCompactProtocolImpl.bytesToLong( const bytes : TBytes) : Int64;
+class function TCompactProtocolImpl.bytesToLong( const bytes : TEightBytesArray) : Int64;
 begin
   ASSERT( Length(bytes) >= 8);
   result := (Int64(bytes[7] and $FF) shl 56) or
@@ -1104,7 +1105,7 @@
 procedure TestLongBytes;
 
   procedure Test( const test : Int64);
-  var buf : TBytes;
+  var buf : TCompactProtocolImpl.TEightBytesArray;
   begin
     TCompactProtocolImpl.fixedLongToBytes( test, buf);
     ASSERT( TCompactProtocolImpl.bytesToLong( buf) = test, IntToStr(test));
diff --git a/lib/delphi/src/Thrift.Protocol.JSON.pas b/lib/delphi/src/Thrift.Protocol.JSON.pas
index 61cad8b..515d85c 100644
--- a/lib/delphi/src/Thrift.Protocol.JSON.pas
+++ b/lib/delphi/src/Thrift.Protocol.JSON.pas
@@ -32,6 +32,7 @@
   Thrift.Configuration,
   Thrift.Transport,
   Thrift.Protocol,
+  Thrift.Stream,
   Thrift.Utils;
 
 type
@@ -832,7 +833,7 @@
 
 
 function TJSONProtocolImpl.ReadJSONString( skipContext : Boolean) : TBytes;
-var buffer : TMemoryStream;
+var buffer : TThriftMemoryStream;
     ch  : Byte;
     wch : Word;
     highSurogate: Char;
@@ -841,7 +842,7 @@
     tmp : TBytes;
 begin
   highSurogate := #0;
-  buffer := TMemoryStream.Create;
+  buffer := TThriftMemoryStream.Create;
   try
     if not skipContext
     then FContext.Read;
diff --git a/lib/delphi/src/Thrift.Protocol.pas b/lib/delphi/src/Thrift.Protocol.pas
index d5a7587..aa12ad3 100644
--- a/lib/delphi/src/Thrift.Protocol.pas
+++ b/lib/delphi/src/Thrift.Protocol.pas
@@ -833,6 +833,7 @@
 begin
   Reset;
   Init( result);
+
   size := ReadI32;
   if (size < 0) then begin
     version := size and Integer( VERSION_MASK);
@@ -842,14 +843,20 @@
     result.Type_ := TMessageType( size and $000000ff);
     result.Name := ReadString;
     result.SeqID := ReadI32;
-  end
-  else begin
-    if FStrictRead then begin
-      raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
-    end;
+    Exit;
+  end;
+
+  try
+    if FStrictRead
+    then raise TProtocolExceptionBadVersion.Create('Missing version in readMessageBegin, old client?' );
+
     result.Name := ReadStringBody( size );
     result.Type_ := TMessageType( ReadByte );
     result.SeqID := ReadI32;
+  except
+    if CharUtils.IsHtmlDoctype(size)
+    then raise TProtocolExceptionInvalidData.Create('Remote end sends HTML instead of data')
+    else raise; // something else
   end;
 end;
 
diff --git a/lib/delphi/src/Thrift.Serializer.pas b/lib/delphi/src/Thrift.Serializer.pas
index cb62603..8ee8a35 100644
--- a/lib/delphi/src/Thrift.Serializer.pas
+++ b/lib/delphi/src/Thrift.Serializer.pas
@@ -38,7 +38,7 @@
   // Generic utility for easily serializing objects into a byte array or Stream.
   TSerializer = class
   strict private
-    FStream    : TMemoryStream;
+    FStream    : TThriftMemoryStream;
     FTransport : ITransport;
     FProtocol  : IProtocol;
 
@@ -59,7 +59,7 @@
   // Generic utility for easily deserializing objects from byte array or Stream.
   TDeserializer = class
   strict private
-    FStream    : TMemoryStream;
+    FStream    : TThriftMemoryStream;
     FTransport : ITransport;
     FProtocol  : IProtocol;
 
@@ -92,7 +92,7 @@
 begin
   inherited Create;
 
-  FStream    := TMemoryStream.Create;
+  FStream    := TThriftMemoryStream.Create;
   adapter    := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
 
   FTransport := TStreamTransportImpl.Create( nil, adapter, aConfig);
@@ -170,7 +170,7 @@
 begin
   inherited Create;
 
-  FStream    := TMemoryStream.Create;
+  FStream    := TThriftMemoryStream.Create;
   adapter    := TThriftStreamAdapterDelphi.Create( FStream, FALSE);
 
   FTransport := TStreamTransportImpl.Create( adapter, nil, aConfig);
diff --git a/lib/delphi/src/Thrift.Stream.pas b/lib/delphi/src/Thrift.Stream.pas
index 1668059..6c1320d 100644
--- a/lib/delphi/src/Thrift.Stream.pas
+++ b/lib/delphi/src/Thrift.Stream.pas
@@ -108,10 +108,52 @@
     constructor Create( const aStream: IStream);
   end;
 
+
+  TThriftMemoryStream = class(TMemoryStream)
+  strict protected
+    FInitialCapacity : NativeInt;
+  public
+    constructor Create( const aInitialCapacity : NativeInt = 4096);
+
+    // reimplemented
+    procedure Clear;
+
+    // make it publicly visible
+    property Capacity;
+  end;
+
+
+
 implementation
 
 uses Thrift.Transport;
 
+
+{ TThriftMemoryStream }
+
+constructor TThriftMemoryStream.Create( const aInitialCapacity : NativeInt);
+begin
+  inherited Create;
+  FInitialCapacity := aInitialCapacity;
+  Clear;
+end;
+
+
+procedure TThriftMemoryStream.Clear;
+// reimplemented to keep initial capacity
+begin
+  Position := 0;
+  Size     := 0;
+
+  // primary goal: minimize costly reallocations (performance!)
+  // secondary goal: prevent costly ressource over-allocations
+  if (FInitialCapacity >= 1024*1024)        // if we are talking about MB
+  or ((Capacity div 2) > FInitialCapacity)  // or the allocated buffer is really large
+  or (Capacity < FInitialCapacity)          // or we are actually below the limit
+  then Capacity := FInitialCapacity;
+end;
+
+
 { TThriftStreamAdapterCOM }
 
 procedure TThriftStreamAdapterCOM.Close;
diff --git a/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas b/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas
index bdc65d1..398e275 100644
--- a/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas
+++ b/lib/delphi/src/Thrift.Transport.MsxmlHTTP.pas
@@ -106,7 +106,7 @@
   FReadTimeout       := XMLHTTP_SENDRECV_TIMEOUT;
 
   FCustomHeaders := TThriftDictionaryImpl<string,string>.Create;
-  FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
+  FOutputStream := TThriftStreamAdapterDelphi.Create( TThriftMemoryStream.Create, True);
 end;
 
 function TMsxmlHTTPClientImpl.CreateRequest: IXMLHTTPRequest;
@@ -197,12 +197,12 @@
 
 function TMsxmlHTTPClientImpl.GetIsOpen: Boolean;
 begin
-  Result := True;
+  Result := Assigned(FOutputStream);
 end;
 
 procedure TMsxmlHTTPClientImpl.Open;
 begin
-  FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
+  FOutputStream := TThriftStreamAdapterDelphi.Create( TThriftMemoryStream.Create, True);
 end;
 
 procedure TMsxmlHTTPClientImpl.Close;
@@ -217,7 +217,7 @@
     SendRequest;
   finally
     FOutputStream := nil;
-    FOutputStream := TThriftStreamAdapterDelphi.Create( TMemoryStream.Create, True);
+    FOutputStream := TThriftStreamAdapterDelphi.Create( TThriftMemoryStream.Create, True);
     ASSERT( FOutputStream <> nil);
   end;
 end;
@@ -239,13 +239,13 @@
 procedure TMsxmlHTTPClientImpl.SendRequest;
 var
   xmlhttp : IXMLHTTPRequest;
-  ms : TMemoryStream;
+  ms : TThriftMemoryStream;
   a : TBytes;
   len : Integer;
 begin
   xmlhttp := CreateRequest;
 
-  ms := TMemoryStream.Create;
+  ms := TThriftMemoryStream.Create;
   try
     a := FOutputStream.ToArray;
     len := Length(a);
@@ -256,6 +256,7 @@
     xmlhttp.send( IUnknown( TStreamAdapter.Create( ms, soReference )));
     FInputStream := nil;
     FInputStream := TThriftStreamAdapterCOM.Create( IUnknown( xmlhttp.responseStream) as IStream);
+    ResetConsumedMessageSize;
     UpdateKnownMessageSize( FInputStream.Size);
   finally
     ms.Free;
@@ -264,7 +265,9 @@
 
 procedure TMsxmlHTTPClientImpl.Write( const pBuf : Pointer; off, len : Integer);
 begin
-  FOutputStream.Write( pBuf, off, len);
+  if FOutputStream <> nil
+  then FOutputStream.Write( pBuf, off, len)
+  else raise TTransportExceptionNotOpen.Create('Transport closed');
 end;
 
 
diff --git a/lib/delphi/src/Thrift.Transport.Pipes.pas b/lib/delphi/src/Thrift.Transport.Pipes.pas
index 635a841..44dfef7 100644
--- a/lib/delphi/src/Thrift.Transport.Pipes.pas
+++ b/lib/delphi/src/Thrift.Transport.Pipes.pas
@@ -239,6 +239,12 @@
   end;
 
 
+  TNamedPipeFlag = (
+    OnlyLocalClients   // sets PIPE_REJECT_REMOTE_CLIENTS
+  );
+  TNamedPipeFlags = set of TNamedPipeFlag;
+
+
   TNamedPipeServerTransportImpl = class( TPipeServerTransportBase, INamedPipeServerTransport)
   strict private
     FPipeName     : string;
@@ -247,7 +253,7 @@
     FTimeout      : DWORD;
     FHandle       : THandle;
     FConnected    : Boolean;
-
+    FOnlyLocalClients : Boolean;
 
   strict protected
     function Accept(const fnAccepting: TProc): ITransport; override;
@@ -264,12 +270,38 @@
                         const aMaxConns : Cardinal = PIPE_UNLIMITED_INSTANCES;
                         const aTimeOut : Cardinal = INFINITE;
                         const aConfig : IThriftConfiguration = nil
+                        );  reintroduce; overload; deprecated 'use the other CTOR instead';
+
+    constructor Create( const aPipename : string;
+                        const aFlags : TNamedPipeFlags;
+                        const aConfig : IThriftConfiguration = nil;
+                        const aBufsize : Cardinal = 4096;
+                        const aMaxConns : Cardinal = PIPE_UNLIMITED_INSTANCES;
+                        const aTimeOut : Cardinal = INFINITE
                         );  reintroduce; overload;
   end;
 
 
 implementation
 
+const
+  // flags used but not declared in all Delphi versions, see MSDN
+  PIPE_ACCEPT_REMOTE_CLIENTS = 0;           // CreateNamedPipe() -> dwPipeMode = default
+  PIPE_REJECT_REMOTE_CLIENTS = $00000008;   // CreateNamedPipe() -> dwPipeMode
+
+  // Windows platfoms only
+  // https://github.com/dotnet/coreclr/pull/379/files
+  // https://referencesource.microsoft.com/#System.Runtime.Remoting/channels/ipc/win32namedpipes.cs,46b96e3f3828f497,references
+  // Citation from the first source:
+  // > For mitigating local elevation of privilege attack through named pipes
+  // > make sure we always call CreateFile with SECURITY_ANONYMOUS so that the
+  // > named pipe server can't impersonate a high privileged client security context
+  {$IFDEF MSWINDOWS}
+  PREVENT_PIPE_IMPERSONATION = SECURITY_SQOS_PRESENT or SECURITY_ANONYMOUS;
+  {$ELSE}
+  PREVENT_PIPE_IMPERSONATION = 0; // not available on Linux etc
+  {$ENDIF}
+
 
 procedure ClosePipeHandle( var hPipe : THandle);
 begin
@@ -561,7 +593,7 @@
 
 procedure TNamedPipeStreamImpl.Open;
 var hPipe    : THandle;
-    retries, timeout, dwErr : DWORD;
+    retries, timeout, dwErr, dwFlagsAndAttributes : DWORD;
 const INTERVAL = 10; // ms
 begin
   if IsOpen then Exit;
@@ -587,14 +619,18 @@
     Sleep(INTERVAL)
   end;
 
+  dwFlagsAndAttributes := FILE_FLAG_OVERLAPPED
+                       or FILE_FLAG_WRITE_THROUGH // async+fast, please
+                       or PREVENT_PIPE_IMPERSONATION;
+
   // open that thingy
   hPipe := CreateFile( PChar( FPipeName),
                        GENERIC_READ or GENERIC_WRITE,
-                       FShareMode,        // sharing
-                       FSecurityAttribs,  // security attributes
-                       OPEN_EXISTING,     // opens existing pipe
-                       FILE_FLAG_OVERLAPPED or FILE_FLAG_WRITE_THROUGH, // async+fast, please
-                       0);                // no template file
+                       FShareMode,            // sharing
+                       FSecurityAttribs,      // security attributes
+                       OPEN_EXISTING,         // opens existing pipe
+                       dwFlagsAndAttributes,  // flags + attribs
+                       0);                    // no template file
 
   if hPipe = INVALID_HANDLE_VALUE
   then raise TTransportExceptionNotOpen.Create('Unable to open pipe, '+SysErrorMessage(GetLastError));
@@ -885,8 +921,9 @@
 
 
 constructor TNamedPipeServerTransportImpl.Create( const aPipename : string;
-                                                  const aBufsize, aMaxConns, aTimeOut : Cardinal;
-                                                  const aConfig : IThriftConfiguration);
+                                                  const aFlags : TNamedPipeFlags;
+                                                  const aConfig : IThriftConfiguration;
+                                                  const aBufsize, aMaxConns, aTimeOut : Cardinal);
 // Named Pipe CTOR
 begin
   inherited Create( aConfig);
@@ -898,11 +935,24 @@
   FConnected := FALSE;
   ASSERT( FTimeout > 0);
 
+  FOnlyLocalClients := (TNamedPipeFlag.OnlyLocalClients in aFlags);
+
   if Copy(FPipeName,1,2) <> '\\'
   then FPipeName := '\\.\pipe\' + FPipeName;  // assume localhost
 end;
 
 
+constructor TNamedPipeServerTransportImpl.Create( const aPipename : string;
+                                                  const aBufsize, aMaxConns, aTimeOut : Cardinal;
+                                                  const aConfig : IThriftConfiguration);
+// Named Pipe CTOR (deprecated)
+begin
+  {$WARN SYMBOL_DEPRECATED OFF}  // Delphi XE emits a false warning here
+  Create( aPipeName, [], aConfig, aBufsize, aMaxConns, aTimeOut);
+  {$WARN SYMBOL_DEPRECATED ON}
+end;
+
+
 function TNamedPipeServerTransportImpl.Accept(const fnAccepting: TProc): ITransport;
 var dwError, dwWait, dwDummy : DWORD;
     overlapped : IOverlappedHelper;
@@ -1008,6 +1058,7 @@
     acl          : PACL;
     sd           : PSECURITY_DESCRIPTOR;
     sa           : SECURITY_ATTRIBUTES;
+    dwPipeModeXtra : DWORD;
 const
   SECURITY_WORLD_SID_AUTHORITY  : TSIDIdentifierAuthority = (Value : (0,0,0,0,0,1));
   SECURITY_WORLD_RID = $00000000;
@@ -1041,22 +1092,24 @@
     sa.lpSecurityDescriptor := sd;
     sa.bInheritHandle       := FALSE;
 
+    // any extra flags we want to add to dwPipeMode
+    dwPipeModeXtra := 0;
+    if FOnlyLocalClients then dwPipeModeXtra := dwPipeModeXtra or PIPE_REJECT_REMOTE_CLIENTS;
+
     // Create an instance of the named pipe
     {$IFDEF OLD_UNIT_NAMES}
     result := Windows.CreateNamedPipe(
     {$ELSE}
     result := Winapi.Windows.CreateNamedPipe(
     {$ENDIF}
-        PChar( FPipeName),        // pipe name
-        PIPE_ACCESS_DUPLEX or     // read/write access
-        FILE_FLAG_OVERLAPPED,     // async mode
-        PIPE_TYPE_BYTE or         // byte type pipe
-        PIPE_READMODE_BYTE,       // byte read mode
-        FMaxConns,                // max. instances
-        FBufSize,                 // output buffer size
-        FBufSize,                 // input buffer size
-        FTimeout,                 // time-out, see MSDN
-        @sa                       // default security attribute
+        PChar( FPipeName),             // pipe name
+        PIPE_ACCESS_DUPLEX or FILE_FLAG_OVERLAPPED,              // read/write access + async mode
+        PIPE_TYPE_BYTE or PIPE_READMODE_BYTE or dwPipeModeXtra,  // byte type pipe + byte read mode + extras
+        FMaxConns,                     // max. instances
+        FBufSize,                      // output buffer size
+        FBufSize,                      // input buffer size
+        FTimeout,                      // time-out, see MSDN
+        @sa                            // default security attribute
     );
 
     if( result <> INVALID_HANDLE_VALUE)
diff --git a/lib/delphi/src/Thrift.Transport.WinHTTP.pas b/lib/delphi/src/Thrift.Transport.WinHTTP.pas
index b0f32ef..746611d 100644
--- a/lib/delphi/src/Thrift.Transport.WinHTTP.pas
+++ b/lib/delphi/src/Thrift.Transport.WinHTTP.pas
@@ -41,7 +41,7 @@
   strict private
     FUri : string;
     FInputStream : IThriftStream;
-    FOutputMemoryStream : TMemoryStream;
+    FOutputMemoryStream : TThriftMemoryStream;
     FDnsResolveTimeout : Integer;
     FConnectionTimeout : Integer;
     FSendTimeout : Integer;
@@ -127,7 +127,7 @@
   FSecureProtocols := DEFAULT_THRIFT_SECUREPROTOCOLS;
 
   FCustomHeaders := TThriftDictionaryImpl<string,string>.Create;
-  FOutputMemoryStream := TMemoryStream.Create;
+  FOutputMemoryStream := TThriftMemoryStream.Create;
 end;
 
 destructor TWinHTTPClientImpl.Destroy;
@@ -269,7 +269,7 @@
 procedure TWinHTTPClientImpl.Open;
 begin
   FreeAndNil( FOutputMemoryStream);
-  FOutputMemoryStream := TMemoryStream.Create;
+  FOutputMemoryStream := TThriftMemoryStream.Create;
 end;
 
 procedure TWinHTTPClientImpl.Close;
@@ -284,7 +284,7 @@
     SendRequest;
   finally
     FreeAndNil( FOutputMemoryStream);
-    FOutputMemoryStream := TMemoryStream.Create;
+    FOutputMemoryStream := TThriftMemoryStream.Create;
     ASSERT( FOutputMemoryStream <> nil);
   end;
 end;
diff --git a/lib/delphi/src/Thrift.Transport.pas b/lib/delphi/src/Thrift.Transport.pas
index 6a69d93..558b65e 100644
--- a/lib/delphi/src/Thrift.Transport.pas
+++ b/lib/delphi/src/Thrift.Transport.pas
@@ -334,8 +334,8 @@
   strict private
     FStream : IThriftStream;
     FBufSize : Integer;
-    FReadBuffer : TMemoryStream;
-    FWriteBuffer : TMemoryStream;
+    FReadBuffer : TThriftMemoryStream;
+    FWriteBuffer : TThriftMemoryStream;
   strict protected
     procedure Write( const pBuf : Pointer; offset: Integer; count: Integer); override;
     function Read( const pBuf : Pointer; const buflen : Integer; offset: Integer; count: Integer): Integer; override;
@@ -450,8 +450,8 @@
   strict protected type
     TFramedHeader = Int32;
   strict protected
-    FWriteBuffer : TMemoryStream;
-    FReadBuffer : TMemoryStream;
+    FWriteBuffer : TThriftMemoryStream;
+    FReadBuffer : TThriftMemoryStream;
 
     procedure InitWriteBuffer;
     procedure ReadFrame;
@@ -1053,8 +1053,8 @@
   inherited Create;
   FStream := aStream;
   FBufSize := aBufSize;
-  FReadBuffer := TMemoryStream.Create;
-  FWriteBuffer := TMemoryStream.Create;
+  FReadBuffer := TThriftMemoryStream.Create(FBufSize);
+  FWriteBuffer := TThriftMemoryStream.Create(FBufSize);
 end;
 
 destructor TBufferedStreamImpl.Destroy;
@@ -1379,16 +1379,11 @@
   Result := InnerTransport.IsOpen;
 end;
 
-type
-  TAccessMemoryStream = class(TMemoryStream)
-  end;
-
 procedure TFramedTransportImpl.InitWriteBuffer;
 const DUMMY_HEADER : TFramedHeader = 0;
 begin
   FreeAndNil( FWriteBuffer);
-  FWriteBuffer := TMemoryStream.Create;
-  TAccessMemoryStream(FWriteBuffer).Capacity := 1024;
+  FWriteBuffer := TThriftMemoryStream.Create(1024);
   FWriteBuffer.Write( DUMMY_HEADER, SizeOf(DUMMY_HEADER));
 end;
 
@@ -1437,7 +1432,9 @@
 
   if Int64(size) > Int64(Configuration.MaxFrameSize) then begin
     Close();
-    raise TTransportExceptionCorruptedData.Create('Frame size ('+IntToStr(size)+') larger than allowed maximum ('+IntToStr(Configuration.MaxFrameSize)+')');
+    if CharUtils.IsHtmlDoctype(size)
+    then raise TTransportExceptionCorruptedData.Create('Remote end sends HTML instead of data')
+    else raise TTransportExceptionCorruptedData.Create('Frame size ('+IntToStr(size)+') larger than allowed maximum ('+IntToStr(Configuration.MaxFrameSize)+')');
   end;
 
   UpdateKnownMessageSize(size + SizeOf(size));
@@ -1446,7 +1443,7 @@
   InnerTransport.ReadAll( buff, 0, size );
 
   FreeAndNil( FReadBuffer);
-  FReadBuffer := TMemoryStream.Create;
+  FReadBuffer := TThriftMemoryStream.Create(1024);
   if Length(buff) > 0
   then FReadBuffer.Write( Pointer(@buff[0])^, size );
   FReadBuffer.Position := 0;
diff --git a/lib/delphi/src/Thrift.Utils.pas b/lib/delphi/src/Thrift.Utils.pas
index bfd020e..4a75af8 100644
--- a/lib/delphi/src/Thrift.Utils.pas
+++ b/lib/delphi/src/Thrift.Utils.pas
@@ -80,6 +80,8 @@
   public
     class function IsHighSurrogate( const c : Char) : Boolean; static; inline;
     class function IsLowSurrogate( const c : Char) : Boolean; static; inline;
+
+    class function IsHtmlDoctype( const fourBytes : Integer) : Boolean; static;
   end;
 
   EnumUtils<T> = class sealed
@@ -259,6 +261,30 @@
 end;
 
 
+class function CharUtils.IsHtmlDoctype( const fourBytes : Integer) : Boolean;
+var pc : PAnsiChar;
+const HTML_BEGIN : PAnsiChar = 'OD!<';  // first 4 bytes of '<!DOCTYPE ' in LE byte order
+begin
+  pc := @fourBytes;
+
+  if UpCase(pc^) <> HTML_BEGIN[0]
+  then Exit(FALSE);
+
+  Inc( pc);
+  if UpCase(pc^) <> HTML_BEGIN[1]
+  then Exit(FALSE);
+
+
+  Inc( pc);
+  if UpCase(pc^) <> HTML_BEGIN[2]
+  then Exit(FALSE);
+
+  Inc( pc);
+  result := (UpCase(pc^) = HTML_BEGIN[3]);
+end;
+
+
+
 {$IFDEF Win64}
 
 function InterlockedCompareExchange64( var Target : Int64; Exchange, Comparand : Int64) : Int64;  inline;
diff --git a/lib/delphi/src/Thrift.pas b/lib/delphi/src/Thrift.pas
index 19dd372..66dda72 100644
--- a/lib/delphi/src/Thrift.pas
+++ b/lib/delphi/src/Thrift.pas
@@ -28,7 +28,7 @@
   Thrift.Protocol;
 
 const
-  Version = '0.14.2';
+  Version = '0.15.0';
 
 type
   TException = Thrift.Exception.TException; // compatibility alias
diff --git a/lib/delphi/test/TestClient.pas b/lib/delphi/test/TestClient.pas
index 6c962ab..ebc0796 100644
--- a/lib/delphi/test/TestClient.pas
+++ b/lib/delphi/test/TestClient.pas
@@ -474,6 +474,10 @@
     on e:Exception do Expect( FALSE, 'Unexpected exception "'+e.ClassName+'": '+e.Message);
   end;
 
+  // re-open connection if needed
+  if not FTransport.IsOpen
+  then FTransport.Open;
+
   // case 2: exception type NOT declared in IDL at the function call
   // this will close the connection
   try
@@ -505,6 +509,9 @@
   end;
   {$ENDIF Exceptions}
 
+  // re-open connection if needed
+  if not FTransport.IsOpen
+  then FTransport.Open;
 
   // simple things
   StartTestGroup( 'simple Thrift calls', test_BaseTypes);
diff --git a/lib/delphi/test/TestServer.pas b/lib/delphi/test/TestServer.pas
index c9b374d..adbbccf 100644
--- a/lib/delphi/test/TestServer.pas
+++ b/lib/delphi/test/TestServer.pas
@@ -479,6 +479,9 @@
   endpoint : TEndpointTransport;
   layered : TLayeredTransports;
   UseSSL : Boolean; // include where appropriate (TLayeredTransport?)
+  config : IThriftConfiguration;
+const
+  PIPEFLAGS = [ TNamedPipeFlag.OnlyLocalClients];
 begin
   try
     ServerEvents := FALSE;
@@ -573,6 +576,7 @@
     ASSERT( ProtocolFactory <> nil);
     Console.WriteLine('- '+THRIFT_PROTOCOLS[protType]+' protocol');
 
+    config := nil; // TODO
     case endpoint of
 
       trns_Sockets : begin
@@ -588,7 +592,7 @@
 
       trns_NamedPipes : begin
         Console.WriteLine('- named pipe ('+sPipeName+')');
-        namedpipe   := TNamedPipeServerTransportImpl.Create( sPipeName, 4096, PIPE_UNLIMITED_INSTANCES, INFINITE);
+        namedpipe   := TNamedPipeServerTransportImpl.Create( sPipeName, PIPEFLAGS, config);
         servertrans := namedpipe;
       end;
 
diff --git a/lib/delphi/test/client.dpr b/lib/delphi/test/client.dpr
index d4875b8..eaeeee0 100644
--- a/lib/delphi/test/client.dpr
+++ b/lib/delphi/test/client.dpr
@@ -27,7 +27,7 @@
   DataFactory in 'Performance\DataFactory.pas',
   PerfTests in 'Performance\PerfTests.pas',
   TestClient in 'TestClient.pas',
-  Thrift.Test, // in 'gen-delphi\Thrift.Test.pas',
+  Thrift.Test in 'gen-delphi\Thrift.Test.pas',
   Thrift in '..\src\Thrift.pas',
   Thrift.Transport in '..\src\Thrift.Transport.pas',
   Thrift.Socket in '..\src\Thrift.Socket.pas',
diff --git a/lib/delphi/test/client.dproj b/lib/delphi/test/client.dproj
new file mode 100644
index 0000000..8df93a0
--- /dev/null
+++ b/lib/delphi/test/client.dproj
@@ -0,0 +1,155 @@
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{F262F488-F81C-4B6E-8694-518C54CBB8F3}</ProjectGuid>
+			<MainSource>client.dpr</MainSource>
+			<Basis>True</Basis>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform>Win32</Platform>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<ProjectVersion>12.3</ProjectVersion>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+			<DCC_F>false</DCC_F>
+			<DCC_S>false</DCC_S>
+			<DCC_N>false</DCC_N>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="client.dpr">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="Performance\DataFactory.pas"/>
+			<DCCReference Include="Performance\PerfTests.pas"/>
+			<DCCReference Include="TestClient.pas"/>
+			<DCCReference Include="gen-delphi\Thrift.Test.pas"/>
+			<DCCReference Include="..\src\Thrift.pas"/>
+			<DCCReference Include="..\src\Thrift.Transport.pas"/>
+			<DCCReference Include="..\src\Thrift.Socket.pas"/>
+			<DCCReference Include="..\src\Thrift.Configuration.pas"/>
+			<DCCReference Include="..\src\Thrift.Exception.pas"/>
+			<DCCReference Include="..\src\Thrift.Transport.Pipes.pas"/>
+			<DCCReference Include="..\src\Thrift.Transport.WinHTTP.pas"/>
+			<DCCReference Include="..\src\Thrift.Transport.MsxmlHTTP.pas"/>
+			<DCCReference Include="..\src\Thrift.Protocol.pas"/>
+			<DCCReference Include="..\src\Thrift.Protocol.JSON.pas"/>
+			<DCCReference Include="..\src\Thrift.Protocol.Compact.pas"/>
+			<DCCReference Include="..\src\Thrift.Protocol.Multiplex.pas"/>
+			<DCCReference Include="..\src\Thrift.Collections.pas"/>
+			<DCCReference Include="..\src\Thrift.Server.pas"/>
+			<DCCReference Include="..\src\Thrift.Stream.pas"/>
+			<DCCReference Include="..\src\Thrift.TypeRegistry.pas"/>
+			<DCCReference Include="..\src\Thrift.WinHTTP.pas"/>
+			<DCCReference Include="..\src\Thrift.Utils.pas"/>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Basis">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[thrift.exe -r -gen delphi ..\..\..\test\ThriftTest.thrift]]></PreBuildEvent>
+		</PropertyGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>VCLApplication</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">client.dpr</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1031</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+					<Parameters>
+						<Parameters Name="RunParams"> --transport=framed --transport=winhttp --host=example.org --port=80</Parameters>
+					</Parameters>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>
diff --git a/lib/delphi/test/keywords/ReservedKeywords.dproj b/lib/delphi/test/keywords/ReservedKeywords.dproj
index cc36988..3603abe 100644
--- a/lib/delphi/test/keywords/ReservedKeywords.dproj
+++ b/lib/delphi/test/keywords/ReservedKeywords.dproj
@@ -1,4 +1,22 @@
-	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 		<PropertyGroup>
 			<ProjectGuid>{F2E9B6FC-A931-4271-8E30-5A4E402481B4}</ProjectGuid>
 			<MainSource>ReservedKeywords.dpr</MainSource>
@@ -24,11 +42,11 @@
 			<Base>true</Base>
 		</PropertyGroup>
 		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
 			<DCC_ImageBase>00400000</DCC_ImageBase>
-			<DCC_DcuOutput>.\$(Config)\$(Platform)</DCC_DcuOutput>
 			<DCC_UnitSearchPath>gen-delphi;..\..\src;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
 			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>
-			<DCC_ExeOutput>.\$(Config)\$(Platform)</DCC_ExeOutput>
 			<DCC_N>false</DCC_N>
 			<DCC_S>false</DCC_S>
 			<DCC_K>false</DCC_K>
diff --git a/lib/delphi/test/multiplexed/Multiplex.Client.Main.pas b/lib/delphi/test/multiplexed/Multiplex.Client.Main.pas
index 4b6a0a2..b6d5fb6 100644
--- a/lib/delphi/test/multiplexed/Multiplex.Client.Main.pas
+++ b/lib/delphi/test/multiplexed/Multiplex.Client.Main.pas
@@ -36,8 +36,8 @@
   Thrift.Stream,
   Thrift.Collections,
   Thrift.Configuration,
-  Benchmark,  // in gen-delphi folder
-  Aggr,       // in gen-delphi folder
+  Benchmark,
+  Aggr,
   Multiplex.Test.Common;
 
 type
diff --git a/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr b/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr
index 19f8f6a..95215ff 100644
--- a/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr
+++ b/lib/delphi/test/multiplexed/Multiplex.Test.Client.dpr
@@ -25,6 +25,8 @@
 uses
   SysUtils,
   Multiplex.Client.Main in 'Multiplex.Client.Main.pas',
+  Benchmark in 'gen-delphi\Benchmark.pas',
+  Aggr in 'gen-delphi\Aggr.pas',
   Thrift in '..\..\src\Thrift.pas',
   Thrift.Socket in '..\..\src\Thrift.Socket.pas',
   Thrift.Exception in '..\..\src\Thrift.Exception.pas',
diff --git a/lib/delphi/test/multiplexed/Multiplex.Test.Client.dproj b/lib/delphi/test/multiplexed/Multiplex.Test.Client.dproj
new file mode 100644
index 0000000..06118f0
--- /dev/null
+++ b/lib/delphi/test/multiplexed/Multiplex.Test.Client.dproj
@@ -0,0 +1,147 @@
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{59132A87-6294-4E25-AE9C-7CD17CD4400D}</ProjectGuid>
+			<MainSource>Multiplex.Test.Client.dpr</MainSource>
+			<Basis>True</Basis>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform>Win32</Platform>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<ProjectVersion>12.3</ProjectVersion>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+			<DCC_F>false</DCC_F>
+			<DCC_S>false</DCC_S>
+			<DCC_N>false</DCC_N>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="Multiplex.Test.Client.dpr">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="Multiplex.Client.Main.pas"/>
+			<DCCReference Include="gen-delphi\Benchmark.pas"/>
+			<DCCReference Include="gen-delphi\Aggr.pas"/>
+			<DCCReference Include="..\..\src\Thrift.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Socket.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Exception.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Transport.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Transport.Pipes.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.Multiplex.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Collections.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Configuration.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Server.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Stream.pas"/>
+			<DCCReference Include="..\..\src\Thrift.TypeRegistry.pas"/>
+			<DCCReference Include="..\..\src\Thrift.WinHTTP.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Utils.pas"/>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Basis">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[thrift.exe -r -gen delphi ..\..\..\..\contrib\async-test\Aggr.thrift
+thrift.exe -r -gen delphi ..\..\..\..\lib\rb\benchmark\Benchmark.thrift]]></PreBuildEvent>
+		</PropertyGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>VCLApplication</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">Multiplex.Test.Client.dpr</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1031</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>
diff --git a/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr b/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr
index 307a9c2..d9bbf88 100644
--- a/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr
+++ b/lib/delphi/test/multiplexed/Multiplex.Test.Server.dpr
@@ -24,6 +24,8 @@
 uses
   SysUtils,
   Multiplex.Server.Main in 'Multiplex.Server.Main.pas',
+  Benchmark in 'gen-delphi\Benchmark.pas',
+  Aggr in 'gen-delphi\Aggr.pas',
   ConsoleHelper in '..\ConsoleHelper.pas',
   Thrift in '..\..\src\Thrift.pas',
   Thrift.Exception in '..\..\src\Thrift.Exception.pas',
diff --git a/lib/delphi/test/multiplexed/Multiplex.Test.Server.dproj b/lib/delphi/test/multiplexed/Multiplex.Test.Server.dproj
new file mode 100644
index 0000000..5f4fa73
--- /dev/null
+++ b/lib/delphi/test/multiplexed/Multiplex.Test.Server.dproj
@@ -0,0 +1,149 @@
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{42C6ED3D-36E2-47C5-99B2-02BDA574B9E5}</ProjectGuid>
+			<MainSource>Multiplex.Test.Server.dpr</MainSource>
+			<Basis>True</Basis>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform>Win32</Platform>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<ProjectVersion>12.3</ProjectVersion>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+			<DCC_F>false</DCC_F>
+			<DCC_S>false</DCC_S>
+			<DCC_N>false</DCC_N>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="Multiplex.Test.Server.dpr">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="Multiplex.Server.Main.pas"/>
+			<DCCReference Include="gen-delphi\Benchmark.pas"/>
+			<DCCReference Include="gen-delphi\Aggr.pas"/>
+			<DCCReference Include="..\ConsoleHelper.pas"/>
+			<DCCReference Include="..\..\src\Thrift.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Exception.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Socket.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Transport.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Transport.Pipes.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.Multiplex.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Processor.Multiplex.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Configuration.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Collections.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Server.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Utils.pas"/>
+			<DCCReference Include="..\..\src\Thrift.WinHTTP.pas"/>
+			<DCCReference Include="..\..\src\Thrift.TypeRegistry.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Stream.pas"/>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Basis">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[thrift.exe -r -gen delphi ..\..\..\..\contrib\async-test\Aggr.thrift
+thrift.exe -r -gen delphi ..\..\..\..\lib\rb\benchmark\Benchmark.thrift]]></PreBuildEvent>
+		</PropertyGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>VCLApplication</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">Multiplex.Test.Server.dpr</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1031</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>
diff --git a/lib/delphi/test/serializer/TestSerializer.Data.pas b/lib/delphi/test/serializer/TestSerializer.Data.pas
index 2420e9a..a90d650 100644
--- a/lib/delphi/test/serializer/TestSerializer.Data.pas
+++ b/lib/delphi/test/serializer/TestSerializer.Data.pas
@@ -284,57 +284,57 @@
 // superhuge compact proto test struct
 begin
   result := TCompactProtoTestStructImpl.Create;
-  result.A_byte := TDebugProtoTestConstants.COMPACT_TEST.A_byte;
-  result.A_i16 := TDebugProtoTestConstants.COMPACT_TEST.A_i16;
-  result.A_i32 := TDebugProtoTestConstants.COMPACT_TEST.A_i32;
-  result.A_i64 := TDebugProtoTestConstants.COMPACT_TEST.A_i64;
-  result.A_double := TDebugProtoTestConstants.COMPACT_TEST.A_double;
-  result.A_string := TDebugProtoTestConstants.COMPACT_TEST.A_string;
-  result.A_binary := TDebugProtoTestConstants.COMPACT_TEST.A_binary;
-  result.True_field := TDebugProtoTestConstants.COMPACT_TEST.True_field;
-  result.False_field := TDebugProtoTestConstants.COMPACT_TEST.False_field;
-  result.Empty_struct_field := TDebugProtoTestConstants.COMPACT_TEST.Empty_struct_field;
-  result.Byte_list := TDebugProtoTestConstants.COMPACT_TEST.Byte_list;
-  result.I16_list := TDebugProtoTestConstants.COMPACT_TEST.I16_list;
-  result.I32_list := TDebugProtoTestConstants.COMPACT_TEST.I32_list;
-  result.I64_list := TDebugProtoTestConstants.COMPACT_TEST.I64_list;
-  result.Double_list := TDebugProtoTestConstants.COMPACT_TEST.Double_list;
-  result.String_list := TDebugProtoTestConstants.COMPACT_TEST.String_list;
-  result.Binary_list := TDebugProtoTestConstants.COMPACT_TEST.Binary_list;
-  result.Boolean_list := TDebugProtoTestConstants.COMPACT_TEST.Boolean_list;
-  result.Struct_list := TDebugProtoTestConstants.COMPACT_TEST.Struct_list;
-  result.Byte_set := TDebugProtoTestConstants.COMPACT_TEST.Byte_set;
-  result.I16_set := TDebugProtoTestConstants.COMPACT_TEST.I16_set;
-  result.I32_set := TDebugProtoTestConstants.COMPACT_TEST.I32_set;
-  result.I64_set := TDebugProtoTestConstants.COMPACT_TEST.I64_set;
-  result.Double_set := TDebugProtoTestConstants.COMPACT_TEST.Double_set;
-  result.String_set := TDebugProtoTestConstants.COMPACT_TEST.String_set;
-  result.String_set := TDebugProtoTestConstants.COMPACT_TEST.String_set;
-  result.String_set := TDebugProtoTestConstants.COMPACT_TEST.String_set;
-  result.Binary_set := TDebugProtoTestConstants.COMPACT_TEST.Binary_set;
-  result.Boolean_set := TDebugProtoTestConstants.COMPACT_TEST.Boolean_set;
-  result.Struct_set := TDebugProtoTestConstants.COMPACT_TEST.Struct_set;
-  result.Byte_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_byte_map;
-  result.I16_byte_map := TDebugProtoTestConstants.COMPACT_TEST.I16_byte_map;
-  result.I32_byte_map := TDebugProtoTestConstants.COMPACT_TEST.I32_byte_map;
-  result.I64_byte_map := TDebugProtoTestConstants.COMPACT_TEST.I64_byte_map;
-  result.Double_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Double_byte_map;
-  result.String_byte_map := TDebugProtoTestConstants.COMPACT_TEST.String_byte_map;
-  result.Binary_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Binary_byte_map;
-  result.Boolean_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Boolean_byte_map;
-  result.Byte_i16_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_i16_map;
-  result.Byte_i32_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_i32_map;
-  result.Byte_i64_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_i64_map;
-  result.Byte_double_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_double_map;
-  result.Byte_string_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_string_map;
-  result.Byte_binary_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_binary_map;
-  result.Byte_boolean_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_boolean_map;
-  result.List_byte_map := TDebugProtoTestConstants.COMPACT_TEST.List_byte_map;
-  result.Set_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Set_byte_map;
-  result.Map_byte_map := TDebugProtoTestConstants.COMPACT_TEST.Map_byte_map;
-  result.Byte_map_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_map_map;
-  result.Byte_set_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_set_map;
-  result.Byte_list_map := TDebugProtoTestConstants.COMPACT_TEST.Byte_list_map;
+  result.A_byte := DebugProtoTest.TConstants.COMPACT_TEST.A_byte;
+  result.A_i16 := DebugProtoTest.TConstants.COMPACT_TEST.A_i16;
+  result.A_i32 := DebugProtoTest.TConstants.COMPACT_TEST.A_i32;
+  result.A_i64 := DebugProtoTest.TConstants.COMPACT_TEST.A_i64;
+  result.A_double := DebugProtoTest.TConstants.COMPACT_TEST.A_double;
+  result.A_string := DebugProtoTest.TConstants.COMPACT_TEST.A_string;
+  result.A_binary := DebugProtoTest.TConstants.COMPACT_TEST.A_binary;
+  result.True_field := DebugProtoTest.TConstants.COMPACT_TEST.True_field;
+  result.False_field := DebugProtoTest.TConstants.COMPACT_TEST.False_field;
+  result.Empty_struct_field := DebugProtoTest.TConstants.COMPACT_TEST.Empty_struct_field;
+  result.Byte_list := DebugProtoTest.TConstants.COMPACT_TEST.Byte_list;
+  result.I16_list := DebugProtoTest.TConstants.COMPACT_TEST.I16_list;
+  result.I32_list := DebugProtoTest.TConstants.COMPACT_TEST.I32_list;
+  result.I64_list := DebugProtoTest.TConstants.COMPACT_TEST.I64_list;
+  result.Double_list := DebugProtoTest.TConstants.COMPACT_TEST.Double_list;
+  result.String_list := DebugProtoTest.TConstants.COMPACT_TEST.String_list;
+  result.Binary_list := DebugProtoTest.TConstants.COMPACT_TEST.Binary_list;
+  result.Boolean_list := DebugProtoTest.TConstants.COMPACT_TEST.Boolean_list;
+  result.Struct_list := DebugProtoTest.TConstants.COMPACT_TEST.Struct_list;
+  result.Byte_set := DebugProtoTest.TConstants.COMPACT_TEST.Byte_set;
+  result.I16_set := DebugProtoTest.TConstants.COMPACT_TEST.I16_set;
+  result.I32_set := DebugProtoTest.TConstants.COMPACT_TEST.I32_set;
+  result.I64_set := DebugProtoTest.TConstants.COMPACT_TEST.I64_set;
+  result.Double_set := DebugProtoTest.TConstants.COMPACT_TEST.Double_set;
+  result.String_set := DebugProtoTest.TConstants.COMPACT_TEST.String_set;
+  result.String_set := DebugProtoTest.TConstants.COMPACT_TEST.String_set;
+  result.String_set := DebugProtoTest.TConstants.COMPACT_TEST.String_set;
+  result.Binary_set := DebugProtoTest.TConstants.COMPACT_TEST.Binary_set;
+  result.Boolean_set := DebugProtoTest.TConstants.COMPACT_TEST.Boolean_set;
+  result.Struct_set := DebugProtoTest.TConstants.COMPACT_TEST.Struct_set;
+  result.Byte_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_byte_map;
+  result.I16_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.I16_byte_map;
+  result.I32_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.I32_byte_map;
+  result.I64_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.I64_byte_map;
+  result.Double_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Double_byte_map;
+  result.String_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.String_byte_map;
+  result.Binary_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Binary_byte_map;
+  result.Boolean_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Boolean_byte_map;
+  result.Byte_i16_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_i16_map;
+  result.Byte_i32_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_i32_map;
+  result.Byte_i64_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_i64_map;
+  result.Byte_double_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_double_map;
+  result.Byte_string_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_string_map;
+  result.Byte_binary_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_binary_map;
+  result.Byte_boolean_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_boolean_map;
+  result.List_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.List_byte_map;
+  result.Set_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Set_byte_map;
+  result.Map_byte_map := DebugProtoTest.TConstants.COMPACT_TEST.Map_byte_map;
+  result.Byte_map_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_map_map;
+  result.Byte_set_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_set_map;
+  result.Byte_list_map := DebugProtoTest.TConstants.COMPACT_TEST.Byte_list_map;
 
   result.Field500 := 500;
   result.Field5000 := 5000;
diff --git a/lib/delphi/test/serializer/TestSerializer.dpr b/lib/delphi/test/serializer/TestSerializer.dpr
index 0620014..971401e 100644
--- a/lib/delphi/test/serializer/TestSerializer.dpr
+++ b/lib/delphi/test/serializer/TestSerializer.dpr
@@ -41,8 +41,9 @@
   Thrift.Stream in '..\..\src\Thrift.Stream.pas',
   Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas',
   Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
-  System_,
-  DebugProtoTest,
+  System_ in 'gen-delphi\System_.pas',
+  SysUtils_ in 'gen-delphi\SysUtils_.pas',
+  DebugProtoTest in 'gen-delphi\DebugProtoTest.pas',
   TestSerializer.Tests in 'TestSerializer.Tests.pas',
   TestSerializer.Data in 'TestSerializer.Data.pas';
 
diff --git a/lib/delphi/test/serializer/TestSerializer.dproj b/lib/delphi/test/serializer/TestSerializer.dproj
new file mode 100644
index 0000000..5f26264
--- /dev/null
+++ b/lib/delphi/test/serializer/TestSerializer.dproj
@@ -0,0 +1,150 @@
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{9282EDD8-7C12-41B0-8172-61C6BFA6E238}</ProjectGuid>
+			<MainSource>TestSerializer.dpr</MainSource>
+			<Basis>True</Basis>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform>Win32</Platform>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<ProjectVersion>12.3</ProjectVersion>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+			<DCC_F>false</DCC_F>
+			<DCC_S>false</DCC_S>
+			<DCC_N>false</DCC_N>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="TestSerializer.dpr">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="..\..\src\Thrift.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Exception.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Socket.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Transport.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.JSON.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.Compact.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Collections.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Configuration.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Server.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Utils.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Serializer.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Stream.pas"/>
+			<DCCReference Include="..\..\src\Thrift.WinHTTP.pas"/>
+			<DCCReference Include="..\..\src\Thrift.TypeRegistry.pas"/>
+			<DCCReference Include="gen-delphi\System_.pas"/>
+			<DCCReference Include="gen-delphi\SysUtils_.pas"/>
+			<DCCReference Include="gen-delphi\DebugProtoTest.pas"/>
+			<DCCReference Include="TestSerializer.Tests.pas"/>
+			<DCCReference Include="TestSerializer.Data.pas"/>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Basis">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[thrift.exe -r -gen delphi ..\keywords\ReservedKeywords.thrift
+thrift.exe -r -gen delphi ..\..\..\..\test\DebugProtoTest.thrift]]></PreBuildEvent>
+		</PropertyGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>VCLApplication</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">TestSerializer.dpr</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1031</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>
diff --git a/lib/delphi/test/server.dpr b/lib/delphi/test/server.dpr
index 954d0b6..7994281 100644
--- a/lib/delphi/test/server.dpr
+++ b/lib/delphi/test/server.dpr
@@ -25,7 +25,7 @@
   SysUtils,
   TestServer in 'TestServer.pas',
   TestServerEvents in 'TestServerEvents.pas',
-  Thrift.Test,  // in gen-delphi folder
+  Thrift.Test in 'gen-delphi\Thrift.Test.pas',
   Thrift in '..\src\Thrift.pas',
   Thrift.Exception in '..\src\Thrift.Exception.pas',
   Thrift.Transport in '..\src\Thrift.Transport.pas',
diff --git a/lib/delphi/test/server.dproj b/lib/delphi/test/server.dproj
new file mode 100644
index 0000000..9f7e5c6
--- /dev/null
+++ b/lib/delphi/test/server.dproj
@@ -0,0 +1,150 @@
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{07CEDA3D-0963-40FE-B3C2-0ED4E24DE067}</ProjectGuid>
+			<MainSource>server.dpr</MainSource>
+			<Basis>True</Basis>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform>Win32</Platform>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<ProjectVersion>12.3</ProjectVersion>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+			<DCC_F>false</DCC_F>
+			<DCC_S>false</DCC_S>
+			<DCC_N>false</DCC_N>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="server.dpr">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="TestServer.pas"/>
+			<DCCReference Include="TestServerEvents.pas"/>
+			<DCCReference Include="gen-delphi\Thrift.Test.pas"/>
+			<DCCReference Include="..\src\Thrift.pas"/>
+			<DCCReference Include="..\src\Thrift.Exception.pas"/>
+			<DCCReference Include="..\src\Thrift.Transport.pas"/>
+			<DCCReference Include="..\src\Thrift.Socket.pas"/>
+			<DCCReference Include="..\src\Thrift.Transport.Pipes.pas"/>
+			<DCCReference Include="..\src\Thrift.Protocol.pas"/>
+			<DCCReference Include="..\src\Thrift.Protocol.JSON.pas"/>
+			<DCCReference Include="..\src\Thrift.Protocol.Compact.pas"/>
+			<DCCReference Include="..\src\Thrift.Protocol.Multiplex.pas"/>
+			<DCCReference Include="..\src\Thrift.Processor.Multiplex.pas"/>
+			<DCCReference Include="..\src\Thrift.Collections.pas"/>
+			<DCCReference Include="..\src\Thrift.Configuration.pas"/>
+			<DCCReference Include="..\src\Thrift.Server.pas"/>
+			<DCCReference Include="..\src\Thrift.TypeRegistry.pas"/>
+			<DCCReference Include="..\src\Thrift.Utils.pas"/>
+			<DCCReference Include="..\src\Thrift.WinHTTP.pas"/>
+			<DCCReference Include="..\src\Thrift.Stream.pas"/>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Basis">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[thrift.exe -r -gen delphi ..\..\..\test\ThriftTest.thrift]]></PreBuildEvent>
+		</PropertyGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>VCLApplication</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">server.dpr</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1031</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>
diff --git a/lib/delphi/test/skip/skiptest_version1.dpr b/lib/delphi/test/skip/skiptest_version1.dpr
index f7cde2f..6d877de 100644
--- a/lib/delphi/test/skip/skiptest_version1.dpr
+++ b/lib/delphi/test/skip/skiptest_version1.dpr
@@ -23,7 +23,7 @@
 
 uses
   Classes, Windows, SysUtils,
-  Skiptest.One,
+  Skiptest.One in 'gen-delphi\Skiptest.One.pas',
   Thrift in '..\..\src\Thrift.pas',
   Thrift.Exception in '..\..\src\Thrift.Exception.pas',
   Thrift.Socket in '..\..\src\Thrift.Socket.pas',
@@ -47,7 +47,7 @@
 function CreatePing : IPing;
 begin
   result := TPingImpl.Create;
-  result.Version1  := Tskiptest_version_1Constants.SKIPTESTSERVICE_VERSION;
+  result.Version1  := TConstants.SKIPTESTSERVICE_VERSION;
   result.EnumTest  := TPingPongEnum.PingOne;
 end;
 
@@ -189,7 +189,7 @@
   FILE_COMPACT = 'pingpong.compact';
 begin
   try
-    Writeln( 'Delphi SkipTest '+IntToStr(Tskiptest_version_1Constants.SKIPTESTSERVICE_VERSION)+' using '+Thrift.Version);
+    Writeln( 'Delphi SkipTest '+IntToStr(TConstants.SKIPTESTSERVICE_VERSION)+' using '+Thrift.Version);
 
     Writeln;
     Writeln('Binary protocol');
diff --git a/lib/delphi/test/skip/skiptest_version1.dproj b/lib/delphi/test/skip/skiptest_version1.dproj
new file mode 100644
index 0000000..2e8997e
--- /dev/null
+++ b/lib/delphi/test/skip/skiptest_version1.dproj
@@ -0,0 +1,144 @@
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{894CD87B-337B-49F7-BC7D-2D9F65CE8FE0}</ProjectGuid>
+			<MainSource>skiptest_version1.dpr</MainSource>
+			<Basis>True</Basis>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform>Win32</Platform>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<ProjectVersion>12.3</ProjectVersion>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+			<DCC_F>false</DCC_F>
+			<DCC_S>false</DCC_S>
+			<DCC_N>false</DCC_N>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="skiptest_version1.dpr">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="gen-delphi\Skiptest.One.pas"/>
+			<DCCReference Include="..\..\src\Thrift.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Exception.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Socket.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Transport.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.JSON.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.Compact.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Collections.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Configuration.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Server.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Utils.pas"/>
+			<DCCReference Include="..\..\src\Thrift.WinHTTP.pas"/>
+			<DCCReference Include="..\..\src\Thrift.TypeRegistry.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Stream.pas"/>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Basis">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[thrift.exe -r -gen delphi idl\skiptest_version_1.thrift]]></PreBuildEvent>
+		</PropertyGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>VCLApplication</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">skiptest_version1.dpr</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1031</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>
diff --git a/lib/delphi/test/skip/skiptest_version2.dpr b/lib/delphi/test/skip/skiptest_version2.dpr
index 478ea7c..b3a270d 100644
--- a/lib/delphi/test/skip/skiptest_version2.dpr
+++ b/lib/delphi/test/skip/skiptest_version2.dpr
@@ -23,7 +23,7 @@
 
 uses
   Classes, Windows, SysUtils,
-  Skiptest.Two,
+  Skiptest.Two in 'gen-delphi\Skiptest.Two.pas',
   Thrift in '..\..\src\Thrift.pas',
   Thrift.Exception in '..\..\src\Thrift.Exception.pas',
   Thrift.Socket in '..\..\src\Thrift.Socket.pas',
@@ -49,7 +49,7 @@
     set_ : IHashSet<string>;
 begin
   result := TPingImpl.Create;
-  result.Version1  := Tskiptest_version_2Constants.SKIPTESTSERVICE_VERSION;
+  result.Version1  := TConstants.SKIPTESTSERVICE_VERSION;
   result.EnumTest  := TPingPongEnum.PingTwo;
 
   result.BoolVal   := TRUE;
@@ -219,7 +219,7 @@
   FILE_COMPACT = 'pingpong.compact';
 begin
   try
-    Writeln( 'Delphi SkipTest '+IntToStr(Tskiptest_version_2Constants.SKIPTESTSERVICE_VERSION)+' using '+Thrift.Version);
+    Writeln( 'Delphi SkipTest '+IntToStr(TConstants.SKIPTESTSERVICE_VERSION)+' using '+Thrift.Version);
 
     Writeln;
     Writeln('Binary protocol');
diff --git a/lib/delphi/test/skip/skiptest_version2.dproj b/lib/delphi/test/skip/skiptest_version2.dproj
new file mode 100644
index 0000000..3192d28
--- /dev/null
+++ b/lib/delphi/test/skip/skiptest_version2.dproj
@@ -0,0 +1,144 @@
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{DBB2D6D8-0FC6-4329-8408-28B1452B33AD}</ProjectGuid>
+			<MainSource>skiptest_version2.dpr</MainSource>
+			<Basis>True</Basis>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform>Win32</Platform>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<ProjectVersion>12.3</ProjectVersion>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+			<DCC_F>false</DCC_F>
+			<DCC_S>false</DCC_S>
+			<DCC_N>false</DCC_N>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="skiptest_version2.dpr">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="gen-delphi\Skiptest.Two.pas"/>
+			<DCCReference Include="..\..\src\Thrift.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Exception.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Socket.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Transport.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.JSON.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.Compact.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Collections.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Configuration.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Server.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Utils.pas"/>
+			<DCCReference Include="..\..\src\Thrift.WinHTTP.pas"/>
+			<DCCReference Include="..\..\src\Thrift.TypeRegistry.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Stream.pas"/>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Basis">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[thrift.exe -r -gen delphi idl\skiptest_version_2.thrift]]></PreBuildEvent>
+		</PropertyGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>VCLApplication</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">skiptest_version2.dpr</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1031</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>
diff --git a/lib/delphi/test/typeregistry/TestTypeRegistry.dpr b/lib/delphi/test/typeregistry/TestTypeRegistry.dpr
index 2896bbf..c7a9767 100644
--- a/lib/delphi/test/typeregistry/TestTypeRegistry.dpr
+++ b/lib/delphi/test/typeregistry/TestTypeRegistry.dpr
@@ -37,7 +37,8 @@
   Thrift.Stream in '..\..\src\Thrift.Stream.pas',
   Thrift.WinHTTP in '..\..\src\Thrift.WinHTTP.pas',
   Thrift.TypeRegistry in '..\..\src\Thrift.TypeRegistry.pas',
-  Thrift.Test, // in 'gen-delphi\Thrift.Test.pas',
+  Thrift.Test in 'gen-delphi\Thrift.Test.pas',
+  DebugProtoTest in 'gen-delphi\DebugProtoTest.pas',
   Test.TypeRegistry,
   Test.EnumToString;
 
diff --git a/lib/delphi/test/typeregistry/TestTypeRegistry.dproj b/lib/delphi/test/typeregistry/TestTypeRegistry.dproj
new file mode 100644
index 0000000..814faf4
--- /dev/null
+++ b/lib/delphi/test/typeregistry/TestTypeRegistry.dproj
@@ -0,0 +1,146 @@
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+		<PropertyGroup>
+			<ProjectGuid>{D6B3910D-CD64-449F-B7A6-404D5DF1DAC5}</ProjectGuid>
+			<MainSource>TestTypeRegistry.dpr</MainSource>
+			<Basis>True</Basis>
+			<Config Condition="'$(Config)'==''">Debug</Config>
+			<Platform>Win32</Platform>
+			<AppType>Console</AppType>
+			<FrameworkType>None</FrameworkType>
+			<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+			<ProjectVersion>12.3</ProjectVersion>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
+			<Cfg_1>true</Cfg_1>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
+			<Cfg_2>true</Cfg_2>
+			<CfgParent>Base</CfgParent>
+			<Base>true</Base>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Base)'!=''">
+			<DCC_DcuOutput>dcu\$(Project)\$(Config)\$(Platform)</DCC_DcuOutput>
+			<DCC_ExeOutput>bin\$(Config)\$(Platform)</DCC_ExeOutput>
+			<DCC_E>false</DCC_E>
+			<DCC_ImageBase>00400000</DCC_ImageBase>
+			<DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;WinTypes=Windows;WinProcs=Windows;$(DCC_UnitAlias)</DCC_UnitAlias>
+			<DCC_F>false</DCC_F>
+			<DCC_S>false</DCC_S>
+			<DCC_N>false</DCC_N>
+			<DCC_K>false</DCC_K>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_1)'!=''">
+			<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+			<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+			<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+			<DCC_DebugInformation>false</DCC_DebugInformation>
+		</PropertyGroup>
+		<PropertyGroup Condition="'$(Cfg_2)'!=''">
+			<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+			<DCC_Optimize>false</DCC_Optimize>
+			<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+		</PropertyGroup>
+		<ItemGroup>
+			<DelphiCompile Include="TestTypeRegistry.dpr">
+				<MainSource>MainSource</MainSource>
+			</DelphiCompile>
+			<DCCReference Include="..\..\src\Thrift.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Transport.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Exception.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Socket.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Protocol.JSON.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Collections.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Configuration.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Server.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Utils.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Serializer.pas"/>
+			<DCCReference Include="..\..\src\Thrift.Stream.pas"/>
+			<DCCReference Include="..\..\src\Thrift.WinHTTP.pas"/>
+			<DCCReference Include="..\..\src\Thrift.TypeRegistry.pas"/>
+			<DCCReference Include="gen-delphi\Thrift.Test.pas"/>
+			<DCCReference Include="gen-delphi\DebugProtoTest.pas"/>
+			<BuildConfiguration Include="Debug">
+				<Key>Cfg_2</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Basis">
+				<Key>Base</Key>
+			</BuildConfiguration>
+			<BuildConfiguration Include="Release">
+				<Key>Cfg_1</Key>
+				<CfgParent>Base</CfgParent>
+			</BuildConfiguration>
+		</ItemGroup>
+		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[thrift.exe -r -gen delphi:register_types ..\..\..\..\test\ThriftTest.thrift
+thrift.exe -r -gen delphi:register_types ..\..\..\..\test\DebugProtoTest.thrift]]></PreBuildEvent>
+		</PropertyGroup>
+		<ProjectExtensions>
+			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
+			<Borland.ProjectType>VCLApplication</Borland.ProjectType>
+			<BorlandProject>
+				<Delphi.Personality>
+					<Source>
+						<Source Name="MainSource">TestTypeRegistry.dpr</Source>
+					</Source>
+					<VersionInfo>
+						<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+						<VersionInfo Name="AutoIncBuild">False</VersionInfo>
+						<VersionInfo Name="MajorVer">1</VersionInfo>
+						<VersionInfo Name="MinorVer">0</VersionInfo>
+						<VersionInfo Name="Release">0</VersionInfo>
+						<VersionInfo Name="Build">0</VersionInfo>
+						<VersionInfo Name="Debug">False</VersionInfo>
+						<VersionInfo Name="PreRelease">False</VersionInfo>
+						<VersionInfo Name="Special">False</VersionInfo>
+						<VersionInfo Name="Private">False</VersionInfo>
+						<VersionInfo Name="DLL">False</VersionInfo>
+						<VersionInfo Name="Locale">1031</VersionInfo>
+						<VersionInfo Name="CodePage">1252</VersionInfo>
+					</VersionInfo>
+					<VersionInfoKeys>
+						<VersionInfoKeys Name="CompanyName"/>
+						<VersionInfoKeys Name="FileDescription"/>
+						<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="InternalName"/>
+						<VersionInfoKeys Name="LegalCopyright"/>
+						<VersionInfoKeys Name="LegalTrademarks"/>
+						<VersionInfoKeys Name="OriginalFilename"/>
+						<VersionInfoKeys Name="ProductName"/>
+						<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+						<VersionInfoKeys Name="Comments"/>
+					</VersionInfoKeys>
+				</Delphi.Personality>
+				<Platforms>
+					<Platform value="Win32">True</Platform>
+				</Platforms>
+			</BorlandProject>
+			<ProjectFileVersion>12</ProjectFileVersion>
+		</ProjectExtensions>
+	</Project>
diff --git a/lib/erl/Makefile.am b/lib/erl/Makefile.am
index d4544a3..bf7abd5 100644
--- a/lib/erl/Makefile.am
+++ b/lib/erl/Makefile.am
@@ -26,16 +26,9 @@
 		  ../../test/DoubleConstantsTest.thrift \
 		  ../../test/ThriftTest.thrift
 
-if ERLANG_OTP16
-ERL_FLAG = erl:otp16
-ERL_FLAG_LEGACY = erl:otp16,legacynames
-# otp16 + maps does not make sense. We need to generate it anyway to avoid include error.
-ERL_FLAG_MAPS = erl:otp16
-else
 ERL_FLAG = erl
 ERL_FLAG_LEGACY = erl:legacynames
 ERL_FLAG_MAPS = erl:maps
-endif
 
 $(THRIFT_OMIT_FILE): test/Thrift_omit_with.thrift
 	grep -v omit $< >$@
diff --git a/lib/erl/rebar.config b/lib/erl/rebar.config
index ab2c255..b5258a2 100644
--- a/lib/erl/rebar.config
+++ b/lib/erl/rebar.config
@@ -1,4 +1,4 @@
-{erl_opts, [{platform_define, "^R.*", otp16_or_less}, debug_info]}.
+{erl_opts, [debug_info]}.
 
 {profiles, [
     {test, [
diff --git a/lib/erl/src/thrift.app.src b/lib/erl/src/thrift.app.src
index 5c9b23d..a98c586 100644
--- a/lib/erl/src/thrift.app.src
+++ b/lib/erl/src/thrift.app.src
@@ -22,7 +22,7 @@
   {description, "Thrift bindings"},
 
   % The version of the applicaton
-  {vsn, "0.14.2"},
+  {vsn, "0.15.0"},
 
   % All modules used by the application.
   {modules, [
diff --git a/lib/erl/test/test_thrift_3214.erl b/lib/erl/test/test_thrift_3214.erl
index 0f9544b..118e779 100644
--- a/lib/erl/test/test_thrift_3214.erl
+++ b/lib/erl/test/test_thrift_3214.erl
@@ -23,7 +23,6 @@
 -include("gen-erl/thrift3214_types.hrl").
 
 -ifdef(TEST).
--ifndef(otp16_or_less).
 -include_lib("eunit/include/eunit.hrl").
 
 record_generation_test_() ->
@@ -57,4 +56,3 @@
   ].
 
 -endif.
--endif.
diff --git a/lib/go/Makefile.am b/lib/go/Makefile.am
index 0dfa5fa..d7f9b27 100644
--- a/lib/go/Makefile.am
+++ b/lib/go/Makefile.am
@@ -20,7 +20,7 @@
 SUBDIRS = .
 
 if WITH_TESTS
-SUBDIRS += test
+SUBDIRS += test test/fuzz
 endif
 
 install:
@@ -31,13 +31,13 @@
 	@echo '##############################################################'
 
 check-local:
-	GOPATH=`pwd` $(GO) test -race ./thrift
+	$(GO) test -mod=mod -race ./thrift
 
 clean-local:
 	$(RM) -rf pkg
 
 all-local:
-	GOPATH=`pwd` $(GO) build ./thrift
+	$(GO) build -mod=mod ./thrift
 
 EXTRA_DIST = \
 	thrift \
diff --git a/lib/go/test/Makefile.am b/lib/go/test/Makefile.am
index 4be652e..a5d0797 100644
--- a/lib/go/test/Makefile.am
+++ b/lib/go/test/Makefile.am
@@ -17,7 +17,7 @@
 # under the License.
 #
 
-THRIFTARGS = -out gopath/src/ --gen go:thrift_import=thrift$(COMPILER_EXTRAFLAG)
+THRIFTARGS = -out gopath/src/ --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/lib/go/test/gopath/src/$(COMPILER_EXTRAFLAG)
 THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift
 
 # Thrift for GO has problems with complex map keys: THRIFT-2063
@@ -77,40 +77,37 @@
 	$(THRIFT) $(THRIFTARGS) -r DuplicateImportsTest.thrift
 	$(THRIFT) $(THRIFTARGS) EqualsTest.thrift
 	$(THRIFT) $(THRIFTARGS) ConflictArgNamesTest.thrift
-	GOPATH=`pwd`/gopath $(GO) get github.com/golang/mock/gomock || true
-	sed -i 's/\"context\"/\"golang.org\/x\/net\/context\"/g' gopath/src/github.com/golang/mock/gomock/controller.go || true
-	GOPATH=`pwd`/gopath $(GO) get github.com/golang/mock/gomock
-	ln -nfs ../../../thrift gopath/src/thrift
 	ln -nfs ../../tests gopath/src/tests
 	cp -r ./dontexportrwtest gopath/src
 	touch gopath
 
 check: gopath
-	GOPATH=`pwd`/gopath $(GO) build \
-				includestest \
-				binarykeytest \
-				servicestest \
-				typedeffieldtest \
-				refannotationfieldstest \
-				errortest	\
-				namestest \
-				initialismstest \
-				dontexportrwtest \
-				ignoreinitialismstest \
-				unionbinarytest \
-				conflictnamespacetestsuperthing \
-				conflict/context/conflict_service-remote \
-				servicestest/container_test-remote \
-				duplicateimportstest \
-				equalstest \
-				conflictargnamestest
-	GOPATH=`pwd`/gopath $(GO) test thrift tests dontexportrwtest
+	$(GO) build -mod=mod \
+				./gopath/src/includestest \
+				./gopath/src/binarykeytest \
+				./gopath/src/servicestest \
+				./gopath/src/typedeffieldtest \
+				./gopath/src/refannotationfieldstest \
+				./gopath/src/errortest	\
+				./gopath/src/namestest \
+				./gopath/src/initialismstest \
+				./gopath/src/dontexportrwtest \
+				./gopath/src/ignoreinitialismstest \
+				./gopath/src/unionbinarytest \
+				./gopath/src/conflictnamespacetestsuperthing \
+				./gopath/src/conflict/context/conflict_service-remote \
+				./gopath/src/servicestest/container_test-remote \
+				./gopath/src/duplicateimportstest \
+				./gopath/src/equalstest \
+				./gopath/src/conflictargnamestest
+	$(GO) test -mod=mod github.com/apache/thrift/lib/go/thrift
+	$(GO) test -mod=mod ./gopath/src/tests ./gopath/src/dontexportrwtest
 
 clean-local:
 	$(RM) -r gopath ThriftTest.thrift gen-go
 
 client: stubs
-	$(GO) run TestClient.go
+	$(GO) run -mod=mod TestClient.go
 
 EXTRA_DIST = \
 	dontexportrwtest \
diff --git a/build/cmake/FindCabal.cmake b/lib/go/test/fuzz/Makefile.am
similarity index 68%
copy from build/cmake/FindCabal.cmake
copy to lib/go/test/fuzz/Makefile.am
index fed337b..a6abfc5 100644
--- a/build/cmake/FindCabal.cmake
+++ b/lib/go/test/fuzz/Makefile.am
@@ -17,14 +17,15 @@
 # under the License.
 #
 
+gopathfuzz: $(THRIFT) fuzz.go
+	$(THRIFT) -r --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift$(COMPILER_EXTRAFLAG) ../../../../tutorial/tutorial.thrift
+	cd gen-go/shared && go mod init shared
+	cd gen-go/tutorial && go mod init tutorial
+	touch gopathfuzz
 
-#  Cabal_FOUND - system has Cabal
-#  Cabal - the Cabal executable
-#
-# It will search the environment variable CABAL_HOME if it is set
+check: gopathfuzz
+	go test -mod=mod -tags gofuzz
 
-include(FindPackageHandleStandardArgs)
+clean-local:
+	$(RM) -r gopathfuzz gen-go
 
-find_program(CABAL NAMES cabal PATHS $ENV{HOME}/.cabal/bin $ENV{CABAL_HOME}/bin)
-find_package_handle_standard_args(CABAL DEFAULT_MSG CABAL)
-mark_as_advanced(CABAL)
diff --git a/lib/go/test/fuzz/fuzz.go b/lib/go/test/fuzz/fuzz.go
new file mode 100644
index 0000000..cd99d58d
--- /dev/null
+++ b/lib/go/test/fuzz/fuzz.go
@@ -0,0 +1,144 @@
+// +build gofuzz
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package fuzz
+
+import (
+	"context"
+	"fmt"
+	"strconv"
+
+	"shared"
+	"tutorial"
+
+	"github.com/apache/thrift/lib/go/thrift"
+)
+
+const nbFuzzedProtocols = 2
+
+func fuzzChooseProtocol(d byte, t thrift.TTransport) thrift.TProtocol {
+	switch d % nbFuzzedProtocols {
+	default:
+		fallthrough
+	case 0:
+		return thrift.NewTBinaryProtocolFactoryConf(nil).GetProtocol(t)
+	case 1:
+		return thrift.NewTCompactProtocolFactoryConf(nil).GetProtocol(t)
+	}
+}
+
+func Fuzz(data []byte) int {
+	if len(data) < 2 {
+		return 0
+	}
+	inputTransport := thrift.NewTMemoryBuffer()
+	inputTransport.Buffer.Write(data[2:])
+	outputTransport := thrift.NewTMemoryBuffer()
+	outputProtocol := fuzzChooseProtocol(data[0], outputTransport)
+	inputProtocol := fuzzChooseProtocol(data[1], inputTransport)
+	ctx := thrift.SetResponseHelper(
+		context.Background(),
+		thrift.TResponseHelper{
+			THeaderResponseHelper: thrift.NewTHeaderResponseHelper(outputProtocol),
+		},
+	)
+	handler := NewCalculatorHandler()
+	processor := tutorial.NewCalculatorProcessor(handler)
+	ok := true
+	var err error
+	for ok {
+		ok, err = processor.Process(ctx, inputProtocol, outputProtocol)
+		if err != nil {
+			// Handle parse error
+			return 0
+		}
+		res := make([]byte, 1024)
+		n, err := outputTransport.Buffer.Read(res)
+		fmt.Printf("lol %d %s %v\n", n, err, res)
+	}
+	return 1
+}
+
+type CalculatorHandler struct {
+	log map[int]*shared.SharedStruct
+}
+
+func NewCalculatorHandler() *CalculatorHandler {
+	return &CalculatorHandler{log: make(map[int]*shared.SharedStruct)}
+}
+
+func (p *CalculatorHandler) Ping(ctx context.Context) (err error) {
+	fmt.Print("ping()\n")
+	return nil
+}
+
+func (p *CalculatorHandler) Add(ctx context.Context, num1 int32, num2 int32) (retval17 int32, err error) {
+	fmt.Print("add(", num1, ",", num2, ")\n")
+	return num1 + num2, nil
+}
+
+func (p *CalculatorHandler) Calculate(ctx context.Context, logid int32, w *tutorial.Work) (val int32, err error) {
+	fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n")
+	switch w.Op {
+	case tutorial.Operation_ADD:
+		val = w.Num1 + w.Num2
+		break
+	case tutorial.Operation_SUBTRACT:
+		val = w.Num1 - w.Num2
+		break
+	case tutorial.Operation_MULTIPLY:
+		val = w.Num1 * w.Num2
+		break
+	case tutorial.Operation_DIVIDE:
+		if w.Num2 == 0 {
+			ouch := tutorial.NewInvalidOperation()
+			ouch.WhatOp = int32(w.Op)
+			ouch.Why = "Cannot divide by 0"
+			err = ouch
+			return
+		}
+		val = w.Num1 / w.Num2
+		break
+	default:
+		ouch := tutorial.NewInvalidOperation()
+		ouch.WhatOp = int32(w.Op)
+		ouch.Why = "Unknown operation"
+		err = ouch
+		return
+	}
+	entry := shared.NewSharedStruct()
+	entry.Key = logid
+	entry.Value = strconv.Itoa(int(val))
+	k := int(logid)
+	p.log[k] = entry
+	return val, err
+}
+
+func (p *CalculatorHandler) GetStruct(ctx context.Context, key int32) (*shared.SharedStruct, error) {
+	fmt.Print("getStruct(", key, ")\n")
+	v, _ := p.log[int(key)]
+	return v, nil
+}
+
+func (p *CalculatorHandler) Zip(ctx context.Context) (err error) {
+	fmt.Print("zip()\n")
+	return nil
+}
diff --git a/lib/as3/settings.gradle b/lib/go/test/fuzz/fuzz_test.go
similarity index 87%
rename from lib/as3/settings.gradle
rename to lib/go/test/fuzz/fuzz_test.go
index 4932346..2983e0f 100644
--- a/lib/as3/settings.gradle
+++ b/lib/go/test/fuzz/fuzz_test.go
@@ -1,3 +1,5 @@
+// +build gofuzz
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements. See the NOTICE file
@@ -17,4 +19,12 @@
  * under the License.
  */
 
-rootProject.name = 'libthrift-as3'
+package fuzz
+
+import (
+	"testing"
+)
+
+func TestFuzz(t *testing.T) {
+	Fuzz([]byte{1, 2, 3})
+}
diff --git a/lib/go/test/fuzz/go.mod b/lib/go/test/fuzz/go.mod
new file mode 100644
index 0000000..efff516
--- /dev/null
+++ b/lib/go/test/fuzz/go.mod
@@ -0,0 +1,9 @@
+module github.com/apache/thrift/lib/go/test/fuzz
+
+go 1.15
+
+replace github.com/apache/thrift => ../../../../
+
+replace shared => ./gen-go/shared
+
+replace tutorial => ./gen-go/tutorial
diff --git a/lib/go/test/tests/binary_key_test.go b/lib/go/test/tests/binary_key_test.go
index aa96193..511c246 100644
--- a/lib/go/test/tests/binary_key_test.go
+++ b/lib/go/test/tests/binary_key_test.go
@@ -20,8 +20,9 @@
 package tests
 
 import (
-	"binarykeytest"
 	"testing"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/binarykeytest"
 )
 
 func TestBinaryMapKeyGeneratesString(t *testing.T) {
diff --git a/lib/go/test/tests/client_error_test.go b/lib/go/test/tests/client_error_test.go
index 8d720ff..64339dc 100644
--- a/lib/go/test/tests/client_error_test.go
+++ b/lib/go/test/tests/client_error_test.go
@@ -22,11 +22,12 @@
 import (
 	"context"
 	"errors"
-	"errortest"
 	"testing"
-	"thrift"
 
 	"github.com/golang/mock/gomock"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/errortest"
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 // TestCase: Comprehensive call and reply workflow in the client.
diff --git a/lib/go/test/tests/conflict_arg_names_test.go b/lib/go/test/tests/conflict_arg_names_test.go
index 9279151..b9049a1 100644
--- a/lib/go/test/tests/conflict_arg_names_test.go
+++ b/lib/go/test/tests/conflict_arg_names_test.go
@@ -20,7 +20,7 @@
 package tests
 
 import (
-	"conflictargnamestest"
+	"github.com/apache/thrift/lib/go/test/gopath/src/conflictargnamestest"
 )
 
 // We just want to make sure that the conflictargnamestest package compiles.
diff --git a/lib/go/test/tests/encoding_json_test.go b/lib/go/test/tests/encoding_json_test.go
index 12d4566..cda8ad9 100644
--- a/lib/go/test/tests/encoding_json_test.go
+++ b/lib/go/test/tests/encoding_json_test.go
@@ -23,7 +23,8 @@
 	"encoding"
 	"encoding/json"
 	"testing"
-	"thrifttest"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/thrifttest"
 )
 
 func TestEnumIsTextMarshaller(t *testing.T) {
diff --git a/lib/go/test/tests/equals_test.go b/lib/go/test/tests/equals_test.go
index deecb77..3bd14b6 100644
--- a/lib/go/test/tests/equals_test.go
+++ b/lib/go/test/tests/equals_test.go
@@ -20,9 +20,10 @@
 package tests
 
 import (
-	"equalstest"
 	"strconv"
 	"testing"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/equalstest"
 )
 
 func TestEquals(t *testing.T) {
diff --git a/lib/go/test/tests/gotag_test.go b/lib/go/test/tests/gotag_test.go
index 4cbea56..b7ad17b 100644
--- a/lib/go/test/tests/gotag_test.go
+++ b/lib/go/test/tests/gotag_test.go
@@ -20,9 +20,10 @@
 package tests
 
 import (
-	"gotagtest"
 	"reflect"
 	"testing"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/gotagtest"
 )
 
 func TestDefaultTag(t *testing.T) {
diff --git a/lib/go/test/tests/ignoreinitialisms_test.go b/lib/go/test/tests/ignoreinitialisms_test.go
index 3cd5f65..c7012dd 100644
--- a/lib/go/test/tests/ignoreinitialisms_test.go
+++ b/lib/go/test/tests/ignoreinitialisms_test.go
@@ -20,9 +20,10 @@
 package tests
 
 import (
-	"ignoreinitialismstest"
 	"reflect"
 	"testing"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/ignoreinitialismstest"
 )
 
 func TestIgnoreInitialismsFlagIsHonoured(t *testing.T) {
diff --git a/lib/go/test/tests/initialisms_test.go b/lib/go/test/tests/initialisms_test.go
index 40923d2..e6b4f63 100644
--- a/lib/go/test/tests/initialisms_test.go
+++ b/lib/go/test/tests/initialisms_test.go
@@ -20,9 +20,10 @@
 package tests
 
 import (
-	"initialismstest"
 	"reflect"
 	"testing"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/initialismstest"
 )
 
 func TestThatCommonInitialismsAreFixed(t *testing.T) {
diff --git a/lib/go/test/tests/multiplexed_protocol_test.go b/lib/go/test/tests/multiplexed_protocol_test.go
index 4fb6f4f..a5975b7 100644
--- a/lib/go/test/tests/multiplexed_protocol_test.go
+++ b/lib/go/test/tests/multiplexed_protocol_test.go
@@ -21,11 +21,12 @@
 
 import (
 	"context"
-	"multiplexedprotocoltest"
 	"net"
 	"testing"
-	"thrift"
 	"time"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/multiplexedprotocoltest"
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 func FindAvailableTCPServerPort() net.Addr {
diff --git a/lib/go/test/tests/names_test.go b/lib/go/test/tests/names_test.go
index 90b63a3..5094bcb 100644
--- a/lib/go/test/tests/names_test.go
+++ b/lib/go/test/tests/names_test.go
@@ -20,9 +20,10 @@
 package tests
 
 import (
-	"namestest"
 	"reflect"
 	"testing"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/namestest"
 )
 
 func TestThatAttributeNameSubstituionDoesNotOccur(t *testing.T) {
diff --git a/lib/go/test/tests/one_way_test.go b/lib/go/test/tests/one_way_test.go
index 010e3bb..295dc1f 100644
--- a/lib/go/test/tests/one_way_test.go
+++ b/lib/go/test/tests/one_way_test.go
@@ -23,10 +23,11 @@
 	"context"
 	"fmt"
 	"net"
-	"onewaytest"
 	"testing"
-	"thrift"
 	"time"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/onewaytest"
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 func findPort() net.Addr {
diff --git a/lib/go/test/tests/optional_fields_test.go b/lib/go/test/tests/optional_fields_test.go
index 7e240e6..39fb1b5 100644
--- a/lib/go/test/tests/optional_fields_test.go
+++ b/lib/go/test/tests/optional_fields_test.go
@@ -22,10 +22,12 @@
 import (
 	"bytes"
 	"context"
-	gomock "github.com/golang/mock/gomock"
-	"optionalfieldstest"
 	"testing"
-	"thrift"
+
+	"github.com/golang/mock/gomock"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/optionalfieldstest"
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 func TestIsSetReturnFalseOnCreation(t *testing.T) {
diff --git a/lib/go/test/tests/protocol_mock.go b/lib/go/test/tests/protocol_mock.go
index 793e4e1..1cdd4c3 100644
--- a/lib/go/test/tests/protocol_mock.go
+++ b/lib/go/test/tests/protocol_mock.go
@@ -24,7 +24,7 @@
 
 import (
 	"context"
-	thrift "thrift"
+	thrift "github.com/apache/thrift/lib/go/thrift"
 
 	gomock "github.com/golang/mock/gomock"
 )
diff --git a/lib/go/test/tests/protocols_test.go b/lib/go/test/tests/protocols_test.go
index 9030e9d..351fe59 100644
--- a/lib/go/test/tests/protocols_test.go
+++ b/lib/go/test/tests/protocols_test.go
@@ -21,8 +21,9 @@
 
 import (
 	"testing"
-	"thrift"
-	"thrifttest"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/thrifttest"
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 func RunSocketTestSuite(t *testing.T, protocolFactory thrift.TProtocolFactory,
diff --git a/lib/go/test/tests/required_fields_test.go b/lib/go/test/tests/required_fields_test.go
index 06e8560..da80f9b 100644
--- a/lib/go/test/tests/required_fields_test.go
+++ b/lib/go/test/tests/required_fields_test.go
@@ -21,11 +21,13 @@
 
 import (
 	"context"
-	"github.com/golang/mock/gomock"
-	"optionalfieldstest"
-	"requiredfieldtest"
 	"testing"
-	"thrift"
+
+	"github.com/golang/mock/gomock"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/optionalfieldstest"
+	"github.com/apache/thrift/lib/go/test/gopath/src/requiredfieldtest"
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 func TestRequiredField_SucecssWhenSet(t *testing.T) {
diff --git a/lib/go/test/tests/struct_args_rets_test.go b/lib/go/test/tests/struct_args_rets_test.go
index 81e9b26..df6b746 100644
--- a/lib/go/test/tests/struct_args_rets_test.go
+++ b/lib/go/test/tests/struct_args_rets_test.go
@@ -20,7 +20,7 @@
 package tests
 
 import (
-	st "servicestest"
+	st "github.com/apache/thrift/lib/go/test/gopath/src/servicestest"
 )
 
 //this function is never called, it will fail to compile if check is failed
diff --git a/lib/go/test/tests/thrifttest_driver.go b/lib/go/test/tests/thrifttest_driver.go
index 4fc5baa..b351295 100644
--- a/lib/go/test/tests/thrifttest_driver.go
+++ b/lib/go/test/tests/thrifttest_driver.go
@@ -22,7 +22,8 @@
 import (
 	"reflect"
 	"testing"
-	"thrifttest"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/thrifttest"
 )
 
 type ThriftTestDriver struct {
diff --git a/lib/go/test/tests/thrifttest_handler.go b/lib/go/test/tests/thrifttest_handler.go
index 7b115ec..419a18b 100644
--- a/lib/go/test/tests/thrifttest_handler.go
+++ b/lib/go/test/tests/thrifttest_handler.go
@@ -22,9 +22,10 @@
 import (
 	"context"
 	"errors"
-	"thrift"
-	"thrifttest"
 	"time"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/thrifttest"
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 type SecondServiceHandler struct {
diff --git a/lib/go/test/tests/union_binary_test.go b/lib/go/test/tests/union_binary_test.go
index bdae2cb..3fe9d0e 100644
--- a/lib/go/test/tests/union_binary_test.go
+++ b/lib/go/test/tests/union_binary_test.go
@@ -21,9 +21,9 @@
 
 import (
 	"testing"
-	"unionbinarytest"
-)
 
+	"github.com/apache/thrift/lib/go/test/gopath/src/unionbinarytest"
+)
 
 // See https://issues.apache.org/jira/browse/THRIFT-4573
 func TestUnionBinary(t *testing.T) {
diff --git a/lib/go/test/tests/union_default_value_test.go b/lib/go/test/tests/union_default_value_test.go
index 2dcbf4e..a02569a 100644
--- a/lib/go/test/tests/union_default_value_test.go
+++ b/lib/go/test/tests/union_default_value_test.go
@@ -21,7 +21,8 @@
 
 import (
 	"testing"
-	"uniondefaultvaluetest"
+
+	"github.com/apache/thrift/lib/go/test/gopath/src/uniondefaultvaluetest"
 )
 
 func TestUnionDefaultValue(t *testing.T) {
diff --git a/lib/go/thrift/protocol.go b/lib/go/thrift/protocol.go
index 0a69bd4..4768c8f 100644
--- a/lib/go/thrift/protocol.go
+++ b/lib/go/thrift/protocol.go
@@ -122,11 +122,14 @@
 			return err
 		}
 		for {
-			_, typeId, _, _ := self.ReadFieldBegin(ctx)
+			_, typeId, _, err := self.ReadFieldBegin(ctx)
+			if err != nil {
+				return err
+			}
 			if typeId == STOP {
 				break
 			}
-			err := Skip(ctx, self, typeId, maxDepth-1)
+			err = Skip(ctx, self, typeId, maxDepth-1)
 			if err != nil {
 				return err
 			}
diff --git a/lib/go/thrift/socket.go b/lib/go/thrift/socket.go
index e911bf1..0cf59a0 100644
--- a/lib/go/thrift/socket.go
+++ b/lib/go/thrift/socket.go
@@ -166,7 +166,11 @@
 		p.addr.String(),
 		p.cfg.GetConnectTimeout(),
 	)); err != nil {
-		return NewTTransportException(NOT_OPEN, err.Error())
+		return &tTransportException{
+			typeId: NOT_OPEN,
+			err:    err,
+			msg:    err.Error(),
+		}
 	}
 	return nil
 }
diff --git a/lib/go/thrift/ssl_socket.go b/lib/go/thrift/ssl_socket.go
index 6359a74..cd711ff 100644
--- a/lib/go/thrift/ssl_socket.go
+++ b/lib/go/thrift/ssl_socket.go
@@ -167,7 +167,11 @@
 			p.hostPort,
 			p.cfg.GetTLSConfig(),
 		)); err != nil {
-			return NewTTransportException(NOT_OPEN, err.Error())
+			return &tTransportException{
+				typeId: NOT_OPEN,
+				err:    err,
+				msg:    err.Error(),
+			}
 		}
 	} else {
 		if p.conn.isValid() {
@@ -190,7 +194,11 @@
 			p.addr.String(),
 			p.cfg.GetTLSConfig(),
 		)); err != nil {
-			return NewTTransportException(NOT_OPEN, err.Error())
+			return &tTransportException{
+				typeId: NOT_OPEN,
+				err:    err,
+				msg:    err.Error(),
+			}
 		}
 	}
 	return nil
diff --git a/lib/go/thrift/transport_exception.go b/lib/go/thrift/transport_exception.go
index 0a3f076..a51510e 100644
--- a/lib/go/thrift/transport_exception.go
+++ b/lib/go/thrift/transport_exception.go
@@ -72,7 +72,7 @@
 }
 
 func (p *tTransportException) Timeout() bool {
-	return p.typeId == TIMED_OUT
+	return p.typeId == TIMED_OUT || isTimeoutError(p.err)
 }
 
 func NewTTransportException(t int, e string) TTransportException {
diff --git a/lib/haxe/README.md b/lib/haxe/README.md
index c9f74b5..1f09c2c 100644
--- a/lib/haxe/README.md
+++ b/lib/haxe/README.md
@@ -26,16 +26,14 @@
 Haxe setup
 ---------------
 
-Thrift requires Haxe 3.1.3. Installers for Windows and OSX
+Thrift requires Haxe 4.2.1. Installers for Windows and OSX
 platforms are available at `http://haxe.org/download`. 
 
 Depending on the desired targets, you may have to install the appropriate HaxeLibs 
-after installing Haxe itself. For example, if you plan to target C#, Java and C++,
-enter the following commands after installing Haxe:
+after installing Haxe itself. For example, if you plan to target C++, enter the 
+following command after installing Haxe:
 
     haxelib install hxcpp
-    haxelib install hxjava
-    haxelib install hxcs
 
 For other targets, please consult the Haxe documentation whether or not any additional
 target libraries need to be installed and how to achieve this.
@@ -66,12 +64,12 @@
 Thrift Haxe bindings
 -------------------
 	
-Thrift Haxe bindings can be set up via the `haxelib` tool  
-either from the official ASF repo, or via the github mirror.
+Thrift Haxe bindings can be set up via the `haxelib` tool  as usual.
+Alternatively, the "github" method can be used.
 
-- To set up any **stable version**, choose the appropriate branch (e.g. `0.12.0`):
+- To set up any **stable version**, choose the appropriate branch (e.g. `0.14.1`):
 
-    - `haxelib git thrift https://github.com/apache/thrift.git 0.12.0 lib/haxe`
+    - `haxelib git thrift https://github.com/apache/thrift.git 0.14.1 lib/haxe`
 
 - To set up the current **development version**, use the `master` branch:
   
@@ -85,36 +83,25 @@
 downloads and more information can be found at http://thrift.apache.org
 	
 To get started, visit the /tutorial/haxe and /test/haxe dirs for examples. 
-If you are using HIDE or the FlashDevelop IDE, you'll find appropriate 
-project files in these folders.
+If you are using the HaxeDevelop IDE, you'll find appropriate project files 
+in these folders.
 
 
-Current status
+Breaking changes
 ========================
-- tested with Haxe C++ target
-- tested with Haxe PHP target (console/web server, binary protocols)
-- transports: Socket, HTTP (servers run inside PHP server/PHP target only), Stream
-- protocols: Binary, JSON, Multiplex, Compact
-- tutorial client and server available
-- cross-test client and server available 
+This version requires Haxe 4 and cannot be used with earlier versions.
 
+It is recommended to clear out all gen-haxe contents once before switching 
+to the new version. Otherwise you may run into troubles with leftovers from 
+previous versions.
 
-Further developments
-========================
-- improve to work with C#, Java and JavaScript Haxe/OpenFL targets
-- improve to work with more (ideally all) Haxe/OpenFL targets
-- add HTTP server, update tutorial and tests accordingly
+The compiler option ```callbacks``` is now obsolete. The compiler will always 
+generate a dual interface (i.e. with optional callback style) for use on the 
+client side, plus a new ```_service``` interface to be used for server 
+implementations. Consequentially, your client and server implementations will
+need some manual intervention.
 
 
-Known restrictions
-========================
-
-Although designed with maximum portability in mind, for technical reasons some platforms
-may only support parts of the library, or not be compatible at all.
-
-Javascript:
-- tutorial fails to build because of unsupported Sys.args
-
 PHP HTTP Server notes
 ========================
 
diff --git a/lib/haxe/haxelib.json b/lib/haxe/haxelib.json
index 1b67d82..61448da 100644
--- a/lib/haxe/haxelib.json
+++ b/lib/haxe/haxelib.json
@@ -2,11 +2,19 @@
 	"name": "thrift",
 	"url" : "http://thrift.apache.org",
 	"license": "Apache",
-	"tags": ["thrift", "rpc", "serialization", "cross", "framework"],
+	"tags": [
+		"thrift", 
+		"rpc", 
+		"serialization", 
+		"cross", 
+		"framework"
+	],
 	"description": "Haxe bindings for the Apache Thrift RPC and serialization framework",
-	"version": "0.14.2",
+	"version": "0.15.0",
 	"releasenote": "Licensed under Apache License, Version 2.0. The Apache Thrift compiler needs to be installed separately.",
 	"contributors": ["ApacheThrift"],
-	"dependencies": { },
+	"dependencies": { 
+		"crypto": ""
+	},
 	"classPath": "src"
 }
diff --git a/lib/haxe/src/org/apache/thrift/Limits.hx b/lib/haxe/src/org/apache/thrift/Limits.hx
index 44eec3a..3a7807d 100644
--- a/lib/haxe/src/org/apache/thrift/Limits.hx
+++ b/lib/haxe/src/org/apache/thrift/Limits.hx
@@ -23,9 +23,9 @@
 
     // Haxe limits are not fixed values, they depend on the target platform
     // For example, neko limits an int to 31 bits instead of 32. So we detect
-    // the values once during intialisation in order to
+    // the values once during initialization in order to
     // (a) get the right values for the current  platform, and
-    // (b) prevent us from dependecies to a bunch of defines
+    // (b) prevent us from dependencies to a bunch of defines
 
     public static var I32_MAX = {
         var last : Int = 0;
diff --git a/lib/haxe/src/org/apache/thrift/TConfiguration.hx b/lib/haxe/src/org/apache/thrift/TConfiguration.hx
new file mode 100644
index 0000000..c5ec4e5
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/TConfiguration.hx
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.thrift;
+
+class TConfiguration
+{
+	public static inline var DEFAULT_MAX_MESSAGE_SIZE = 100 * 1024 * 1024;
+	public static inline var DEFAULT_MAX_FRAME_SIZE = 16384000;      // this value is used consistently across all Thrift libraries
+	public static inline var DEFAULT_RECURSION_DEPTH = 64;
+
+	public var MaxMessageSize(default,null) : Int = DEFAULT_MAX_MESSAGE_SIZE;
+	public var MaxFrameSize(default,null) : Int = DEFAULT_MAX_FRAME_SIZE;
+	public var RecursionLimit(default,null) : Int = DEFAULT_RECURSION_DEPTH;
+
+	// TODO(JensG): add connection and i/o timeouts
+	
+	public function new() {
+		// CTOR
+	}
+}
+
diff --git a/lib/haxe/src/org/apache/thrift/TException.hx b/lib/haxe/src/org/apache/thrift/TException.hx
index 54fa1ff..8bd9fcc 100644
--- a/lib/haxe/src/org/apache/thrift/TException.hx
+++ b/lib/haxe/src/org/apache/thrift/TException.hx
@@ -32,5 +32,10 @@
         errorMsg = msg;
     }
 
+	public function toString() : String {
+		var clsname = Type.getClassName( Type.getClass(this));
+		return '${clsname}: ${errorMsg} (code ${errorID})';
+	}
+	
 }
  
\ No newline at end of file
diff --git a/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx b/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
index 8845fd0..a8e735f 100644
--- a/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
+++ b/lib/haxe/src/org/apache/thrift/helper/Int64Map.hx
@@ -137,6 +137,17 @@
         return lomap.exists( GetLowIndex(key));
     }
 
+    public function clear() : Void {
+		SubMaps.clear();
+    }
+
+    public function copy() : IMap< Int64, T> {
+		var retval = new Int64Map<T>();
+		for( key in this.keys())
+			retval.set( key, this.get(key));
+		return retval;
+    }
+
     /**
         Removes the mapping of `key` and returns true if such a mapping existed,
         false otherwise. If `key` is null, the result is unspecified.
@@ -172,6 +183,14 @@
     }
 
     /**
+        Returns an Iterator over the values of `this` Map.
+        The order of values is undefined.
+    **/
+    public function keyValueIterator() : KeyValueIterator<Int64, T> {
+        return new Int64KeyValueIterator<T>(SubMaps);
+    }
+
+    /**
         Returns a String representation of `this` Map.
         The exact representation depends on the platform and key-type.
     **/
@@ -246,7 +265,7 @@
 
 // internal helper class for Int64Map<T>
 // all class with matching methods can be used as iterator (duck typing)
-private class Int64KeyIterator<T>extends Int64MapIteratorBase<T> {
+private class Int64KeyIterator<T> extends Int64MapIteratorBase<T> {
 
     public function new( data : IntMap< IntMap< T>>) : Void {
         super(data);
@@ -270,6 +289,32 @@
 
 // internal helper class for Int64Map<T>
 // all class with matching methods can be used as iterator (duck typing)
+private class Int64KeyValueIterator<T> extends Int64MapIteratorBase<T> {
+
+    public function new( data : IntMap< IntMap< T>>) : Void {
+        super(data);
+    };
+
+    /**
+        Returns the current key/item pair and advances to the next one.
+
+        This method is not required to check hasNext() first. A call to this
+        method while hasNext() is false yields unspecified behavior.
+    **/
+    public function next() : {value:T,key:Int64} {
+        if( ! hasNext()) 
+            throw "no more elements";
+
+		return { 
+			key: Int64.make( CurrentHi, LoIterator.next()), 
+			value: SubMaps.get(CurrentHi).get(LoIterator.next())
+		};
+    }
+}
+
+
+// internal helper class for Int64Map<T>
+// all class with matching methods can be used as iterator (duck typing)
 private class Int64ValueIterator<T> extends Int64MapIteratorBase<T> {
 
     public function new( data : IntMap< IntMap< T>>) : Void {
diff --git a/lib/haxe/src/org/apache/thrift/helper/StringSet.hx b/lib/haxe/src/org/apache/thrift/helper/StringSet.hx
index d8c0d90..b47f868 100644
--- a/lib/haxe/src/org/apache/thrift/helper/StringSet.hx
+++ b/lib/haxe/src/org/apache/thrift/helper/StringSet.hx
@@ -89,7 +89,7 @@
         return ret;
     }
 
-    public function get_size() : String {
+    public function get_size() : Int {
         return _size;
     }
 }
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
index 7ef291c..736a7dc 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TBinaryProtocol.hx
@@ -31,7 +31,7 @@
 /**
 * Binary protocol implementation for thrift.
 */
-class TBinaryProtocol extends TRecursionTracker implements TProtocol {
+class TBinaryProtocol extends TProtocolImplBase implements TProtocol {
 
     private static var ANONYMOUS_STRUCT:TStruct = new TStruct();
 
@@ -40,19 +40,14 @@
 
     private var strictRead_ : Bool = false;
     private var strictWrite_ : Bool = true;
-    private var trans_ : TTransport;
 
     /**
      * Constructor
      */
-    public function new(trans:TTransport, strictRead : Bool=false, strictWrite : Bool=true) {
-      trans_ = trans;
-      strictRead_ = strictRead;
-      strictWrite_ = strictWrite;
-    }
-
-    public function getTransport():TTransport {
-      return trans_;
+    public function new(transport:TTransport, strictRead : Bool = false, strictWrite : Bool = true) {
+		super(transport);
+		strictRead_ = strictRead;
+		strictWrite_ = strictWrite;
     }
 
     public function writeMessageBegin(message:TMessage) : Void {
@@ -116,21 +111,21 @@
         var out = new BytesOutput();
         out.bigEndian = true;
         out.writeByte(b);
-        trans_.write(out.getBytes(), 0, 1);
+        Transport.write(out.getBytes(), 0, 1);
     }
 
     public function writeI16(i16 : Int) : Void {
         var out = new BytesOutput();
         out.bigEndian = true;
         out.writeInt16(i16);
-        trans_.write(out.getBytes(), 0, 2);
+        Transport.write(out.getBytes(), 0, 2);
     }
 
     public function writeI32(i32 : Int) : Void {
         var out = new BytesOutput();
         out.bigEndian = true;
         out.writeInt32(i32);
-        trans_.write(out.getBytes(), 0, 4);
+        Transport.write(out.getBytes(), 0, 4);
     }
 
     public function writeI64(i64 : haxe.Int64) : Void {
@@ -145,14 +140,14 @@
         out.writeInt32(i64.high);
         out.writeInt32(i64.low);
         #end
-        trans_.write(out.getBytes(), 0, 8);
+        Transport.write(out.getBytes(), 0, 8);
     }
 
     public function writeDouble(dub:Float) : Void {
         var out = new BytesOutput();
         out.bigEndian = true;
         out.writeDouble(dub);
-        trans_.write(out.getBytes(), 0, 8);
+        Transport.write(out.getBytes(), 0, 8);
     }
 
     public function writeString(str : String) : Void {
@@ -161,12 +156,12 @@
         out.writeString(str);
         var bytes = out.getBytes();
         writeI32( bytes.length);
-        trans_.write( bytes, 0, bytes.length);
+        Transport.write( bytes, 0, bytes.length);
     }
 
     public function writeBinary(bin:Bytes) : Void {
         writeI32(bin.length);
-        trans_.write(bin, 0, bin.length);
+        Transport.write(bin, 0, bin.length);
     }
 
     /**
@@ -210,19 +205,25 @@
     public function readFieldEnd() : Void {}
 
     public function readMapBegin() : TMap {
-        return new TMap(readByte(), readByte(), readI32());
+        var map = new TMap(readByte(), readByte(), readI32());
+		CheckReadBytesAvailableMap(map);
+        return map;
     }
 
     public function readMapEnd() : Void {}
 
     public function readListBegin():TList {
-        return new TList(readByte(), readI32());
+        var list = new TList(readByte(), readI32());
+		CheckReadBytesAvailableList(list);
+		return list;
     }
 
     public function readListEnd() : Void {}
 
     public function readSetBegin() : TSet {
-      return new TSet(readByte(), readI32());
+		var set = new TSet(readByte(), readI32());
+		CheckReadBytesAvailableSet(set);
+		return set;
     }
 
     public function readSetEnd() : Void {}
@@ -234,7 +235,7 @@
 
     public function readByte() : Int {
         var buffer = new BytesBuffer();
-        var len = trans_.readAll( buffer, 0, 1);
+        var len = Transport.readAll( buffer, 0, 1);
         var inp = new BytesInput( buffer.getBytes(), 0, 1);
         inp.bigEndian = true;
         return inp.readByte();
@@ -242,7 +243,7 @@
 
     public function readI16() : Int {
         var buffer = new BytesBuffer();
-        var len = trans_.readAll( buffer, 0, 2);
+        var len = Transport.readAll( buffer, 0, 2);
         var inp = new BytesInput( buffer.getBytes(), 0, 2);
         inp.bigEndian = true;
         return inp.readInt16();
@@ -250,7 +251,7 @@
 
     public function readI32() : Int {
         var buffer = new BytesBuffer();
-        var len = trans_.readAll( buffer, 0, 4);
+        var len = Transport.readAll( buffer, 0, 4);
         var inp = new BytesInput( buffer.getBytes(), 0, 4);
         inp.bigEndian = true;
         return inp.readInt32();
@@ -258,7 +259,7 @@
 
     public function readI64() : haxe.Int64 {
         var buffer = new BytesBuffer();
-        var len = trans_.readAll( buffer, 0, 8);
+        var len = Transport.readAll( buffer, 0, 8);
         var inp = new BytesInput( buffer.getBytes(), 0, 8);
         inp.bigEndian = true;
         var hi = inp.readInt32();
@@ -268,7 +269,7 @@
 
     public function readDouble():Float {
         var buffer = new BytesBuffer();
-        var len = trans_.readAll( buffer, 0, 8);
+        var len = Transport.readAll( buffer, 0, 8);
         var inp = new BytesInput( buffer.getBytes(), 0, 8);
         inp.bigEndian = true;
         return inp.readDouble();
@@ -279,9 +280,10 @@
     }
 
     public function readStringBody(len : Int) : String {
+		Transport.CheckReadBytesAvailable(len);
         if( len > 0) {
             var buffer = new BytesBuffer();
-            trans_.readAll( buffer, 0, len);
+            Transport.readAll( buffer, 0, len);
             var inp = new BytesInput( buffer.getBytes(), 0, len);
             inp.bigEndian = true;
             return inp.readString(len);
@@ -292,10 +294,33 @@
 
     public function readBinary() : Bytes {
         var len : Int = readI32();
-        var buffer = new BytesBuffer();
-        trans_.readAll( buffer, 0, len);
+		Transport.CheckReadBytesAvailable(len);
+		var buffer = new BytesBuffer();
+        Transport.readAll( buffer, 0, len);
         return buffer.getBytes();
     }
 
+	// Return the minimum number of bytes a type will consume on the wire
+	public override function GetMinSerializedSize(type : TType) : Int
+	{
+		switch (type)
+		{
+			case TType.STOP: return 0;
+			case TType.VOID_: return 0;
+			case TType.BOOL: return 1;
+			case TType.BYTE: return 1;
+			case TType.DOUBLE: return 8;
+			case TType.I16: return 2;
+			case TType.I32: return 4;
+			case TType.I64: return 8;
+			case TType.STRING: return 4;  // string length
+			case TType.STRUCT: return 0;  // empty struct
+			case TType.MAP: return 4;  // element count
+			case TType.SET: return 4;  // element count
+			case TType.LIST: return 4;  // element count
+			default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
+		}
+	}
+
 }
 
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx
index 03b13e2..bf7b886 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TCompactProtocol.hx
@@ -23,10 +23,10 @@
 import haxe.io.BytesInput;
 import haxe.io.BytesOutput;
 import haxe.io.BytesBuffer;
+import haxe.io.Encoding;
 import haxe.ds.GenericStack;
 import haxe.Int32;
 import haxe.Int64;
-import haxe.Utf8;
 
 import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
@@ -37,7 +37,7 @@
 /**
 * Compact protocol implementation for thrift.
 */
-class TCompactProtocol extends TRecursionTracker implements TProtocol {
+class TCompactProtocol extends TProtocolImplBase implements TProtocol {
 
     private static var ANONYMOUS_STRUCT : TStruct = new TStruct("");
     private static var TSTOP : TField = new TField("", TType.STOP, 0);
@@ -102,24 +102,11 @@
     private var boolValue_ : Null<Bool>;
 
 
-    // whether the underlying system holds Strings as UTF-8
-    // http://old.haxe.org/manual/encoding
-    private static var utf8Strings = haxe.Utf8.validate("Ç-ß-Æ-Ю-Ш");
-
-    // the transport used
-    public var trans(default,null) : TTransport;
-
-
     // TCompactProtocol Constructor
-    public function new( trans : TTransport) {
-        this.trans = trans;
+    public function new( transport : TTransport) {
+		super(transport);
     }
 
-    public function getTransport() : TTransport {
-      return trans;
-    }
-
-
     public function Reset() : Void{
         while ( ! lastField_.isEmpty()) {
             lastField_.pop();
@@ -135,7 +122,7 @@
     private function WriteByteDirect( b : Int) : Void {
         var buf = Bytes.alloc(1);
         buf.set( 0, b);
-        trans.write( buf, 0, 1);
+        Transport.write( buf, 0, 1);
     }
 
     /**
@@ -158,7 +145,7 @@
         }
 
         var tmp = i32buf.getBytes();
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
     /**
@@ -329,7 +316,7 @@
      */
     public function writeDouble( dub : Float) : Void {
         var data = BitConverter.fixedLongToBytes( BitConverter.DoubleToInt64Bits(dub));
-        trans.write( data, 0, data.length);
+        Transport.write( data, 0, data.length);
     }
 
     /**
@@ -337,10 +324,7 @@
      */
     public function writeString(str : String) : Void {
         var buf = new BytesBuffer();
-        if( utf8Strings)
-            buf.addString( str);  // no need to encode on UTF8 targets, the string is just fine
-        else
-            buf.addString( Utf8.encode( str));
+		buf.addString( str, Encoding.UTF8);
         var tmp = buf.getBytes();
         writeBinary( tmp);
     }
@@ -350,7 +334,7 @@
      */
     public function writeBinary( bin : Bytes) : Void {
         WriteVarint32( cast(bin.length,UInt));
-        trans.write( bin, 0, bin.length);
+        Transport.write( bin, 0, bin.length);
     }
 
 
@@ -408,7 +392,7 @@
             }
         }
         var tmp = varint64out.getBytes();
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
 
@@ -497,7 +481,9 @@
         var keyAndValueType : Int = ((size == 0)  ?  0  :  readByte());
         var key : Int = cast( getTType( (keyAndValueType & 0xF0) >> 4), Int);
         var val : Int = cast( getTType( keyAndValueType & 0x0F), Int);
-        return new TMap( key, val, size);
+        var map = new TMap( key, val, size);
+		CheckReadBytesAvailableMap(map);
+        return map;
     }
 
     /**
@@ -515,7 +501,9 @@
         }
 
         var type = getTType(size_and_type);
-        return new TList( type, size);
+        var list = new TList( type, size);
+		CheckReadBytesAvailableList(list);
+        return list;
     }
 
     /**
@@ -533,7 +521,9 @@
         }
 
         var type = getTType(size_and_type);
-        return new TSet( type, size);
+        var set = new TSet( type, size);
+		CheckReadBytesAvailableSet(set);
+        return set;
     }
 
     /**
@@ -556,7 +546,7 @@
      */
     public function readByte() : Int {
         var byteRawBuf = new BytesBuffer();
-        trans.readAll( byteRawBuf, 0, 1);
+        Transport.readAll( byteRawBuf, 0, 1);
         return byteRawBuf.getBytes().get(0);
     }
 
@@ -586,7 +576,7 @@
      */
     public function readDouble():Float {
         var longBits = new BytesBuffer();
-        trans.readAll( longBits, 0, 8);
+        Transport.readAll( longBits, 0, 8);
         return BitConverter.Int64BitsToDouble( BitConverter.bytesToLong( longBits.getBytes()));
     }
 
@@ -595,21 +585,19 @@
      */
     public function readString() : String {
         var length : Int = cast( ReadVarint32(), Int);
+		Transport.CheckReadBytesAvailable(length);
 
         if (length == 0) {
             return "";
         }
 
         var buf = new BytesBuffer();
-        trans.readAll( buf, 0, length);
+        Transport.readAll( buf, 0, length);
 
         length = buf.length;
         var inp = new BytesInput( buf.getBytes());
-        var str = inp.readString( length);
-        if( utf8Strings)
-            return str;  // no need to decode on UTF8 targets, the string is just fine
-        else
-            return Utf8.decode( str);
+        var str = inp.readString( length, Encoding.UTF8);
+        return str;  
     }
 
     /**
@@ -617,12 +605,13 @@
      */
     public function readBinary() : Bytes {
         var length : Int = cast( ReadVarint32(), Int);
+		Transport.CheckReadBytesAvailable(length);
         if (length == 0) {
             return Bytes.alloc(0);
         }
 
         var buf = new BytesBuffer();
-        trans.readAll( buf, 0, length);
+        Transport.readAll( buf, 0, length);
         return buf.getBytes();
     }
 
@@ -715,4 +704,27 @@
     {
         return cast( ttypeToCompactType[ttype], Int);
     }
+	
+	// Return the minimum number of bytes a type will consume on the wire
+	public override function GetMinSerializedSize(type : TType) : Int
+	{
+		switch (type)
+		{
+			case TType.STOP:    return 0;
+			case TType.VOID_:    return 0;
+			case TType.BOOL:   return 1;
+			case TType.DOUBLE: return 8;  // uses fixedLongToBytes() which always writes 8 bytes
+			case TType.BYTE: return 1;
+			case TType.I16:     return 1;  // zigzag
+			case TType.I32:     return 1;  // zigzag
+			case TType.I64:     return 1;  // zigzag
+			case TType.STRING: return 1;  // string length
+			case TType.STRUCT:  return 0;             // empty struct
+			case TType.MAP:     return 1;  // element count
+			case TType.SET:    return 1;  // element count
+			case TType.LIST:    return 1;  // element count
+			default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
+		}
+	}
+
 }
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
index e20ff33..2385ca8 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TJSONProtocol.hx
@@ -23,8 +23,8 @@
 import haxe.io.BytesInput;
 import haxe.io.BytesOutput;
 import haxe.io.BytesBuffer;
+import haxe.io.Encoding;
 import haxe.ds.GenericStack;
-import haxe.Utf8;
 import haxe.crypto.Base64;
 import haxe.Int64;
 
@@ -45,9 +45,7 @@
 *
 *  Adapted from the Java version.
 */
-class TJSONProtocol extends TRecursionTracker implements TProtocol {
-
-    public var trans(default,null) : TTransport;
+class TJSONProtocol extends TProtocolImplBase implements TProtocol {
 
     // Stack of nested contexts that we may be in
     private var contextStack : GenericStack<JSONBaseContext> = new GenericStack<JSONBaseContext>();
@@ -58,22 +56,14 @@
     // Reader that manages a 1-byte buffer
     private var reader : LookaheadReader;
 
-    // whether the underlying system holds Strings as UTF-8
-    // http://old.haxe.org/manual/encoding
-    private static var utf8Strings = haxe.Utf8.validate("Ç-ß-Æ-Ю-Ш");
-
     // TJSONProtocol Constructor
-    public function new( trans : TTransport)
+    public function new( transport : TTransport)
     {
-        this.trans = trans;
+		super(transport);
         this.context = new JSONBaseContext(this);
         this.reader = new LookaheadReader(this);
     }
 
-    public function getTransport() : TTransport {
-      return trans;
-    }
-
     public function writeMessageBegin(message:TMessage) : Void {
         WriteJSONArrayStart();
         WriteJSONInteger( JSONConstants.VERSION);
@@ -230,7 +220,8 @@
         ReadJSONObjectStart();
 
         var map = new TMap( KeyType, ValueType, Count);
-        return map;
+		CheckReadBytesAvailableMap(map);
+		return map;
     }
 
     public function readMapEnd() : Void {
@@ -244,6 +235,7 @@
         var Count : Int = ReadJSONInteger();
 
         var list = new TList( ElementType, Count);
+		CheckReadBytesAvailableList(list);
         return list;
     }
 
@@ -257,6 +249,7 @@
         var Count : Int = ReadJSONInteger();
 
         var set = new TSet( ElementType, Count);
+		CheckReadBytesAvailableSet(set);
         return set;
     }
 
@@ -313,7 +306,7 @@
         context.Write();
 
         var tmp = BytesFromString( JSONConstants.QUOTE);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
 
         for (i in 0 ... b.length) {
             var value = b.get(i);
@@ -323,11 +316,11 @@
                 if (String.fromCharCode(value) == JSONConstants.BACKSLASH.charAt(0))
                 {
                     tmp = BytesFromString( JSONConstants.BACKSLASH + JSONConstants.BACKSLASH);
-                    trans.write( tmp, 0, tmp.length);
+                    Transport.write( tmp, 0, tmp.length);
                 }
                 else
                 {
-                    trans.write( b, i, 1);
+                    Transport.write( b, i, 1);
                 }
             }
             else
@@ -335,7 +328,7 @@
                 var num = JSONConstants.JSON_CHAR_TABLE[value];
                 if (num == 1)
                 {
-                    trans.write( b, i, 1);
+                    Transport.write( b, i, 1);
                 }
                 else if (num > 1)
                 {
@@ -343,7 +336,7 @@
                     buf.addString( JSONConstants.BACKSLASH);
                     buf.addByte( num);
                     tmp = buf.getBytes();
-                    trans.write( tmp, 0, tmp.length);
+                    Transport.write( tmp, 0, tmp.length);
                 }
                 else
                 {
@@ -354,13 +347,13 @@
                     buf.addString( HexChar( (value & 0x0000FF00) >> 4));
                     buf.addString( HexChar( value & 0x000000FF));
                     tmp = buf.getBytes();
-                    trans.write( tmp, 0, tmp.length);
+                    Transport.write( tmp, 0, tmp.length);
                 }
             }
         }
 
         tmp = BytesFromString( JSONConstants.QUOTE);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
     // Write out number as a JSON value. If the context dictates so,
@@ -382,7 +375,7 @@
         }
 
         var tmp = BytesFromString( str);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
     // Write out number as a JSON value. If the context dictates so,
@@ -404,7 +397,7 @@
         }
 
         var tmp = BytesFromString( str);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
     // Write out a double as a JSON value. If it is NaN or infinity or if the
@@ -441,7 +434,7 @@
         }
 
         var tmp = BytesFromString( str);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
     // Write out contents of byte array b as a JSON string with base-64 encoded data
@@ -454,33 +447,33 @@
         buf.addString( JSONConstants.QUOTE);
 
         var tmp = buf.getBytes();
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
     private function WriteJSONObjectStart() : Void {
         context.Write();
         var tmp = BytesFromString( JSONConstants.LBRACE);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
         PushContext( new JSONPairContext(this));
     }
 
     private function WriteJSONObjectEnd() : Void {
         PopContext();
         var tmp = BytesFromString( JSONConstants.RBRACE);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
     private function WriteJSONArrayStart() : Void {
         context.Write();
         var tmp = BytesFromString( JSONConstants.LBRACKET);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
         PushContext( new JSONListContext(this));
     }
 
     private function WriteJSONArrayEnd() : Void {
         PopContext();
         var tmp = BytesFromString( JSONConstants.RBRACKET);
-        trans.write( tmp, 0, tmp.length);
+        Transport.write( tmp, 0, tmp.length);
     }
 
 
@@ -545,7 +538,7 @@
 
             // it's \uXXXX
             var hexbuf = new BytesBuffer();
-            var hexlen = trans.readAll( hexbuf, 0, 4);
+            var hexlen = Transport.readAll( hexbuf, 0, 4);
             if( hexlen != 4)
             {
                 throw new TProtocolException( TProtocolException.INVALID_DATA, "Not enough data for \\uNNNN sequence");
@@ -756,10 +749,7 @@
 
     public static function BytesFromString( str : String) : Bytes {
         var buf = new BytesBuffer();
-        if( utf8Strings)
-            buf.addString( str);  // no need to encode on UTF8 targets, the string is just fine
-        else
-            buf.addString( Utf8.encode( str));
+        buf.addString( str, Encoding.UTF8);
         return buf.getBytes();
     }
 
@@ -767,11 +757,7 @@
         var inp = new BytesInput( buf);
         if( buf.length == 0)
             return "";  // readString() would return null in that case, which is wrong
-        var str = inp.readString( buf.length);
-        if( utf8Strings)
-            return str;  // no need to decode on UTF8 targets, the string is just fine
-        else
-            return Utf8.decode( str);
+        return inp.readString( buf.length, Encoding.UTF8);
     }
 
     // Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its corresponding hex value
@@ -790,6 +776,28 @@
     }
 
 
+	// Return the minimum number of bytes a type will consume on the wire
+	public override function GetMinSerializedSize(type : TType) : Int
+	{
+		switch (type)
+		{
+			case TType.STOP: return 0;
+			case TType.VOID_: return 0;
+			case TType.BOOL: return 1;  // written as int  
+			case TType.BYTE: return 1;
+			case TType.DOUBLE: return 1;
+			case TType.I16: return 1;
+			case TType.I32: return 1;
+			case TType.I64: return 1;
+			case TType.STRING: return 2;  // empty string
+			case TType.STRUCT: return 2;  // empty struct
+			case TType.MAP: return 2;  // empty map
+			case TType.SET: return 2;  // empty set
+			case TType.LIST: return 2;  // empty list
+			default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
+		}
+	}
+
 }
 
 
@@ -971,7 +979,7 @@
             var buf = new BytesBuffer();
             buf.addString( JSONConstants.COMMA);
             var tmp = buf.getBytes();
-            proto.trans.write( tmp, 0, tmp.length);
+            proto.Transport.write( tmp, 0, tmp.length);
         }
     }
 
@@ -1014,7 +1022,7 @@
             var buf = new BytesBuffer();
             buf.addString( colon ? JSONConstants.COLON : JSONConstants.COMMA);
             var tmp = buf.getBytes();
-            proto.trans.write( tmp, 0, tmp.length);
+            proto.Transport.write( tmp, 0, tmp.length);
             colon = !colon;
         }
     }
@@ -1064,7 +1072,7 @@
     public function Peek() : Bytes {
         if (data == null) {
             var buf = new BytesBuffer();
-            proto.trans.readAll(buf, 0, 1);
+            proto.Transport.readAll(buf, 0, 1);
             data = buf.getBytes();
         }
         return data;
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx b/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
index b7f3842..316067a 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TProtocol.hx
@@ -82,4 +82,7 @@
     // recursion tracking
     function IncrementRecursionDepth() : Void;
     function DecrementRecursionDepth() : Void;
+	
+	// message size
+	function GetMinSerializedSize(type : TType) : Int;
 }
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx b/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
index 769e93c..011f42b 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TProtocolDecorator.hx
@@ -223,4 +223,10 @@
     public function DecrementRecursionDepth() : Void {
         return wrapped.DecrementRecursionDepth();
     }
+	
+	// Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
+	public function GetMinSerializedSize(type : TType) : Int
+	{
+		return wrapped.GetMinSerializedSize(type);
+	}
 }
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TProtocolImplBase.hx b/lib/haxe/src/org/apache/thrift/protocol/TProtocolImplBase.hx
new file mode 100644
index 0000000..60e4a1f
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/protocol/TProtocolImplBase.hx
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.thrift.protocol;
+
+import org.apache.thrift.*;
+import org.apache.thrift.transport.TTransport;
+
+
+class TProtocolImplBase {
+
+	private var Configuration : TConfiguration;
+    public var Transport(default,null) : TTransport;
+	
+	public function new( transport : TTransport)
+	{
+		Transport = transport;
+		Configuration = (transport.Configuration != null) ? transport.Configuration : new TConfiguration();
+	}
+
+	
+    public function getTransport() : TTransport {
+		return Transport;
+    }
+
+	
+    // limit and actual value
+    public var recursionLimit(get,never) : Int;
+    private var recursionDepth : Int = 0;
+
+    public function get_recursionLimit() : Int
+	{
+		return Configuration.RecursionLimit;
+	}
+	
+	
+    public function IncrementRecursionDepth() : Void
+    {
+        if (recursionDepth < recursionLimit)
+            ++recursionDepth;
+        else
+            throw new TProtocolException(TProtocolException.DEPTH_LIMIT, "Depth limit exceeded");
+    }
+
+    public function DecrementRecursionDepth() : Void
+    {
+        --recursionDepth;
+    }
+
+
+	private function CheckReadBytesAvailableSet(set : TSet) : Void
+	{
+		Transport.CheckReadBytesAvailable(set.size * GetMinSerializedSize(set.elemType));
+	}
+
+	private function CheckReadBytesAvailableList(list : TList) : Void
+	{
+		Transport.CheckReadBytesAvailable(list.size * GetMinSerializedSize(list.elemType));
+	}
+
+	private function CheckReadBytesAvailableMap (map : TMap) : Void
+	{
+		var elmSize = GetMinSerializedSize(map.keyType) + GetMinSerializedSize(map.valueType);
+		Transport.CheckReadBytesAvailable(map.size * elmSize);
+	}
+
+	// Returns the minimum amount of bytes needed to store the smallest possible instance of TType.
+	public function GetMinSerializedSize(type : TType) : Int throw "abstract method called";
+
+}
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TRecursionTracker.hx b/lib/haxe/src/org/apache/thrift/protocol/TRecursionTracker.hx
deleted file mode 100644
index cf0211b..0000000
--- a/lib/haxe/src/org/apache/thrift/protocol/TRecursionTracker.hx
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.thrift.protocol;
-
-import org.apache.thrift.*;
-
-
-class TRecursionTracker {
-
-    // default
-    private static inline var DEFAULT_RECURSION_DEPTH : Int = 64;
-
-    // limit and actual value
-    public var recursionLimit : Int = DEFAULT_RECURSION_DEPTH;
-    private var recursionDepth : Int = 0;
-
-    public function IncrementRecursionDepth() : Void
-    {
-        if (recursionDepth < recursionLimit)
-            ++recursionDepth;
-        else
-            throw new TProtocolException(TProtocolException.DEPTH_LIMIT, "Depth limit exceeded");
-    }
-
-    public function DecrementRecursionDepth() : Void
-    {
-        --recursionDepth;
-    }
-
-
-}
diff --git a/lib/haxe/src/org/apache/thrift/protocol/TType.hx b/lib/haxe/src/org/apache/thrift/protocol/TType.hx
index 6abbc96..964b26e 100644
--- a/lib/haxe/src/org/apache/thrift/protocol/TType.hx
+++ b/lib/haxe/src/org/apache/thrift/protocol/TType.hx
@@ -22,7 +22,7 @@
 @:enum
 abstract TType(Int)  from Int to Int  {
     public static inline var STOP : Int   = 0;
-    public static inline var VOID : Int   = 1;
+    public static inline var VOID_ : Int  = 1;  // VOID produces collisions with cpp targets in some cases
     public static inline var BOOL : Int   = 2;
     public static inline var BYTE : Int   = 3;
     public static inline var DOUBLE : Int = 4;
diff --git a/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx
index 4b33fcf..72ce921 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TBufferedTransport.hx
@@ -21,6 +21,7 @@
 
 import org.apache.thrift.transport.*;
 
+import haxe.Int64;
 import haxe.io.Eof;
 import haxe.io.Bytes;
 import haxe.io.BytesBuffer;
@@ -28,16 +29,13 @@
 import haxe.io.BytesInput;
 
 
-class TBufferedTransport extends TTransport
+class TBufferedTransport extends TLayeredTransport
 {
     // constants
     public static inline var DEFAULT_BUFSIZE : Int = 0x1000;    // 4096 Bytes
     public static inline var MIN_BUFSIZE : Int = 0x100;         // 256 Bytes
     public static inline var MAX_BUFSIZE : Int = 0x100000;      // 1 MB
 
-    // Underlying transport
-    public var transport(default,null) :  TTransport = null;
-
     // Buffer for input/output
     private var readBuffer_ : BytesInput = null;
     private var writeBuffer_ : BytesOutput = null;
@@ -45,6 +43,7 @@
 
     // Constructor wraps around another transport
     public function new( transport : TTransport, bufSize : Int = DEFAULT_BUFSIZE) {
+		super(transport);
 
         // ensure buffer size is in the range
         if ( bufSize < MIN_BUFSIZE)
@@ -52,22 +51,21 @@
         else if( bufSize > MAX_BUFSIZE)
             bufSize = MAX_BUFSIZE;
 
-        this.transport = transport;
         this.bufSize = bufSize;
         this.writeBuffer_ = new BytesOutput();
         this.writeBuffer_.bigEndian = true;
     }
 
     public override function open() : Void {
-        transport.open();
+        InnerTransport.open();
     }
 
     public override function isOpen() : Bool {
-        return transport.isOpen();
+        return InnerTransport.isOpen();
     }
 
     public override function close() : Void {
-        transport.close();
+        InnerTransport.close();
     }
 
     public override function read(buf : BytesBuffer, off : Int, len : Int) : Int {
@@ -86,7 +84,7 @@
                 // there is no point in buffering whenever the
                 // remaining length exceeds the buffer size
                 if ( len >= bufSize) {
-                    var got = transport.read( buf, off, len);
+                    var got = InnerTransport.read( buf, off, len);
                     if (got > 0) {
                         buf.addBytes(data, 0, got);
                         return got;
@@ -109,7 +107,7 @@
         var size = bufSize;
         try {
             var buffer = new BytesBuffer();
-            size = transport.read( buffer, 0, size);
+            size = InnerTransport.read( buffer, 0, size);
             readBuffer_ = new BytesInput( buffer.getBytes(), 0, size);
             readBuffer_.bigEndian = true;
             return size;
@@ -125,7 +123,7 @@
                 var buf = writeBuffer_.getBytes();
                 writeBuffer_ = new BytesOutput();
                 writeBuffer_.bigEndian = true;
-                transport.write(buf, 0, buf.length);
+                InnerTransport.write(buf, 0, buf.length);
             }
         }
     }
@@ -141,7 +139,7 @@
         var write_thru : Bool = exceeds_buf && (writeBuffer_.length >= halfSize);
         if ( write_thru) {
             writeChunk(true); // force send whatever we have in there
-            transport.write(buf, off, len);  // write thru
+            InnerTransport.write(buf, off, len);  // write thru
         } else {
             writeBuffer_.writeBytes(buf, off, len);
             writeChunk(false);
@@ -150,6 +148,18 @@
 
     public override function flush( callback : Dynamic->Void =null) : Void {
         writeChunk(true);
-        transport.flush(callback);
+        InnerTransport.flush(callback);
     }
+	
+	public override function CheckReadBytesAvailable(numBytes : Int64) : Void
+	{
+		var buffered = readBuffer_.length - readBuffer_.position;
+		if (buffered < numBytes)
+		{
+			numBytes -= buffered;
+			InnerTransport.CheckReadBytesAvailable(numBytes);
+		}
+	}
+	
+	
 }
diff --git a/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx b/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx
index 539e720..11d1a72 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TBufferedTransportFactory.hx
@@ -27,7 +27,7 @@
     private var bufSize : Int;
 
     public function new(bufSize : Int = TBufferedTransport.DEFAULT_BUFSIZE) {
-        super();
+		super();
         this.bufSize = bufSize;
     }
 
diff --git a/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx
new file mode 100644
index 0000000..8c0d3ef
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/transport/TEndpointTransport.hx
@@ -0,0 +1,95 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.thrift.transport;
+
+import haxe.Int64;
+import org.apache.thrift.TConfiguration;
+
+class TEndpointTransport extends TTransport
+{
+	private var MaxMessageSize(get, never) : Int64;
+	private var KnownMessageSize(default, null) : Int64 ;
+	private var RemainingMessageSize(default, null) : Int64 ;
+
+	private var _configuration(default,null) : TConfiguration;
+	
+	public override function get_Configuration() : TConfiguration {
+		return _configuration;
+	}
+	
+	private function get_MaxMessageSize() : Int64 {
+		return Configuration.MaxMessageSize; 
+	}
+	
+	
+	// private CTOR to prevent direct instantiation
+	// in other words, this class MUST be extended
+	private function new( config : TConfiguration)
+	{
+		_configuration = (config != null) ? config : new TConfiguration();
+		ResetConsumedMessageSize();
+	}
+
+	// Resets RemainingMessageSize to the configured maximum 
+	private function ResetConsumedMessageSize(?newSize : Int64) : Void
+	{
+		// full reset 
+		if (newSize == null)
+		{
+			KnownMessageSize = MaxMessageSize;
+			RemainingMessageSize = MaxMessageSize;
+			return;
+		}
+
+		// update only: message size can shrink, but not grow
+		if (newSize > KnownMessageSize)
+			throw new TTransportException(TTransportException.END_OF_FILE, "ResetConsumedMessageSize: MaxMessageSize reached");
+
+		KnownMessageSize = newSize;
+		RemainingMessageSize = newSize;
+	}
+
+	// Updates RemainingMessageSize to reflect then known real message size (e.g. framed transport).
+	// Will throw if we already consumed too many bytes or if the new size is larger than allowed.
+	public override function UpdateKnownMessageSize(size : Int64) : Void
+	{
+		var consumed = KnownMessageSize - RemainingMessageSize;
+		ResetConsumedMessageSize(size);
+		CountConsumedMessageBytes(consumed);
+	}
+
+	// Throws if there are not enough bytes in the input stream to satisfy a read of numBytes bytes of data
+	public override function CheckReadBytesAvailable(numBytes : Int64) : Void
+	{
+		if (RemainingMessageSize < numBytes)
+			throw new TTransportException(TTransportException.END_OF_FILE, 'CheckReadBytesAvailable(${numBytes}): MaxMessageSize reached, only ${RemainingMessageSize} bytes available');
+	}
+
+	// Consumes numBytes from the RemainingMessageSize.
+	private function CountConsumedMessageBytes(numBytes : Int64) : Void
+	{
+		if (RemainingMessageSize >= numBytes)
+		{
+			RemainingMessageSize -= numBytes;
+		}
+		else
+		{
+			RemainingMessageSize = 0;
+			throw new TTransportException(TTransportException.END_OF_FILE, 'CountConsumedMessageBytes(${numBytes}): MaxMessageSize reached');
+		}
+	}
+}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx
index cef82ef..37e4959 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TFramedTransport.hx
@@ -21,6 +21,7 @@
 
 import org.apache.thrift.transport.*;
 
+import haxe.Int64;
 import haxe.io.Eof;
 import haxe.io.Bytes;
 import haxe.io.BytesBuffer;
@@ -32,16 +33,9 @@
  * TFramedTransport is a buffered TTransport that ensures a fully read message
  * every time by preceding messages with a 4-byte frame size.
  */
-class TFramedTransport extends TTransport
+class TFramedTransport extends TLayeredTransport
 {
-    public static inline var DEFAULT_MAX_LENGTH = 16384000;
-
-    var maxLength_ :  Int;
-
-    /**
-     * Underlying transport
-     */
-    var transport_ :  TTransport = null;
+	private static inline var HEADER_SIZE = 4;
 
     /**
      * Buffer for output
@@ -56,21 +50,20 @@
     /**
      * Constructor wraps around another transport
      */
-    public function new( transport : TTransport, maxLength : Int = DEFAULT_MAX_LENGTH) {
-        transport_ = transport;
-        maxLength_ = maxLength;
+    public function new( transport : TTransport) {
+		super(transport);
     }
 
     public override function open() : Void {
-        transport_.open();
+        InnerTransport.open();
     }
 
     public override function isOpen() : Bool {
-        return transport_.isOpen();
+        return InnerTransport.isOpen();
     }
 
     public override function close() : Void {
-        transport_.close();
+        InnerTransport.close();
     }
 
     public override function read(buf : BytesBuffer, off : Int, len : Int) : Int {
@@ -101,13 +94,13 @@
     function readFrameSize() : Int {
         try {
             var buffer = new BytesBuffer();
-            var len = transport_.readAll( buffer, 0, 4);
-            var inp = new BytesInput( buffer.getBytes(), 0, 4);
+            var len = InnerTransport.readAll( buffer, 0, HEADER_SIZE);
+            var inp = new BytesInput( buffer.getBytes(), 0, HEADER_SIZE);
             inp.bigEndian = true;
             return inp.readInt32();
         }
         catch(eof : Eof) {
-            throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read 4 bytes!');
+            throw new TTransportException(TTransportException.END_OF_FILE, 'Can\'t read ${HEADER_SIZE} bytes!');
         }
     }
 
@@ -118,13 +111,14 @@
         if (size < 0) {
             throw new TTransportException(TTransportException.UNKNOWN, 'Read a negative frame size ($size)!');
         };
-        if (size > maxLength_) {
-            throw new TTransportException(TTransportException.UNKNOWN, 'Frame size ($size) larger than max length ($maxLength_)!');
+        if (size > Configuration.MaxFrameSize) {
+            throw new TTransportException(TTransportException.UNKNOWN, 'Frame size ($size) larger than max length ($Configuration.MaxFrameSize)!');
         };
 
+		UpdateKnownMessageSize(size + HEADER_SIZE);
         try {
             var buffer = new BytesBuffer();
-            size = transport_.readAll( buffer, 0, size);
+            size = InnerTransport.readAll( buffer, 0, size);
             readBuffer_ = new BytesInput( buffer.getBytes(), 0, size);
             readBuffer_.bigEndian = true;
         }
@@ -141,18 +135,31 @@
         var out = new BytesOutput();
         out.bigEndian = true;
         out.writeInt32(len);
-        transport_.write(out.getBytes(), 0, 4);
+        InnerTransport.write(out.getBytes(), 0, HEADER_SIZE);
     }
 
     public override function flush( callback : Dynamic->Void =null) : Void {
         var buf : Bytes = writeBuffer_.getBytes();
         var len : Int = buf.length;
         writeBuffer_ = new BytesOutput();
+		readBuffer_ = null;
 
         writeFrameSize(len);
-        transport_.write(buf, 0, len);
-        transport_.flush(callback);
+        InnerTransport.write(buf, 0, len);
+        InnerTransport.flush(callback);
     }
+	
+	
+	public override function CheckReadBytesAvailable(numBytes : Int64) : Void
+	{
+		var buffered = readBuffer_.length - readBuffer_.position;
+		if (buffered < numBytes)
+		{
+			numBytes -= buffered;
+			InnerTransport.CheckReadBytesAvailable(numBytes);
+		}
+	}
+	
 }
 
 
diff --git a/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx b/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx
index 8d45a64..ca04e7f 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TFramedTransportFactory.hx
@@ -19,19 +19,17 @@
 
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
 import org.apache.thrift.transport.*;
 
 
 class TFramedTransportFactory extends TTransportFactory {
 
-    var maxLength_ : Int;
-
-    public function new(maxLength : Int = TFramedTransport.DEFAULT_MAX_LENGTH) {
-        super();
-        maxLength_ = maxLength;
+    public function new() {
+		super();
     }
 
     public override function getTransport(base : TTransport) : TTransport {
-        return new TFramedTransport(base, maxLength_);
+        return new TFramedTransport(base);
     }
 }
diff --git a/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx b/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx
index 1972853..cc34ec4 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TFullDuplexHttpClient.hx
@@ -41,213 +41,217 @@
      * Unlike Http Client, it uses a single POST, and chunk-encoding to transfer all messages.
      */
 
-    public class TFullDuplexHttpClient extends TTransport
-    {
-        private var socket : Socket = null;
-        private var host  :  String;
-        private var port  :  Int;
-        private var resource  :  String;
-        private var stripped  :  Bool = false;
-        private var obuffer : Bytes = new Bytes();
-        private var input : IDataInput;
-        private var output : IDataOutput;
-        private var bytesInChunk  :  Int = 0;
-        private var CRLF : Bytes = new Bytes();
-        private var ioCallback : TException->Void = null;
-        private var eventDispatcher : EventDispatcher = new EventDispatcher();
+public class TFullDuplexHttpClient extends TEndpointTransport
+{
+	private var socket : Socket = null;
+	private var host  :  String;
+	private var port  :  Int;
+	private var resource  :  String;
+	private var stripped  :  Bool = false;
+	private var obuffer : Bytes = new Bytes();
+	private var input : IDataInput;
+	private var output : IDataOutput;
+	private var bytesInChunk  :  Int = 0;
+	private var CRLF : Bytes = new Bytes();
+	private var ioCallback : TException->Void = null;
+	private var eventDispatcher : EventDispatcher = new EventDispatcher();
 
-        public function new(host  :  String, port  :  Int, resource  :  String)  :  Void
-        {
-            CRLF.writeByte(13);
-            CRLF.writeByte(10);
-            this.host = host;
-            this.port = port;
-            this.resource = resource;
-        }
+	public function new(host  :  String, port  :  Int, resource  :  String, config : TConfiguration = null)  :  Void
+	{
+		super(config);		
+		CRLF.writeByte(13);
+		CRLF.writeByte(10);
+		this.host = host;
+		this.port = port;
+		this.resource = resource;
+	}
 
-        public override function close()  :  Void
-        {
-            this.input = null;
-            this.output = null;
-            this.stripped = false;
-            socket.close()
-        }
+	public override function close()  :  Void
+	{
+		this.input = null;
+		this.output = null;
+		this.stripped = false;
+		socket.close();
+		ResetConsumedMessageSize();
+	}
 
-        public override function peek()  :  Bool
-        {
-            if(socket.connected)
-            {
-                trace("Bytes remained:" + socket.bytesAvailable);
-                return socket.bytesAvailable>0;
-            }
-            return false;
-        }
+	public override function peek()  :  Bool
+	{
+		if(socket.connected)
+		{
+			trace("Bytes remaining:" + socket.bytesAvailable);
+			return socket.bytesAvailable>0;
+		}
+		return false;
+	}
 
-        public override function read(buf : Bytes, off  :  Int, len  :  Int)  :  Int
-        {
-            var n1  :  Int = 0, n2  :  Int = 0, n3  :  Int = 0, n4  :  Int = 0, cidx  :  Int = 2;
-            var chunkSize : Bytes = new Bytes();
+	public override function read(buf : Bytes, off  :  Int, len  :  Int)  :  Int
+	{
+		var n1  :  Int = 0, n2  :  Int = 0, n3  :  Int = 0, n4  :  Int = 0, cidx  :  Int = 2;
+		var chunkSize : Bytes = new Bytes();
 
-            try
-            {
-                while (!stripped)
-                {
-                    n1 = n2;
-                    n2 = n3;
-                    n3 = n4;
-                    n4 = input.readByte();
-                    if ((n1 == 13) && (n2 == 10) && (n3 == 13) && (n4 == 10))
-                    {
-                        stripped = true;
-                    }
-                }
+		try
+		{
+			while (!stripped)
+			{
+				n1 = n2;
+				n2 = n3;
+				n3 = n4;
+				n4 = input.readByte();
+				if ((n1 == 13) && (n2 == 10) && (n3 == 13) && (n4 == 10))
+				{
+					stripped = true;
+				}
+			}
 
-                // read chunk size
-                if (bytesInChunk == 0)
-                {
-                    n1 = input.readByte();
-                    n2 = input.readByte();
+			// read chunk size
+			if (bytesInChunk == 0)
+			{
+				n1 = input.readByte();
+				n2 = input.readByte();
 
-                    chunkSize.writeByte(n1);
-                    chunkSize.writeByte(n2);
+				chunkSize.writeByte(n1);
+				chunkSize.writeByte(n2);
 
-                    while (!((n1 == 13) && (n2 == 10)))
-                    {
-                        n1 = n2;
-                        n2 = input.readByte();
-                        chunkSize.writeByte(n2);
-                    }
+				while (!((n1 == 13) && (n2 == 10)))
+				{
+					n1 = n2;
+					n2 = input.readByte();
+					chunkSize.writeByte(n2);
+				}
 
-                    bytesInChunk = parseInt(chunkSize.toString(), 16);
-                }
+				bytesInChunk = parseInt(chunkSize.toString(), 16);
+			}
 
-                input.readBytes(buf, off, len);
-                debugBuffer(buf);
-                bytesInChunk -= len;
+			input.readBytes(buf, off, len);
+			debugBuffer(buf);
+			bytesInChunk -= len;
 
-                if (bytesInChunk == 0)
-                {
-                    // advance the  :  "\r\n"
-                    input.readUTFBytes(2);
-                }
-                return len;
-            }
-            catch (e : EOFError)
-            {
-                trace(e);
-                throw new TTransportException(TTransportException.UNKNOWN, "No more data available.");
-            }
-            catch (e : TException)
-            {
-                trace('TException $e');
-                throw e;
-            }
-            catch (e : Error)
-            {
-                trace(e);
-                throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e');
-            }
-            catch (e : Dynamic)
-            {
-                trace(e);
-                throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e');
-            }
-            return 0;
-        }
+			if (bytesInChunk == 0)
+			{
+				// advance the  :  "\r\n"
+				input.readUTFBytes(2);
+			}
+			
+			CountConsumedMessageBytes(len);
+			return len;
+		}
+		catch (e : EOFError)
+		{
+			trace(e);
+			throw new TTransportException(TTransportException.UNKNOWN, "No more data available.");
+		}
+		catch (e : TException)
+		{
+			trace('TException $e');
+			throw e;
+		}
+		catch (e : Error)
+		{
+			trace(e);
+			throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e');
+		}
+		catch (e : Dynamic)
+		{
+			trace(e);
+			throw new TTransportException(TTransportException.UNKNOWN, 'Bad IO error: $e');
+		}
+		return 0;
+	}
 
-        public function debugBuffer(buf : Bytes)  :  Void
-        {
-            var debug  :  String = "BUFFER >>";
-            var i  :  Int;
-            for (i = 0; i < buf.length; i++)
-            {
-                debug += buf[i] as int;
-                debug += " ";
-            }
+	public function debugBuffer(buf : Bytes)  :  Void
+	{
+		var debug  :  String = "BUFFER >>";
+		var i  :  Int;
+		for (i = 0; i < buf.length; i++)
+		{
+			debug += buf[i] as int;
+			debug += " ";
+		}
 
-            trace(debug + "<<");
-        }
+		trace(debug + "<<");
+	}
 
-        public override function write(buf : Bytes, off  :  Int, len  :  Int)  :  Void
-        {
-            obuffer.writeBytes(buf, off, len);
-        }
+	public override function write(buf : Bytes, off  :  Int, len  :  Int)  :  Void
+	{
+		obuffer.writeBytes(buf, off, len);
+	}
 
-        public function addEventListener(type  :  String, listener : Function, useCapture  :  Bool = false, priority  :  Int = 0, useWeakReference  :  Bool = false)  :  Void
-        {
-            this.eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
-        }
+	public function addEventListener(type  :  String, listener : Function, useCapture  :  Bool = false, priority  :  Int = 0, useWeakReference  :  Bool = false)  :  Void
+	{
+		this.eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);
+	}
 
-        public override function open()  :  Void
-        {
-            this.socket = new Socket();
-            this.socket.addEventListener(Event.CONNECT, socketConnected);
-            this.socket.addEventListener(IOErrorEvent.IO_ERROR, socketError);
-            this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socketSecurityError);
-            this.socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
-            this.socket.connect(host, port);
-        }
+	public override function open()  :  Void
+	{
+		this.socket = new Socket();
+		this.socket.addEventListener(Event.CONNECT, socketConnected);
+		this.socket.addEventListener(IOErrorEvent.IO_ERROR, socketError);
+		this.socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socketSecurityError);
+		this.socket.addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
+		this.socket.connect(host, port);
+		ResetConsumedMessageSize();
+	}
 
-        public function socketConnected(event : Event)  :  Void
-        {
-            this.output = this.socket;
-            this.input = this.socket;
-            this.output.writeUTF( "CONNECT " + resource + " HTTP/1.1\n"
-                                + "Host :  " + host + ":" + port + "\r\n"
-                                + "User-Agent :  Thrift/Haxe\r\n"
-                                + "Transfer-Encoding :  chunked\r\n"
-                                + "content-type :  application/x-thrift\r\n"
-                                + "Accept :  */*\r\n"
-                                + "\r\n");
-            this.eventDispatcher.dispatchEvent(event);
-        }
+	public function socketConnected(event : Event)  :  Void
+	{
+		this.output = this.socket;
+		this.input = this.socket;
+		this.output.writeUTF( "CONNECT " + resource + " HTTP/1.1\n"
+							+ "Host :  " + host + ":" + port + "\r\n"
+							+ "User-Agent :  Thrift/Haxe\r\n"
+							+ "Transfer-Encoding :  chunked\r\n"
+							+ "Content-Type :  application/x-thrift\r\n"
+							+ "Accept :  */*\r\n"
+							+ "\r\n");
+		this.eventDispatcher.dispatchEvent(event);
+	}
 
-        public function socketError(event : IOErrorEvent)  :  Void
-        {
-            trace("Error Connecting:" + event);
-            this.close();
-            if (ioCallback == null)
-            {
-                return;
-            }
-            ioCallback(new TTransportException(TTransportException.UNKNOWN, "IOError :  " + event.text));
-            this.eventDispatcher.dispatchEvent(event);
-        }
+	public function socketError(event : IOErrorEvent)  :  Void
+	{
+		trace("Error Connecting:" + event);
+		this.close();
+		if (ioCallback == null)
+		{
+			return;
+		}
+		ioCallback(new TTransportException(TTransportException.UNKNOWN, "IOError :  " + event.text));
+		this.eventDispatcher.dispatchEvent(event);
+	}
 
-        public function socketSecurityError(event : SecurityErrorEvent)  :  Void
-        {
-            trace("Security Error Connecting:" + event);
-            this.close();
-            this.eventDispatcher.dispatchEvent(event);
-        }
+	public function socketSecurityError(event : SecurityErrorEvent)  :  Void
+	{
+		trace("Security Error Connecting:" + event);
+		this.close();
+		this.eventDispatcher.dispatchEvent(event);
+	}
 
-        public function socketDataHandler(event : ProgressEvent)  :  Void
-        {
-            trace("Got Data call:" +ioCallback);
-            if (ioCallback != null)
-            {
-                ioCallback(null);
-            };
-            this.eventDispatcher.dispatchEvent(event);
-        }
+	public function socketDataHandler(event : ProgressEvent)  :  Void
+	{
+		trace("Got Data call:" +ioCallback);
+		if (ioCallback != null)
+		{
+			ioCallback(null);
+		};
+		this.eventDispatcher.dispatchEvent(event);
+	}
 
-        public override function flush(callback : Error->Void = null)  :  Void
-        {
-            trace("set callback:" + callback);
-            this.ioCallback = callback;
-            this.output.writeUTF(this.obuffer.length.toString(16));
-            this.output.writeBytes(CRLF);
-            this.output.writeBytes(this.obuffer);
-            this.output.writeBytes(CRLF);
-            this.socket.flush();
-            // waiting for  new Flex sdk 3.5
-            //this.obuffer.clear();
-            this.obuffer = new Bytes();
-        }
+	public override function flush(callback : Error->Void = null)  :  Void
+	{
+		trace("set callback:" + callback);
+		this.ioCallback = callback;
+		this.output.writeUTF(this.obuffer.length.toString(16));
+		this.output.writeBytes(CRLF);
+		this.output.writeBytes(this.obuffer);
+		this.output.writeBytes(CRLF);
+		this.socket.flush();
+		this.obuffer = new Bytes();
+		ResetConsumedMessageSize();
+	}
 
-        public override function isOpen()  :  Bool
-        {
-            return (this.socket == null ? false  :  this.socket.connected);
-        }
+	public override function isOpen()  :  Bool
+	{
+		return (this.socket != null) && this.socket.connected;
+	}
 
 }
\ No newline at end of file
diff --git a/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx b/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx
index 79f8661..703dd81 100644
--- a/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/THttpClient.hx
@@ -20,6 +20,7 @@
 package org.apache.thrift.transport;
 
 
+import haxe.Timer;
 import haxe.io.Bytes;
 import haxe.io.BytesBuffer;
 import haxe.io.BytesOutput;
@@ -27,6 +28,9 @@
 
 import haxe.Http;
 
+#if js
+import js.lib.Promise;
+#end
 
 
 /**
@@ -34,7 +38,7 @@
 * Thrift web services implementation.
 */
 
-class THttpClient extends TTransport {
+class THttpClient extends TEndpointTransport {
 
     private var requestBuffer_  : BytesOutput = new BytesOutput();
     private var responseBuffer_ : BytesInput = null;
@@ -42,20 +46,23 @@
     private var request_        : Http = null;
 
 
-    public function new( requestUrl : String) : Void {
-          request_ = new Http(requestUrl);
-        request_.addHeader( "contentType", "application/x-thrift");
+    public function new( requestUrl : String, config : TConfiguration = null) : Void {
+		super(config);
+		
+		request_ = new Http(requestUrl);
+        request_.addHeader( "Content-Type", "application/x-thrift");
     }
 
 
     public override function open() : Void {
+		ResetConsumedMessageSize();
     }
 
     public override function close() : Void {
     }
 
     public override function isOpen() : Bool {
-      return true;
+		return true;
     }
 
     public override function read(buf:BytesBuffer, off : Int, len : Int) : Int {
@@ -66,6 +73,7 @@
         var data =Bytes.alloc(len);
         len = responseBuffer_.readBytes(data, off, len);
         buf.addBytes(data,0,len);
+        CountConsumedMessageBytes(len);
         return len;
     }
 
@@ -78,24 +86,36 @@
         var buffer = requestBuffer_;
         requestBuffer_ = new BytesOutput();
         responseBuffer_ = null;
+		ResetConsumedMessageSize();
 
+		/*
         request_.onData = function(data : String) {
-            var tmp = new BytesBuffer();
-            tmp.addString(data);
-            responseBuffer_ = new BytesInput(tmp.getBytes());
-            if( callback != null) {
-                callback(null);
-            }
+			var tmp = new BytesBuffer();
+			tmp.addString(data);
+			responseBuffer_ = new BytesInput(tmp.getBytes());
+			if( callback != null) {
+				callback(null);
         };
+		*/
 
-        request_.onError = function(msg : String) {
-            if( callback != null) {
-                callback(new TTransportException(TTransportException.UNKNOWN, "IOError: " + msg));
-            }
-        };
+		request_.onBytes = function(data : Bytes) {
+			responseBuffer_ = new BytesInput(data);
+			if( callback != null) {
+				callback(null);
+			}
+		};
 
-        request_.setPostData(buffer.getBytes().toString());
-        request_.request(true/*POST*/);
+		request_.onError = function(msg : String) {
+			if( callback != null) {
+				callback(new TTransportException(TTransportException.UNKNOWN, "IOError: " + msg));
+			}
+		};
+		
+		
+		// the request
+		request_.setPostBytes(buffer.getBytes());
+		request_.request(true/*POST*/);
+		
     }
 
 }
diff --git a/lib/haxe/src/org/apache/thrift/transport/TLayeredTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TLayeredTransport.hx
new file mode 100644
index 0000000..161d91e
--- /dev/null
+++ b/lib/haxe/src/org/apache/thrift/transport/TLayeredTransport.hx
@@ -0,0 +1,50 @@
+// Licensed to the Apache Software Foundation(ASF) under one
+// or more contributor license agreements.See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.thrift.transport;
+
+import haxe.Int64;
+import org.apache.thrift.TConfiguration;
+
+class TLayeredTransport extends TTransport
+{
+	private var InnerTransport : TTransport;
+
+	public override function get_Configuration() : TConfiguration {
+		return InnerTransport.Configuration;
+	}
+
+	// private CTOR to prevent direct instantiation
+	// in other words, this class MUST be extended
+	private function new(transport : TTransport)
+	{
+		if( transport != null)
+			InnerTransport = transport;
+		else
+			throw new TTransportException( TTransportException.UNKNOWN, "Inner transport must not be null");
+	}
+
+	public override function UpdateKnownMessageSize(size : Int64) : Void
+	{
+		InnerTransport.UpdateKnownMessageSize(size);
+	}
+
+	public override function CheckReadBytesAvailable(numBytes : Int64) : Void
+	{
+		InnerTransport.CheckReadBytesAvailable(numBytes);
+	}
+}
diff --git a/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx b/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
index 4badb2a..e1ef5a1 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TServerSocket.hx
@@ -19,7 +19,10 @@
 
 package org.apache.thrift.transport;
 
-import haxe.remoting.SocketProtocol;
+#if (cs || neko || cpp || java || macro || lua || php || python || hl)
+import sys.net.Socket;
+#end
+
 import haxe.io.Bytes;
 import haxe.io.BytesBuffer;
 import haxe.io.BytesInput;
@@ -27,9 +30,9 @@
 import haxe.io.Input;
 import haxe.io.Output;
 import haxe.io.Eof;
+import org.apache.thrift.TConfiguration;
 
-//import flash.net.ServerSocket; - not yet available on Haxe 3.1.3
-#if ! (flash || html5)
+#if ! (flash || html5 || js)
 
 import sys.net.Host;
 
@@ -46,8 +49,10 @@
     private var _useBufferedSockets : Bool = false;
 
 
-    public function new(?address : String = 'localhost',  port : Int, clientTimeout : Float = 5, useBufferedSockets : Bool = false)
+    public function new(?address : String = 'localhost',  port : Int, clientTimeout : Float = 5, useBufferedSockets : Bool = false, config : TConfiguration = null)
     {
+		super(config);
+
         _clientTimeout = clientTimeout;
         _useBufferedSockets = useBufferedSockets;
 
diff --git a/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx
index 2189981..16fa564 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TServerTransport.hx
@@ -21,6 +21,15 @@
 
 class TServerTransport {
 
+	private var Configuration(default,null) : TConfiguration;
+
+	// private CTOR to prevent direct instantiation
+	// in other words, this class MUST be extended
+	private function new( config : TConfiguration)
+	{
+		Configuration = (config != null) ? config : new TConfiguration();
+	}
+
     public function Accept() : TTransport {
         var transport = AcceptImpl();
         if (transport == null) {
diff --git a/lib/haxe/src/org/apache/thrift/transport/TSocket.hx b/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
index 7941ab9..a743543 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TSocket.hx
@@ -19,12 +19,12 @@
 
 package org.apache.thrift.transport;
 
-#if flash
+#if (cs || neko || cpp || java || macro || lua || php || python || hl)
+import sys.net.Socket;
+#elseif flash
 import flash.net.Socket;
 #elseif js
 import js.html.WebSocket;
-#else
-import haxe.remoting.SocketProtocol;
 #end
 
 import haxe.io.Bytes;
@@ -34,6 +34,7 @@
 import haxe.io.Input;
 import haxe.io.Output;
 import haxe.io.Eof;
+import org.apache.thrift.TConfiguration;
 
 
 #if ! (flash || js)
@@ -46,7 +47,7 @@
    * Thrift Socket Server based implementations.
    */
 
-class TSocket extends TTransport  {
+class TSocket extends TEndpointTransport  {
 
     #if (flash || js)
     private var host  :  String;
@@ -79,7 +80,9 @@
     private var ioCallback : TException->Void = null;
     private var readCount : Int = 0;
 
-    public function new(host : String, port  :  Int)  :  Void  {
+    public function new(host : String, port :  Int, config : TConfiguration = null)  :  Void  {
+		super(config);
+
         #if (flash || js)
         this.host = host;
         #else
@@ -132,6 +135,7 @@
                 buf.addByte( input.readByte());
                 --remaining;
             }
+            CountConsumedMessageBytes(len);
             return len;
 
             #elseif js
@@ -144,6 +148,7 @@
                 buf.addByte( input.get(off+nr));
                 ++nr;
             }
+			CountConsumedMessageBytes(len);
             return len;
 
             #else
@@ -158,6 +163,7 @@
             var got = input.readBytes(data, 0, len);
             buf.addBytes( data, 0, got);
             readCount += got;
+			CountConsumedMessageBytes(got);
             return got;
 
             #end
@@ -223,6 +229,7 @@
         #end
 
         obuffer = new BytesOutput();
+		ResetConsumedMessageSize();
 
 
         ioCallback = callback;
@@ -262,7 +269,7 @@
     public override function open()  :  Void
     {
         #if js
-        var socket = new WebSocket();
+        var socket = new WebSocket(host);
         socket.onmessage = function( event : js.html.MessageEvent) {
             this.input = event.data;
         }
@@ -287,6 +294,7 @@
         #end
 
         assignSocket( socket);
+		ResetConsumedMessageSize();
     }
 
     #if js
@@ -308,11 +316,26 @@
         #end
     }
 
-    public function setTimeout( timeout : Float ) : Void {
+	#if (flash)
+	
+    public function setTimeout( timeout : UInt) : Void {
         if(isOpen()) {
-            socket.setTimeout(timeout);
+            socket.timeout = timeout;
         }
         this.timeout = timeout;
     }
 
+	#else
+	
+    public function setTimeout( timeout : Float ) : Void {
+        if(isOpen()) {
+			#if ! (js)
+			socket.setTimeout(timeout);
+			#end
+        }
+        this.timeout = timeout;
+    }
+
+	#end
+
 }
diff --git a/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx
index 31a7c14..59bef15 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TStreamTransport.hx
@@ -19,6 +19,7 @@
 
 package org.apache.thrift.transport;
 
+import org.apache.thrift.TConfiguration;
 import org.apache.thrift.transport.*;
 import org.apache.thrift.helper.*;
 
@@ -28,13 +29,15 @@
 import haxe.io.BytesInput;
 
 
-class TStreamTransport extends TTransport {
+class TStreamTransport extends TEndpointTransport {
 
     public var InputStream(default,null) : TStream;
     public var OutputStream(default,null) : TStream;
 
 
-    public function new( input : TStream, output : TStream) {
+    public function new( input : TStream, output : TStream, config : TConfiguration) {
+		super(config);
+
         this.InputStream = input;
         this.OutputStream = output;
     }
@@ -48,7 +51,7 @@
     }
 
     public override function open() : Void {
-    }
+	}
 
     public override function close() : Void {
         if (InputStream != null)
diff --git a/lib/haxe/src/org/apache/thrift/transport/TTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TTransport.hx
index e6b3179..8d2b5b8 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TTransport.hx
@@ -19,12 +19,18 @@
 
 package org.apache.thrift.transport;
 
+import haxe.Int64;
 import haxe.io.Eof;
 import haxe.io.Bytes;
 import haxe.io.BytesBuffer;
 import org.apache.thrift.AbstractMethodError;
 
 class TTransport {
+	
+	public var Configuration(get, never) : TConfiguration;
+	public function get_Configuration() : TConfiguration throw "abstract method called";
+	public function UpdateKnownMessageSize(size : Int64) : Void throw "abstract method called";
+	public function CheckReadBytesAvailable(numBytes : Int64) : Void  throw "abstract method called";
 
     /**
      * Queries whether the transport is open.
diff --git a/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx b/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx
index b2272f3..6da6e01 100644
--- a/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx
+++ b/lib/haxe/src/org/apache/thrift/transport/TWrappingServerTransport.hx
@@ -25,23 +25,25 @@
 */
 class TWrappingServerTransport extends TServerTransport {
 
-  private var transport(default,null) : TTransport;
+	private var transport(default,null) : TTransport;
 
-  public function new(transport : TTransport) {
-    this.transport = transport;
-  }
+	public function new(transport : TTransport) {
+		super(transport.Configuration);
 
-  public override function Listen() : Void
-  {
-  }
+		this.transport = transport;
+	}
 
-  private override function AcceptImpl() : TTransport
-  {
-    return transport;
-  }
+	public override function Listen() : Void
+	{
+	}
 
-  public override function Close() : Void
-  {
+	private override function AcceptImpl() : TTransport
+	{
+		return transport;
+	}
 
-  }
+	public override function Close() : Void
+	{
+
+	}
 }
diff --git a/lib/hs/CMakeLists.txt b/lib/hs/CMakeLists.txt
deleted file mode 100644
index c477c9b..0000000
--- a/lib/hs/CMakeLists.txt
+++ /dev/null
@@ -1,93 +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.
-#
-
-# Rebuild when any of these files changes
-set(haskell_sources
-    src/Thrift.hs
-    src/Thrift/Arbitraries.hs
-    src/Thrift/Protocol.hs
-    src/Thrift/Protocol/Binary.hs
-    src/Thrift/Protocol/Compact.hs
-    src/Thrift/Protocol/JSON.hs
-    src/Thrift/Server.hs
-    src/Thrift/Transport.hs
-    src/Thrift/Transport/Empty.hs
-    src/Thrift/Transport/Framed.hs
-    src/Thrift/Transport/Handle.hs
-    src/Thrift/Transport/HttpClient.hs
-    src/Thrift/Transport/IOBuffer.hs
-    src/Thrift/Types.hs
-    thrift.cabal
-)
-
-if(BUILD_TESTING)
-    list(APPEND haskell_sources
-        test/Spec.hs
-        test/BinarySpec.hs
-        test/CompactSpec.hs
-        test/JSONSpec.hs
-    )
-    set(hs_enable_test "--enable-tests")
-endif()
-
-set(haskell_artifacts thrift_cabal.stamp)
-# Adding *.hi files so that any missing file triggers the build
-foreach(SRC ${haskell_sources})
-    get_filename_component(EX ${SRC} EXT)
-    if(${EX} STREQUAL ".hs")
-        file(RELATIVE_PATH REL ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/${SRC})
-        get_filename_component(DIR ${REL} DIRECTORY)
-        get_filename_component(BASE ${REL} NAME_WE)
-        list(APPEND haskell_artifacts dist/build/${DIR}/${BASE}.hi)
-    endif()
-endforeach()
-
-if(CMAKE_BUILD_TYPE STREQUAL "Debug")
-    set(hs_optimize -O0)
-else()
-    set(hs_optimize -O1)
-endif()
-
-add_custom_command(
-    OUTPUT ${haskell_artifacts}
-    COMMAND ${CABAL} update
-    # Build dependencies first without --builddir, otherwise it fails.
-    COMMAND ${CABAL} install --only-dependencies ${hs_enable_test}
-    COMMAND ${CABAL} configure ${hs_optimize} ${hs_enable_test} --builddir=${CMAKE_CURRENT_BINARY_DIR}/dist
-    COMMAND ${CABAL} build --builddir=${CMAKE_CURRENT_BINARY_DIR}/dist
-    COMMAND ${CABAL} install --builddir=${CMAKE_CURRENT_BINARY_DIR}/dist
-    COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/thrift_cabal.stamp
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
-    DEPENDS ${haskell_sources}
-    COMMENT "Building Haskell library")
-
-add_custom_target(haskell_library ALL
-    DEPENDS ${haskell_artifacts})
-
-if(BUILD_TESTING)
-    add_test(NAME HaskellCabalCheck
-            COMMAND ${CABAL} check
-            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-    add_test(NAME HaskellCabalTest
-            # Cabal fails to find built executable when --builddir is specified.
-            # So we invoke the executable directly.
-            # COMMAND ${CABAL} test --builddir=${CMAKE_CURRENT_BINARY_DIR}/dist
-            # WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-            COMMAND dist/build/spec/spec)
-endif()
diff --git a/lib/hs/LICENSE b/lib/hs/LICENSE
deleted file mode 100644
index d645695..0000000
--- a/lib/hs/LICENSE
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
diff --git a/lib/hs/README.md b/lib/hs/README.md
deleted file mode 100644
index 10bdeff..0000000
--- a/lib/hs/README.md
+++ /dev/null
@@ -1,113 +0,0 @@
-Haskell Thrift Bindings
-
-License
-=======
-
-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.
-
-Compile
-=======
-
-Use Cabal to compile and install; ./configure uses Cabal underneath, and that
-path is not yet well tested. Thrift's library and generated code should compile
-with pretty much any GHC extensions or warnings you enable (or disable).
-Please report this not being the case as a bug on
-https://issues.apache.org/jira/secure/CreateIssue!default.jspa
-
-Chances you'll need to muck a bit with Cabal flags to install Thrift:
-
-CABAL_CONFIGURE_FLAGS="--user" ./configure
-
-Base Types
-==========
-
-The mapping from Thrift types to Haskell's is:
-
- * double -> Double
- * byte -> Data.Int.Int8
- * i16 -> Data.Int.Int16
- * i32 -> Data.Int.Int32
- * i64 -> Data.Int.Int64
- * string -> Text
- * binary -> Data.ByteString.Lazy
- * bool -> Boolean
-
-Enums
-=====
-
-Become Haskell 'data' types. Use fromEnum to get out the int value.
-
-Lists
-=====
-
-Become Data.Vector.Vector from the vector package.
-
-Maps and Sets
-=============
-
-Become Data.HashMap.Strict.Map and Data.HashSet.Set from the
-unordered-containers package.
-
-Structs
-=======
-
-Become records. Field labels are ugly, of the form f_STRUCTNAME_FIELDNAME. All
-fields are Maybe types.
-
-Exceptions
-==========
-
-Identical to structs. Use them with throw and catch from Control.Exception.
-
-Client
-======
-
-Just a bunch of functions. You may have to import a bunch of client files to
-deal with inheritance.
-
-Interface
-=========
-
-You should only have to import the last one in the chain of inheritors. To make
-an interface, declare a label:
-
-  data MyIface = MyIface
-
-and then declare it an instance of each iface class, starting with the superest
-class and proceeding down (all the while defining the methods).  Then pass your
-label to process as the handler.
-
-Processor
-=========
-
-Just a function that takes a handler label, protocols. It calls the
-superclasses process if there is a superclass.
-
-Releasing to Hackage
-====================
-
-Using the [Docker Container for Ubuntu Bionic](../../build/docker/README.md), run:
-
-    root@e941f5311545:/thrift/src# ./bootstrap.sh && ./configure
-    root@e941f5311545:/thrift/src# cd lib/hs && make dist-local
-
-This will produce a `lib/hs/dist/thrift-<version>.tar.gz` file.  Take this
-file and upload it as a Haskell Hackage
-[package candidate](https://hackage.haskell.org/upload#candidates) and 
-check to make sure all the information is correct.  Assuming all is satisfactory,
-you can upload the package as official using the link at the top of the page.
diff --git a/lib/hs/Setup.lhs b/lib/hs/Setup.lhs
deleted file mode 100755
index d52ae94..0000000
--- a/lib/hs/Setup.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env runhaskell
-
-> -- 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.
-
-> import Distribution.Simple
-> main = defaultMain
diff --git a/lib/hs/TODO b/lib/hs/TODO
deleted file mode 100644
index 1368173..0000000
--- a/lib/hs/TODO
+++ /dev/null
@@ -1,2 +0,0 @@
-The library could stand to be built up more.
-Many modules need export lists.
diff --git a/lib/hs/coding_standards.md b/lib/hs/coding_standards.md
deleted file mode 100644
index fa0390b..0000000
--- a/lib/hs/coding_standards.md
+++ /dev/null
@@ -1 +0,0 @@
-Please follow [General Coding Standards](/doc/coding_standards.md)
diff --git a/lib/hs/src/Thrift.hs b/lib/hs/src/Thrift.hs
deleted file mode 100644
index 6580209..0000000
--- a/lib/hs/src/Thrift.hs
+++ /dev/null
@@ -1,114 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RankNTypes #-}
---
--- 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
-    ( module Thrift.Transport
-    , module Thrift.Protocol
-    , AppExnType(..)
-    , AppExn(..)
-    , readAppExn
-    , writeAppExn
-    , ThriftException(..)
-    ) where
-
-import Control.Exception
-
-import Data.Int
-import Data.Text.Lazy ( Text, pack, unpack )
-import Data.Text.Lazy.Encoding
-import Data.Typeable ( Typeable )
-import qualified Data.HashMap.Strict as Map
-
-import Thrift.Protocol
-import Thrift.Transport
-import Thrift.Types
-
-data ThriftException = ThriftException
-  deriving ( Show, Typeable )
-instance Exception ThriftException
-
-data AppExnType
-    = AE_UNKNOWN
-    | AE_UNKNOWN_METHOD
-    | AE_INVALID_MESSAGE_TYPE
-    | AE_WRONG_METHOD_NAME
-    | AE_BAD_SEQUENCE_ID
-    | AE_MISSING_RESULT
-    | AE_INTERNAL_ERROR
-    | AE_PROTOCOL_ERROR
-    | AE_INVALID_TRANSFORM
-    | AE_INVALID_PROTOCOL
-    | AE_UNSUPPORTED_CLIENT_TYPE
-      deriving ( Eq, Show, Typeable )
-
-instance Enum AppExnType where
-    toEnum 0 = AE_UNKNOWN
-    toEnum 1 = AE_UNKNOWN_METHOD
-    toEnum 2 = AE_INVALID_MESSAGE_TYPE
-    toEnum 3 = AE_WRONG_METHOD_NAME
-    toEnum 4 = AE_BAD_SEQUENCE_ID
-    toEnum 5 = AE_MISSING_RESULT
-    toEnum 6 = AE_INTERNAL_ERROR
-    toEnum 7 = AE_PROTOCOL_ERROR
-    toEnum 8 = AE_INVALID_TRANSFORM
-    toEnum 9 = AE_INVALID_PROTOCOL
-    toEnum 10 = AE_UNSUPPORTED_CLIENT_TYPE
-    toEnum t = error $ "Invalid AppExnType " ++ show t
-
-    fromEnum AE_UNKNOWN = 0
-    fromEnum AE_UNKNOWN_METHOD = 1
-    fromEnum AE_INVALID_MESSAGE_TYPE = 2
-    fromEnum AE_WRONG_METHOD_NAME = 3
-    fromEnum AE_BAD_SEQUENCE_ID = 4
-    fromEnum AE_MISSING_RESULT = 5
-    fromEnum AE_INTERNAL_ERROR = 6
-    fromEnum AE_PROTOCOL_ERROR = 7
-    fromEnum AE_INVALID_TRANSFORM = 8
-    fromEnum AE_INVALID_PROTOCOL = 9
-    fromEnum AE_UNSUPPORTED_CLIENT_TYPE = 10
-
-data AppExn = AppExn { ae_type :: AppExnType, ae_message :: String }
-  deriving ( Show, Typeable )
-instance Exception AppExn
-
-writeAppExn :: Protocol p => p -> AppExn -> IO ()
-writeAppExn pt ae = writeVal pt $ TStruct $ Map.fromList
-                    [ (1, ("message", TString $ encodeUtf8 $ pack $ ae_message ae))
-                    , (2, ("type", TI32 $ fromIntegral $ fromEnum (ae_type ae)))
-                    ]
-
-readAppExn :: Protocol p => p -> IO AppExn
-readAppExn pt = do
-    let typemap = Map.fromList [(1,("message",T_STRING)),(2,("type",T_I32))]
-    TStruct fields <- readVal pt $ T_STRUCT typemap
-    return $ readAppExnFields fields
-
-readAppExnFields :: Map.HashMap Int16 (Text, ThriftVal) -> AppExn
-readAppExnFields fields = AppExn{
-  ae_message = maybe undefined unwrapMessage $ Map.lookup 1 fields,
-  ae_type    = maybe undefined unwrapType $ Map.lookup 2 fields
-  }
-  where
-    unwrapMessage (_, TString s) = unpack $ decodeUtf8 s
-    unwrapMessage _ = undefined
-    unwrapType (_, TI32 i) = toEnum $ fromIntegral i
-    unwrapType _ = undefined
diff --git a/lib/hs/src/Thrift/Arbitraries.hs b/lib/hs/src/Thrift/Arbitraries.hs
deleted file mode 100644
index e9c0fc3..0000000
--- a/lib/hs/src/Thrift/Arbitraries.hs
+++ /dev/null
@@ -1,55 +0,0 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-
-module Thrift.Arbitraries where
-
-import Data.Bits()
-
-import Test.QuickCheck.Arbitrary
-
-import Control.Applicative ((<$>))
-import Data.Map (Map)
-import qualified Data.Map as Map
-import qualified Data.Set as Set
-import qualified Data.Vector as Vector
-import qualified Data.Text.Lazy as Text
-import qualified Data.HashSet as HSet
-import qualified Data.HashMap.Strict as HMap
-import Data.Hashable (Hashable)
-
-import Data.ByteString.Lazy (ByteString)
-import qualified Data.ByteString.Lazy as BS
-
--- String has an Arbitrary instance already
--- Bool has an Arbitrary instance already
--- A Thrift 'list' is a Vector.
-
-instance Arbitrary ByteString where
-  arbitrary = BS.pack . filter (/= 0) <$> arbitrary
-
-instance (Arbitrary k) => Arbitrary (Vector.Vector k) where
-  arbitrary = Vector.fromList <$> arbitrary
-
-instance Arbitrary Text.Text where
-  arbitrary = Text.pack . filter (/= '\0') <$> arbitrary
-
-instance (Eq k, Hashable k, Arbitrary k) => Arbitrary (HSet.HashSet k) where
-  arbitrary = HSet.fromList <$> arbitrary
-
-instance (Eq k, Hashable k, Arbitrary k, Arbitrary v) =>
-    Arbitrary (HMap.HashMap k v) where
-  arbitrary = HMap.fromList <$> arbitrary
-
-{-
-   To handle Thrift 'enum' we would ideally use something like:
-
-instance (Enum a, Bounded a) => Arbitrary a
-    where arbitrary = elements (enumFromTo minBound maxBound)
-
-Unfortunately this doesn't play nicely with the type system.
-Instead we'll generate an arbitrary instance along with the code.
--}
-
-{-
-    There might be some way to introspect on the Haskell structure of a
-    Thrift 'struct' or 'exception' but generating the code directly is simpler.
--}
diff --git a/lib/hs/src/Thrift/Protocol.hs b/lib/hs/src/Thrift/Protocol.hs
deleted file mode 100644
index 67a9175..0000000
--- a/lib/hs/src/Thrift/Protocol.hs
+++ /dev/null
@@ -1,136 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE OverloadedStrings #-}
---
--- 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.Protocol
-    ( Protocol(..)
-    , StatelessProtocol(..)
-    , ProtocolExn(..)
-    , ProtocolExnType(..)
-    , getTypeOf
-    , runParser
-    , bsToDouble
-    , bsToDoubleLE
-    ) where
-
-import Control.Exception
-import Data.Attoparsec.ByteString
-import Data.Bits
-import Data.ByteString.Unsafe
-import Data.Functor ((<$>))
-import Data.Int
-import Data.Monoid (mempty)
-import Data.Text.Lazy (Text)
-import Data.Typeable (Typeable)
-import Data.Word
-import Foreign.Ptr (castPtr)
-import Foreign.Storable (peek, poke)
-import System.IO.Unsafe
-import qualified Data.ByteString as BS
-import qualified Data.HashMap.Strict as Map
-import qualified Data.ByteString.Lazy as LBS
-
-import Thrift.Transport
-import Thrift.Types
-
-class Protocol a where
-  readByte :: a -> IO LBS.ByteString
-  readVal :: a -> ThriftType -> IO ThriftVal
-  readMessage :: a -> ((Text, MessageType, Int32) -> IO b) -> IO b
-
-  writeVal :: a -> ThriftVal -> IO ()
-  writeMessage :: a -> (Text, MessageType, Int32) -> IO () -> IO ()
-
-class Protocol a => StatelessProtocol a where
-  serializeVal :: a -> ThriftVal -> LBS.ByteString
-  deserializeVal :: a -> ThriftType -> LBS.ByteString -> ThriftVal
-
-data ProtocolExnType
-    = PE_UNKNOWN
-    | PE_INVALID_DATA
-    | PE_NEGATIVE_SIZE
-    | PE_SIZE_LIMIT
-    | PE_BAD_VERSION
-    | PE_NOT_IMPLEMENTED
-    | PE_MISSING_REQUIRED_FIELD
-      deriving ( Eq, Show, Typeable )
-
-data ProtocolExn = ProtocolExn ProtocolExnType String
-  deriving ( Show, Typeable )
-instance Exception ProtocolExn
-
-getTypeOf :: ThriftVal -> ThriftType
-getTypeOf v =  case v of
-  TStruct{} -> T_STRUCT Map.empty
-  TMap{} -> T_MAP T_VOID T_VOID
-  TList{} -> T_LIST T_VOID
-  TSet{} -> T_SET T_VOID
-  TBool{} -> T_BOOL
-  TByte{} -> T_BYTE
-  TI16{} -> T_I16
-  TI32{} -> T_I32
-  TI64{} -> T_I64
-  TString{} -> T_STRING
-  TBinary{} -> T_BINARY
-  TDouble{} -> T_DOUBLE
-
-runParser :: (Protocol p, Show a) => p -> Parser a -> IO a
-runParser prot p = refill >>= getResult . parse p
-  where
-    refill = handle handleEOF $ LBS.toStrict <$> readByte prot
-    getResult (Done _ a) = return a
-    getResult (Partial k) = refill >>= getResult . k
-    getResult f = throw $ ProtocolExn PE_INVALID_DATA (show f)
-
-handleEOF :: SomeException -> IO BS.ByteString
-handleEOF = const $ return mempty
-
--- | Converts a ByteString to a Floating point number
--- The ByteString is assumed to be encoded in network order (Big Endian)
--- therefore the behavior of this function varies based on whether the local
--- machine is big endian or little endian.
-bsToDouble :: BS.ByteString -> Double
-bsToDoubleLE :: BS.ByteString -> Double
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-bsToDouble bs = unsafeDupablePerformIO $ unsafeUseAsCString bs castBsSwapped
-bsToDoubleLE bs = unsafeDupablePerformIO $ unsafeUseAsCString bs castBs
-#else
-bsToDouble bs = unsafeDupablePerformIO $ unsafeUseAsCString bs castBs
-bsToDoubleLE bs = unsafeDupablePerformIO $ unsafeUseAsCString bs castBsSwapped
-#endif
-
-
-castBsSwapped chrPtr = do
-  w <- peek (castPtr chrPtr)
-  poke (castPtr chrPtr) (byteSwap w)
-  peek (castPtr chrPtr)
-castBs = peek . castPtr
-
--- | Swap endianness of a 64-bit word
-byteSwap :: Word64 -> Word64
-byteSwap w = (w `shiftL` 56 .&. 0xFF00000000000000) .|.
-             (w `shiftL` 40 .&. 0x00FF000000000000) .|.
-             (w `shiftL` 24 .&. 0x0000FF0000000000) .|.
-             (w `shiftL` 8  .&. 0x000000FF00000000) .|.
-             (w `shiftR` 8  .&. 0x00000000FF000000) .|.
-             (w `shiftR` 24 .&. 0x0000000000FF0000) .|.
-             (w `shiftR` 40 .&. 0x000000000000FF00) .|.
-             (w `shiftR` 56 .&. 0x00000000000000FF)
diff --git a/lib/hs/src/Thrift/Protocol/Binary.hs b/lib/hs/src/Thrift/Protocol/Binary.hs
deleted file mode 100644
index 7b0acd9..0000000
--- a/lib/hs/src/Thrift/Protocol/Binary.hs
+++ /dev/null
@@ -1,212 +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.
---
-
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Thrift.Protocol.Binary
-    ( module Thrift.Protocol
-    , BinaryProtocol(..)
-    , versionMask
-    , version1
-    ) where
-
-import Control.Exception ( throw )
-import Control.Monad
-import Data.Bits
-import Data.ByteString.Lazy.Builder
-import Data.Functor
-import Data.Int
-import Data.Monoid
-import Data.Text.Lazy.Encoding ( decodeUtf8, encodeUtf8 )
-import Data.Word
-
-import Thrift.Protocol
-import Thrift.Transport
-import Thrift.Types
-
-import qualified Data.Attoparsec.ByteString as P
-import qualified Data.Attoparsec.ByteString.Lazy as LP
-import qualified Data.Binary as Binary
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.HashMap.Strict as Map
-import qualified Data.Text.Lazy as LT
-
-versionMask :: Int32
-versionMask = fromIntegral (0xffff0000 :: Word32)
-
-version1 :: Int32
-version1 = fromIntegral (0x80010000 :: Word32)
-
-data BinaryProtocol a = Transport a => BinaryProtocol a
-
-getTransport :: Transport t => BinaryProtocol t -> t
-getTransport (BinaryProtocol t) = t
-
--- NOTE: Reading and Writing functions rely on Builders and Data.Binary to
--- encode and decode data.  Data.Binary assumes that the binary values it is
--- encoding to and decoding from are in BIG ENDIAN format, and converts the
--- endianness as necessary to match the local machine.
-instance Transport t => Protocol (BinaryProtocol t) where
-    readByte p = tReadAll (getTransport p) 1
-    -- flushTransport p = tFlush (getTransport p)
-    writeMessage p (n, t, s) f = do
-      tWrite (getTransport p) messageBegin
-      f
-      tFlush $ getTransport p
-      where
-        messageBegin = toLazyByteString $
-          buildBinaryValue (TI32 (version1 .|. fromIntegral (fromEnum t))) <>
-          buildBinaryValue (TString $ encodeUtf8 n) <>
-          buildBinaryValue (TI32 s)
-
-    readMessage p = (readMessageBegin p >>=)
-      where
-        readMessageBegin p = runParser p $ do
-          TI32 ver <- parseBinaryValue T_I32
-          if ver .&. versionMask /= version1
-            then throw $ ProtocolExn PE_BAD_VERSION "Missing version identifier"
-            else do
-              TString s <- parseBinaryValue T_STRING
-              TI32 sz <- parseBinaryValue T_I32
-              return (decodeUtf8 s, toEnum $ fromIntegral $ ver .&. 0xFF, sz)
-
-    writeVal p = tWrite (getTransport p) . toLazyByteString . buildBinaryValue
-    readVal p = runParser p . parseBinaryValue
-
-instance Transport t => StatelessProtocol (BinaryProtocol t) where
-    serializeVal _ = toLazyByteString . buildBinaryValue
-    deserializeVal _ ty bs =
-      case LP.eitherResult $ LP.parse (parseBinaryValue ty) bs of
-        Left s -> error s
-        Right val -> val
-
--- | Writing Functions
-buildBinaryValue :: ThriftVal -> Builder
-buildBinaryValue (TStruct fields) = buildBinaryStruct fields <> buildType T_STOP
-buildBinaryValue (TMap ky vt entries) =
-  buildType ky <>
-  buildType vt <>
-  int32BE (fromIntegral (length entries)) <>
-  buildBinaryMap entries
-buildBinaryValue (TList ty entries) =
-  buildType ty <>
-  int32BE (fromIntegral (length entries)) <>
-  buildBinaryList entries
-buildBinaryValue (TSet ty entries) =
-  buildType ty <>
-  int32BE (fromIntegral (length entries)) <>
-  buildBinaryList entries
-buildBinaryValue (TBool b) =
-  word8 $ toEnum $ if b then 1 else 0
-buildBinaryValue (TByte b) = int8 b
-buildBinaryValue (TI16 i) = int16BE i
-buildBinaryValue (TI32 i) = int32BE i
-buildBinaryValue (TI64 i) = int64BE i
-buildBinaryValue (TDouble d) = doubleBE d
-buildBinaryValue (TString s) = int32BE len <> lazyByteString s
-  where
-    len :: Int32 = fromIntegral (LBS.length s)
-buildBinaryValue (TBinary s) = buildBinaryValue (TString s)
-
-buildBinaryStruct :: Map.HashMap Int16 (LT.Text, ThriftVal) -> Builder
-buildBinaryStruct = Map.foldrWithKey combine mempty
-  where
-    combine fid (_,val) s =
-      buildTypeOf val <> int16BE fid <> buildBinaryValue val <> s
-
-buildBinaryMap :: [(ThriftVal, ThriftVal)] -> Builder
-buildBinaryMap = foldl combine mempty
-  where
-    combine s (key, val) = s <> buildBinaryValue key <> buildBinaryValue val
-
-buildBinaryList :: [ThriftVal] -> Builder
-buildBinaryList = foldr (mappend . buildBinaryValue) mempty
-
--- | Reading Functions
-parseBinaryValue :: ThriftType -> P.Parser ThriftVal
-parseBinaryValue (T_STRUCT tmap) = TStruct <$> parseBinaryStruct tmap
-parseBinaryValue (T_MAP _ _) = do
-  kt <- parseType
-  vt <- parseType
-  n <- Binary.decode . LBS.fromStrict <$> P.take 4
-  TMap kt vt <$> parseBinaryMap kt vt n
-parseBinaryValue (T_LIST _) = do
-  t <- parseType
-  n <- Binary.decode . LBS.fromStrict <$> P.take 4
-  TList t <$> parseBinaryList t n
-parseBinaryValue (T_SET _) = do
-  t <- parseType
-  n <- Binary.decode . LBS.fromStrict <$> P.take 4
-  TSet t <$> parseBinaryList t n
-parseBinaryValue T_BOOL = TBool . (/=0) <$> P.anyWord8
-parseBinaryValue T_BYTE = TByte . Binary.decode . LBS.fromStrict <$> P.take 1
-parseBinaryValue T_I16 = TI16 . Binary.decode . LBS.fromStrict <$> P.take 2
-parseBinaryValue T_I32 = TI32 . Binary.decode . LBS.fromStrict <$> P.take 4
-parseBinaryValue T_I64 = TI64 . Binary.decode . LBS.fromStrict <$> P.take 8
-parseBinaryValue T_DOUBLE = TDouble . bsToDouble <$> P.take 8
-parseBinaryValue T_STRING = parseBinaryString TString
-parseBinaryValue T_BINARY = parseBinaryString TBinary
-parseBinaryValue ty = error $ "Cannot read value of type " ++ show ty
-
-parseBinaryString ty = do
-  i :: Int32  <- Binary.decode . LBS.fromStrict <$> P.take 4
-  ty . LBS.fromStrict <$> P.take (fromIntegral i)
-
-parseBinaryStruct :: TypeMap -> P.Parser (Map.HashMap Int16 (LT.Text, ThriftVal))
-parseBinaryStruct tmap = Map.fromList <$> P.manyTill parseField (matchType T_STOP)
-  where
-    parseField = do
-      t <- parseType
-      n <- Binary.decode . LBS.fromStrict <$> P.take 2
-      v <- case (t, Map.lookup n tmap) of
-             (T_STRING, Just (_, T_BINARY)) -> parseBinaryValue T_BINARY
-             _ -> parseBinaryValue t
-      return (n, ("", v))
-
-parseBinaryMap :: ThriftType -> ThriftType -> Int32 -> P.Parser [(ThriftVal, ThriftVal)]
-parseBinaryMap kt vt n | n <= 0 = return []
-                       | otherwise = do
-  k <- parseBinaryValue kt
-  v <- parseBinaryValue vt
-  ((k,v) :) <$> parseBinaryMap kt vt (n-1)
-
-parseBinaryList :: ThriftType -> Int32 -> P.Parser [ThriftVal]
-parseBinaryList ty n | n <= 0 = return []
-                     | otherwise = liftM2 (:) (parseBinaryValue ty)
-                                   (parseBinaryList ty (n-1))
-
-
-
--- | Write a type as a byte
-buildType :: ThriftType -> Builder
-buildType t = word8 $ fromIntegral $ fromEnum t
-
--- | Write type of a ThriftVal as a byte
-buildTypeOf :: ThriftVal -> Builder
-buildTypeOf = buildType . getTypeOf
-
--- | Read a byte as though it were a ThriftType
-parseType :: P.Parser ThriftType
-parseType = toEnum . fromIntegral <$> P.anyWord8
-
-matchType :: ThriftType -> P.Parser ThriftType
-matchType t = t <$ P.word8 (fromIntegral $ fromEnum t)
diff --git a/lib/hs/src/Thrift/Protocol/Compact.hs b/lib/hs/src/Thrift/Protocol/Compact.hs
deleted file mode 100644
index f23970a..0000000
--- a/lib/hs/src/Thrift/Protocol/Compact.hs
+++ /dev/null
@@ -1,311 +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.
---
-
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-
-module Thrift.Protocol.Compact
-    ( module Thrift.Protocol
-    , CompactProtocol(..)
-    , parseVarint
-    , buildVarint
-    ) where
-
-import Control.Applicative
-import Control.Monad
-import Data.Attoparsec.ByteString as P
-import Data.Attoparsec.ByteString.Lazy as LP
-import Data.Bits
-import Data.ByteString.Lazy.Builder as B
-import Data.Int
-import Data.List as List
-import Data.Monoid
-import Data.Word
-import Data.Text.Lazy.Encoding ( decodeUtf8, encodeUtf8 )
-
-import Thrift.Protocol
-import Thrift.Transport
-import Thrift.Types
-
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.HashMap.Strict as Map
-import qualified Data.Text.Lazy as LT
-
--- | the Compact Protocol implements the standard Thrift 'TCompactProcotol'
--- which is similar to the 'TBinaryProtocol', but takes less space on the wire.
--- Integral types are encoded using as varints.
-data CompactProtocol a = CompactProtocol a
-                         -- ^ Constuct a 'CompactProtocol' with a 'Transport'
-
-protocolID, version, versionMask, typeMask, typeBits :: Word8
-protocolID  = 0x82 -- 1000 0010
-version     = 0x01
-versionMask = 0x1f -- 0001 1111
-typeMask    = 0xe0 -- 1110 0000
-typeBits    = 0x07 -- 0000 0111
-typeShiftAmount :: Int
-typeShiftAmount = 5
-
-getTransport :: Transport t => CompactProtocol t -> t
-getTransport (CompactProtocol t) = t
-
-instance Transport t => Protocol (CompactProtocol t) where
-    readByte p = tReadAll (getTransport p) 1
-    writeMessage p (n, t, s) f = do
-      tWrite (getTransport p) messageBegin
-      f
-      tFlush $ getTransport p
-      where
-        messageBegin = toLazyByteString $
-          B.word8 protocolID <>
-          B.word8 ((version .&. versionMask) .|.
-                  (((fromIntegral $ fromEnum t) `shiftL`
-                  typeShiftAmount) .&. typeMask)) <>
-          buildVarint (i32ToZigZag s) <>
-          buildCompactValue (TString $ encodeUtf8 n)
-
-    readMessage p f = readMessageBegin >>= f
-      where
-        readMessageBegin = runParser p $ do
-          pid <- fromIntegral <$> P.anyWord8
-          when (pid /= protocolID) $ error "Bad Protocol ID"
-          w <- fromIntegral <$> P.anyWord8
-          let ver = w .&. versionMask
-          when (ver /= version) $ error "Bad Protocol version"
-          let typ = (w `shiftR` typeShiftAmount) .&. typeBits
-          seqId <- parseVarint zigZagToI32
-          TString name <- parseCompactValue T_STRING
-          return (decodeUtf8 name, toEnum $ fromIntegral $ typ, seqId)
-
-    writeVal p = tWrite (getTransport p) . toLazyByteString . buildCompactValue
-    readVal p ty = runParser p $ parseCompactValue ty
-
-instance Transport t => StatelessProtocol (CompactProtocol t) where
-    serializeVal _ = toLazyByteString . buildCompactValue
-    deserializeVal _ ty bs =
-      case LP.eitherResult $ LP.parse (parseCompactValue ty) bs of
-        Left s -> error s
-        Right val -> val
-
--- | Writing Functions
-buildCompactValue :: ThriftVal -> Builder
-buildCompactValue (TStruct fields) = buildCompactStruct fields
-buildCompactValue (TMap kt vt entries) =
-  let len = fromIntegral $ length entries :: Word32 in
-  if len == 0
-  then B.word8 0x00
-  else buildVarint len <>
-       B.word8 (fromTType kt `shiftL` 4 .|. fromTType vt) <>
-       buildCompactMap entries
-buildCompactValue (TList ty entries) =
-  let len = length entries in
-  (if len < 15
-   then B.word8 $ (fromIntegral len `shiftL` 4) .|. fromTType ty
-   else B.word8 (0xF0 .|. fromTType ty) <>
-        buildVarint (fromIntegral len :: Word32)) <>
-  buildCompactList entries
-buildCompactValue (TSet ty entries) = buildCompactValue (TList ty entries)
-buildCompactValue (TBool b) =
-  B.word8 $ toEnum $ if b then 1 else 0
-buildCompactValue (TByte b) = int8 b
-buildCompactValue (TI16 i) = buildVarint $ i16ToZigZag i
-buildCompactValue (TI32 i) = buildVarint $ i32ToZigZag i
-buildCompactValue (TI64 i) = buildVarint $ i64ToZigZag i
-buildCompactValue (TDouble d) = doubleLE d
-buildCompactValue (TString s) = buildVarint len <> lazyByteString s
-  where
-    len = fromIntegral (LBS.length s) :: Word32
-buildCompactValue (TBinary s) = buildCompactValue (TString s)
-
-buildCompactStruct :: Map.HashMap Int16 (LT.Text, ThriftVal) -> Builder
-buildCompactStruct = flip (loop 0) mempty . Map.toList
-  where
-    loop _ [] acc = acc <> B.word8 (fromTType T_STOP)
-    loop lastId ((fid, (_,val)) : fields) acc = loop fid fields $ acc <>
-      (if fid > lastId && fid - lastId <= 15
-       then B.word8 $ fromIntegral ((fid - lastId) `shiftL` 4) .|. typeOf val
-       else B.word8 (typeOf val) <> buildVarint (i16ToZigZag fid)) <>
-      (if typeOf val > 0x02 -- Not a T_BOOL
-       then buildCompactValue val
-       else mempty) -- T_BOOLs are encoded in the type
-buildCompactMap :: [(ThriftVal, ThriftVal)] -> Builder
-buildCompactMap = foldl combine mempty
-  where
-    combine s (key, val) = buildCompactValue key <> buildCompactValue val <> s
-
-buildCompactList :: [ThriftVal] -> Builder
-buildCompactList = foldr (mappend . buildCompactValue) mempty
-
--- | Reading Functions
-parseCompactValue :: ThriftType -> Parser ThriftVal
-parseCompactValue (T_STRUCT tmap) = TStruct <$> parseCompactStruct tmap
-parseCompactValue (T_MAP kt' vt') = do
-  n <- parseVarint id
-  if n == 0
-    then return $ TMap kt' vt' []
-    else do
-    w <- P.anyWord8
-    let kt = typeFrom $ w `shiftR` 4
-        vt = typeFrom $ w .&. 0x0F
-    TMap kt vt <$> parseCompactMap kt vt n
-parseCompactValue (T_LIST ty) = TList ty <$> parseCompactList
-parseCompactValue (T_SET ty) = TSet ty <$> parseCompactList
-parseCompactValue T_BOOL = TBool . (/=0) <$> P.anyWord8
-parseCompactValue T_BYTE = TByte . fromIntegral <$> P.anyWord8
-parseCompactValue T_I16 = TI16 <$> parseVarint zigZagToI16
-parseCompactValue T_I32 = TI32 <$> parseVarint zigZagToI32
-parseCompactValue T_I64 = TI64 <$> parseVarint zigZagToI64
-parseCompactValue T_DOUBLE = TDouble . bsToDoubleLE <$> P.take 8
-parseCompactValue T_STRING = parseCompactString TString
-parseCompactValue T_BINARY = parseCompactString TBinary
-parseCompactValue ty = error $ "Cannot read value of type " ++ show ty
-
-parseCompactString ty = do
-  len :: Word32 <- parseVarint id
-  ty . LBS.fromStrict <$> P.take (fromIntegral len)
-
-parseCompactStruct :: TypeMap -> Parser (Map.HashMap Int16 (LT.Text, ThriftVal))
-parseCompactStruct tmap = Map.fromList <$> parseFields 0
-  where
-    parseFields :: Int16 -> Parser [(Int16, (LT.Text, ThriftVal))]
-    parseFields lastId = do
-      w <- P.anyWord8
-      if w == 0x00
-        then return []
-        else do
-          let ty = typeFrom (w .&. 0x0F)
-              modifier = (w .&. 0xF0) `shiftR` 4
-          fid <- if modifier /= 0
-                 then return (lastId + fromIntegral modifier)
-                 else parseVarint zigZagToI16
-          val <- if ty == T_BOOL
-                 then return (TBool $ (w .&. 0x0F) == 0x01)
-                 else case (ty, Map.lookup fid tmap) of
-                        (T_STRING, Just (_, T_BINARY)) -> parseCompactValue T_BINARY
-                        _ -> parseCompactValue ty
-          ((fid, (LT.empty, val)) : ) <$> parseFields fid
-
-parseCompactMap :: ThriftType -> ThriftType -> Int32 ->
-                   Parser [(ThriftVal, ThriftVal)]
-parseCompactMap kt vt n | n <= 0 = return []
-                        | otherwise = do
-  k <- parseCompactValue kt
-  v <- parseCompactValue vt
-  ((k,v) :) <$> parseCompactMap kt vt (n-1)
-
-parseCompactList :: Parser [ThriftVal]
-parseCompactList = do
-  w <- P.anyWord8
-  let ty = typeFrom $ w .&. 0x0F
-      lsize = w `shiftR` 4
-  size <- if lsize == 0xF
-          then parseVarint id
-          else return $ fromIntegral lsize
-  loop ty size
-  where
-    loop :: ThriftType -> Int32 -> Parser [ThriftVal]
-    loop ty n | n <= 0 = return []
-              | otherwise = liftM2 (:) (parseCompactValue ty)
-                            (loop ty (n-1))
-
--- Signed numbers must be converted to "Zig Zag" format before they can be
--- serialized in the Varint format
-i16ToZigZag :: Int16 -> Word16
-i16ToZigZag n = fromIntegral $ (n `shiftL` 1) `xor` (n `shiftR` 15)
-
-zigZagToI16 :: Word16 -> Int16
-zigZagToI16 n = fromIntegral $ (n `shiftR` 1) `xor` negate (n .&. 0x1)
-
-i32ToZigZag :: Int32 -> Word32
-i32ToZigZag n = fromIntegral $ (n `shiftL` 1) `xor` (n `shiftR` 31)
-
-zigZagToI32 :: Word32 -> Int32
-zigZagToI32 n = fromIntegral $ (n `shiftR` 1) `xor` negate (n .&. 0x1)
-
-i64ToZigZag :: Int64 -> Word64
-i64ToZigZag n = fromIntegral $ (n `shiftL` 1) `xor` (n `shiftR` 63)
-
-zigZagToI64 :: Word64 -> Int64
-zigZagToI64 n = fromIntegral $ (n `shiftR` 1) `xor` negate (n .&. 0x1)
-
-buildVarint :: (Bits a, Integral a)  => a -> Builder
-buildVarint n | n .&. complement 0x7F == 0 = B.word8 $ fromIntegral n
-              | otherwise = B.word8 (0x80 .|. (fromIntegral n .&. 0x7F)) <>
-                            buildVarint (n `shiftR` 7)
-
-parseVarint :: (Bits a, Integral a, Ord a) => (a -> b) -> Parser b
-parseVarint fromZigZag = do
-  bytestemp <- BS.unpack <$> P.takeTill (not . flip testBit 7)
-  lsb <- P.anyWord8
-  let bytes = lsb : List.reverse bytestemp
-  return $ fromZigZag $ List.foldl' combine 0x00 bytes
-  where combine a b = (a `shiftL` 7) .|. (fromIntegral b .&. 0x7f)
-
--- | Compute the Compact Type
-fromTType :: ThriftType -> Word8
-fromTType ty = case ty of
-  T_STOP -> 0x00
-  T_BOOL -> 0x01
-  T_BYTE -> 0x03
-  T_I16 -> 0x04
-  T_I32 -> 0x05
-  T_I64 -> 0x06
-  T_DOUBLE -> 0x07
-  T_STRING -> 0x08
-  T_BINARY -> 0x08
-  T_LIST{} -> 0x09
-  T_SET{} -> 0x0A
-  T_MAP{} -> 0x0B
-  T_STRUCT{} -> 0x0C
-  T_VOID -> error "No Compact type for T_VOID"
-
-typeOf :: ThriftVal -> Word8
-typeOf v = case v of
-  TBool True -> 0x01
-  TBool False -> 0x02
-  TByte _ -> 0x03
-  TI16 _ -> 0x04
-  TI32 _ -> 0x05
-  TI64 _ -> 0x06
-  TDouble _ -> 0x07
-  TString _ -> 0x08
-  TBinary _ -> 0x08
-  TList{} -> 0x09
-  TSet{} -> 0x0A
-  TMap{} -> 0x0B
-  TStruct{} -> 0x0C
-
-typeFrom :: Word8 -> ThriftType
-typeFrom w = case w of
-  0x01 -> T_BOOL
-  0x02 -> T_BOOL
-  0x03 -> T_BYTE
-  0x04 -> T_I16
-  0x05 -> T_I32
-  0x06 -> T_I64
-  0x07 -> T_DOUBLE
-  0x08 -> T_STRING
-  0x09 -> T_LIST T_VOID
-  0x0A -> T_SET T_VOID
-  0x0B -> T_MAP T_VOID T_VOID
-  0x0C -> T_STRUCT Map.empty
-  n -> error $ "typeFrom: " ++ show n ++ " is not a compact type"
diff --git a/lib/hs/src/Thrift/Protocol/Header.hs b/lib/hs/src/Thrift/Protocol/Header.hs
deleted file mode 100644
index 5f42db4..0000000
--- a/lib/hs/src/Thrift/Protocol/Header.hs
+++ /dev/null
@@ -1,141 +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.
---
-
-
-module Thrift.Protocol.Header
-    ( module Thrift.Protocol
-    , HeaderProtocol(..)
-    , getProtocolType
-    , setProtocolType
-    , getHeaders
-    , getWriteHeaders
-    , setHeader
-    , setHeaders
-    , createHeaderProtocol
-    , createHeaderProtocol1
-    ) where
-
-import Thrift.Protocol
-import Thrift.Protocol.Binary
-import Thrift.Protocol.JSON
-import Thrift.Protocol.Compact
-import Thrift.Transport
-import Thrift.Transport.Header
-import Data.IORef
-import qualified Data.Map as Map
-
-data ProtocolWrap = forall a. (Protocol a) => ProtocolWrap(a)
-
-instance Protocol ProtocolWrap where
-  readByte (ProtocolWrap p) = readByte p
-  readVal (ProtocolWrap p) = readVal p
-  readMessage (ProtocolWrap p) = readMessage p
-  writeVal (ProtocolWrap p) = writeVal p
-  writeMessage (ProtocolWrap p) = writeMessage p
-
-data HeaderProtocol i o = (Transport i, Transport o) => HeaderProtocol {
-    trans :: HeaderTransport i o,
-    wrappedProto :: IORef ProtocolWrap
-  }
-
-createProtocolWrap :: Transport t => ProtocolType -> t -> ProtocolWrap
-createProtocolWrap typ t =
-  case typ of
-    TBinary -> ProtocolWrap $ BinaryProtocol t
-    TCompact -> ProtocolWrap $ CompactProtocol t
-    TJSON -> ProtocolWrap $ JSONProtocol t
-
-createHeaderProtocol :: (Transport i, Transport o) => i -> o -> IO(HeaderProtocol i o)
-createHeaderProtocol i o = do
-  t <- openHeaderTransport i o
-  pid <- readIORef $ protocolType t
-  proto <- newIORef $ createProtocolWrap pid t
-  return $ HeaderProtocol { trans = t, wrappedProto = proto }
-
-createHeaderProtocol1 :: Transport t => t -> IO(HeaderProtocol t t)
-createHeaderProtocol1 t = createHeaderProtocol t t
-
-resetProtocol :: (Transport i, Transport o) => HeaderProtocol i o -> IO ()
-resetProtocol p = do
-  pid <- readIORef $ protocolType $ trans p
-  writeIORef (wrappedProto p) $ createProtocolWrap pid $ trans p
-
-getWrapped = readIORef . wrappedProto
-
-setTransport :: (Transport i, Transport o) => HeaderProtocol i o -> HeaderTransport i o -> HeaderProtocol i o
-setTransport p t = p { trans = t }
-
-updateTransport :: (Transport i, Transport o) => HeaderProtocol i o -> (HeaderTransport i o -> HeaderTransport i o)-> HeaderProtocol i o
-updateTransport p f = setTransport p (f $ trans p)
-
-type Headers = Map.Map String String
-
--- TODO: we want to set headers without recreating client...
-setHeader :: (Transport i, Transport o) => HeaderProtocol i o -> String -> String -> HeaderProtocol i o
-setHeader p k v = updateTransport p $ \t -> t { writeHeaders = Map.insert k v $ writeHeaders t }
-
-setHeaders :: (Transport i, Transport o) => HeaderProtocol i o -> Headers -> HeaderProtocol i o
-setHeaders p h = updateTransport p $ \t -> t { writeHeaders = h }
-
--- TODO: make it public once we have first transform implementation for Haskell
-setTransforms :: (Transport i, Transport o) => HeaderProtocol i o -> [TransformType] -> HeaderProtocol i o
-setTransforms p trs = updateTransport p $ \t -> t { writeTransforms = trs }
-
-setTransform :: (Transport i, Transport o) => HeaderProtocol i o -> TransformType -> HeaderProtocol i o
-setTransform p tr = updateTransport p $ \t -> t { writeTransforms = tr:(writeTransforms t) }
-
-getWriteHeaders :: (Transport i, Transport o) => HeaderProtocol i o -> Headers
-getWriteHeaders = writeHeaders . trans
-
-getHeaders :: (Transport i, Transport o) => HeaderProtocol i o -> IO [(String, String)]
-getHeaders = readIORef . headers . trans
-
-getProtocolType :: (Transport i, Transport o) => HeaderProtocol i o -> IO ProtocolType
-getProtocolType p = readIORef $ protocolType $ trans p
-
-setProtocolType :: (Transport i, Transport o) => HeaderProtocol i o -> ProtocolType -> IO ()
-setProtocolType p typ = do
-  typ0 <- getProtocolType p
-  if typ == typ0
-    then return ()
-    else do
-      tSetProtocol (trans p) typ
-      resetProtocol p
-
-instance (Transport i, Transport o) => Protocol (HeaderProtocol i o) where
-  readByte p = tReadAll (trans p) 1
-
-  readVal p tp = do
-    proto <- getWrapped p
-    readVal proto tp
-
-  readMessage p f = do
-    tResetProtocol (trans p)
-    resetProtocol p
-    proto <- getWrapped p
-    readMessage proto f
-
-  writeVal p v = do
-    proto <- getWrapped p
-    writeVal proto v
-
-  writeMessage p x f = do
-    proto <- getWrapped p
-    writeMessage proto x f
-
diff --git a/lib/hs/src/Thrift/Protocol/JSON.hs b/lib/hs/src/Thrift/Protocol/JSON.hs
deleted file mode 100644
index 839eddc..0000000
--- a/lib/hs/src/Thrift/Protocol/JSON.hs
+++ /dev/null
@@ -1,362 +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.
---
-
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ExistentialQuantification #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TupleSections #-}
-
-module Thrift.Protocol.JSON
-    ( module Thrift.Protocol
-    , JSONProtocol(..)
-    ) where
-
-import Control.Applicative
-import Control.Exception (bracket)
-import Control.Monad
-import Data.Attoparsec.ByteString as P
-import Data.Attoparsec.ByteString.Char8 as PC
-import Data.Attoparsec.ByteString.Lazy as LP
-import Data.ByteString.Base64.Lazy as B64C
-import Data.ByteString.Lazy.Builder as B
-import Data.ByteString.Internal (c2w, w2c)
-import Data.Functor
-import Data.Int
-import Data.List
-import Data.Maybe (catMaybes)
-import Data.Monoid
-import Data.Text.Lazy.Encoding
-import Data.Word
-import qualified Data.HashMap.Strict as Map
-
-import Thrift.Protocol
-import Thrift.Transport
-import Thrift.Types
-
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.ByteString.Lazy.Char8 as LBSC
-import qualified Data.Text.Lazy as LT
-
--- | The JSON Protocol data uses the standard 'TJSONProtocol'.  Data is
--- encoded as a JSON 'ByteString'
-data JSONProtocol t = JSONProtocol t
-                      -- ^ Construct a 'JSONProtocol' with a 'Transport'
-getTransport :: Transport t => JSONProtocol t -> t
-getTransport (JSONProtocol t) = t
-
-instance Transport t => Protocol (JSONProtocol t) where
-    readByte p = tReadAll (getTransport p) 1
-
-    writeMessage (JSONProtocol t) (s, ty, sq) = bracket readMessageBegin readMessageEnd . const
-      where
-        readMessageBegin = tWrite t $ toLazyByteString $
-          B.char8 '[' <> buildShowable (1 :: Int32) <>
-          B.string8 ",\"" <> escape (encodeUtf8 s) <> B.char8 '\"' <>
-          B.char8 ',' <> buildShowable (fromEnum ty) <>
-          B.char8 ',' <> buildShowable sq <>
-          B.char8 ','
-        readMessageEnd _ = do
-          tWrite t "]"
-          tFlush t
-
-    readMessage p = bracket readMessageBegin readMessageEnd
-      where
-        readMessageBegin = runParser p $ skipSpace *> do
-          _ver :: Int32 <- lexeme (PC.char8 '[') *> lexeme (signed decimal)
-          bs <- lexeme (PC.char8 ',') *> lexeme escapedString
-          case decodeUtf8' bs of
-            Left _ -> fail "readMessage: invalid text encoding"
-            Right str -> do
-              ty <- toEnum <$> (lexeme (PC.char8 ',') *> lexeme (signed decimal))
-              seqNum <- lexeme (PC.char8 ',') *> lexeme (signed decimal)
-              _ <- PC.char8 ','
-              return (str, ty, seqNum)
-        readMessageEnd _ = void $ runParser p (PC.char8 ']')
-
-    writeVal p = tWrite (getTransport p) . toLazyByteString . buildJSONValue
-    readVal p ty = runParser p $ skipSpace *> parseJSONValue ty
-
-instance Transport t => StatelessProtocol (JSONProtocol t) where
-    serializeVal _ = toLazyByteString . buildJSONValue
-    deserializeVal _ ty bs =
-      case LP.eitherResult $ LP.parse (parseJSONValue ty) bs of
-        Left s -> error s
-        Right val -> val
-
--- Writing Functions
-
-buildJSONValue :: ThriftVal -> Builder
-buildJSONValue (TStruct fields) = B.char8 '{' <> buildJSONStruct fields <> B.char8 '}'
-buildJSONValue (TMap kt vt entries) =
-  B.char8 '[' <> B.char8 '"' <> getTypeName kt <> B.char8 '"' <>
-  B.char8 ',' <> B.char8 '"' <> getTypeName vt <> B.char8 '"' <>
-  B.char8 ',' <> buildShowable (length entries) <>
-  B.char8 ',' <> B.char8 '{' <> buildJSONMap entries <> B.char8 '}' <>
-  B.char8 ']'
-buildJSONValue (TList ty entries) =
-  B.char8 '[' <> B.char8 '"' <> getTypeName ty <> B.char8 '"' <>
-  B.char8 ',' <> buildShowable (length entries) <>
-  (if length entries > 0
-   then B.char8 ',' <> buildJSONList entries
-   else mempty) <>
-  B.char8 ']'
-buildJSONValue (TSet ty entries) = buildJSONValue (TList ty entries)
-buildJSONValue (TBool b) = if b then B.char8 '1' else B.char8 '0'
-buildJSONValue (TByte b) = buildShowable b
-buildJSONValue (TI16 i) = buildShowable i
-buildJSONValue (TI32 i) = buildShowable i
-buildJSONValue (TI64 i) = buildShowable i
-buildJSONValue (TDouble d) = buildShowable d
-buildJSONValue (TString s) = B.char8 '\"' <> escape s <> B.char8 '\"'
-buildJSONValue (TBinary s) = B.char8 '\"' <> (B.lazyByteString . B64C.encode $ s) <> B.char8 '\"'
-
-buildJSONStruct :: Map.HashMap Int16 (LT.Text, ThriftVal) -> Builder
-buildJSONStruct = mconcat . intersperse (B.char8 ',') . Map.foldrWithKey buildField []
-  where 
-    buildField fid (_,val) = (:) $
-      B.char8 '"' <> buildShowable fid <> B.string8 "\":" <> 
-      B.char8 '{' <>
-      B.char8 '"' <> getTypeName (getTypeOf val) <> B.string8 "\":" <>
-      buildJSONValue val <>
-      B.char8 '}'
-
-buildJSONMap :: [(ThriftVal, ThriftVal)] -> Builder
-buildJSONMap = mconcat . intersperse (B.char8 ',') . map buildKV
-  where
-    buildKV (key@(TString _), val) =
-      buildJSONValue key <> B.char8 ':' <> buildJSONValue val
-    buildKV (key, val) =
-      B.char8 '\"' <> buildJSONValue key <> B.string8 "\":" <> buildJSONValue val
-buildJSONList :: [ThriftVal] -> Builder
-buildJSONList = mconcat . intersperse (B.char8 ',') . map buildJSONValue
-
-buildShowable :: Show a => a ->  Builder
-buildShowable = B.string8 . show
-
--- Reading Functions
-
-parseJSONValue :: ThriftType -> Parser ThriftVal
-parseJSONValue (T_STRUCT tmap) =
-  TStruct <$> (lexeme (PC.char8 '{') *> parseJSONStruct tmap <* PC.char8 '}')
-parseJSONValue (T_MAP kt vt) = fmap (TMap kt vt) $
-  between '[' ']' $
-    lexeme escapedString *> lexeme (PC.char8 ',') *>
-    lexeme escapedString *> lexeme (PC.char8 ',') *>
-    lexeme decimal *> lexeme (PC.char8 ',') *>
-    between '{' '}' (parseJSONMap kt vt)
-parseJSONValue (T_LIST ty) = fmap (TList ty) $
-  between '[' ']' $ do
-    len <- lexeme escapedString *> lexeme (PC.char8 ',') *> lexeme decimal
-    if len > 0
-      then lexeme (PC.char8 ',') *> parseJSONList ty
-      else return []
-parseJSONValue (T_SET ty) = fmap (TSet ty) $
-  between '[' ']' $ do
-    len <- lexeme escapedString *> lexeme (PC.char8 ',') *> lexeme decimal
-    if len > 0
-      then  lexeme (PC.char8 ',') *> parseJSONList ty
-      else return []
-parseJSONValue T_BOOL =
-  (TBool True <$ PC.char8 '1') <|> (TBool False <$ PC.char8 '0')
-parseJSONValue T_BYTE = TByte <$> signed decimal
-parseJSONValue T_I16 = TI16 <$> signed decimal
-parseJSONValue T_I32 = TI32 <$> signed decimal
-parseJSONValue T_I64 = TI64 <$> signed decimal
-parseJSONValue T_DOUBLE = TDouble <$> double
-parseJSONValue T_STRING = TString <$> escapedString
-parseJSONValue T_BINARY = TBinary <$> base64String
-parseJSONValue T_STOP = fail "parseJSONValue: cannot parse type T_STOP"
-parseJSONValue T_VOID = fail "parseJSONValue: cannot parse type T_VOID"
-
-parseAnyValue :: Parser ()
-parseAnyValue = choice $
-                skipBetween '{' '}' :
-                skipBetween '[' ']' :
-                map (void . parseJSONValue)
-                  [ T_BOOL
-                  , T_I16
-                  , T_I32
-                  , T_I64
-                  , T_DOUBLE
-                  , T_STRING
-                  , T_BINARY
-                  ]
-  where
-    skipBetween :: Char -> Char -> Parser ()
-    skipBetween a b = between a b $ void (PC.satisfy (\c -> c /= a && c /= b))
-                                          <|> skipBetween a b
-
-parseJSONStruct :: TypeMap -> Parser (Map.HashMap Int16 (LT.Text, ThriftVal))
-parseJSONStruct tmap = Map.fromList . catMaybes <$> parseField
-                       `sepBy` lexeme (PC.char8 ',')
-  where
-    parseField = do
-      fid <- lexeme (between '"' '"' decimal) <* lexeme (PC.char8 ':')
-      case Map.lookup fid tmap of
-        Just (str, ftype) -> between '{' '}' $ do
-          _ <- lexeme (escapedString) *> lexeme (PC.char8 ':')
-          val <- lexeme (parseJSONValue ftype)
-          return $ Just (fid, (str, val))
-        Nothing -> lexeme parseAnyValue *> return Nothing
-
-parseJSONMap :: ThriftType -> ThriftType -> Parser [(ThriftVal, ThriftVal)]
-parseJSONMap kt vt =
-  ((,) <$> lexeme (parseJSONKey kt) <*>
-   (lexeme (PC.char8 ':') *> lexeme (parseJSONValue vt))) `sepBy`
-  lexeme (PC.char8 ',')
-  where
-    parseJSONKey T_STRING = parseJSONValue T_STRING
-    parseJSONKey T_BINARY = parseJSONValue T_BINARY
-    parseJSONKey kt = PC.char8 '"' *> parseJSONValue kt <* PC.char8 '"'
-
-parseJSONList :: ThriftType -> Parser [ThriftVal]
-parseJSONList ty = lexeme (parseJSONValue ty) `sepBy` lexeme (PC.char8 ',')
-
-escapedString :: Parser LBS.ByteString
-escapedString = PC.char8 '"' *>
-                (LBS.pack <$> P.many' (escapedChar <|> notChar8 '"')) <*
-                PC.char8 '"'
-
-base64String :: Parser LBS.ByteString
-base64String = PC.char8 '"' *>
-               (decodeBase64 . LBSC.pack <$> P.many' (PC.notChar '"')) <*
-               PC.char8 '"'
-               where
-                 decodeBase64 b =
-                   let padded = case (LBS.length b) `mod` 4 of
-                                  2 -> LBS.append b "=="
-                                  3 -> LBS.append b "="
-                                  _ -> b in
-                   case B64C.decode padded of
-                     Right s -> s
-                     Left x -> error x
-
-escapedChar :: Parser Word8
-escapedChar = PC.char8 '\\' *> (c2w <$> choice
-                                [ '\SOH' <$ P.string "u0001"
-                                , '\STX' <$ P.string "u0002"
-                                , '\ETX' <$ P.string "u0003"
-                                , '\EOT' <$ P.string "u0004"
-                                , '\ENQ' <$ P.string "u0005"
-                                , '\ACK' <$ P.string "u0006"
-                                , '\BEL' <$ P.string "u0007"
-                                , '\BS'  <$ P.string "u0008"
-                                , '\VT'  <$ P.string "u000b"
-                                , '\FF'  <$ P.string "u000c"
-                                , '\CR'  <$ P.string "u000d"
-                                , '\SO'  <$ P.string "u000e"
-                                , '\SI'  <$ P.string "u000f"
-                                , '\DLE' <$ P.string "u0010"
-                                , '\DC1' <$ P.string "u0011"
-                                , '\DC2' <$ P.string "u0012"
-                                , '\DC3' <$ P.string "u0013"
-                                , '\DC4' <$ P.string "u0014"
-                                , '\NAK' <$ P.string "u0015"
-                                , '\SYN' <$ P.string "u0016"
-                                , '\ETB' <$ P.string "u0017"
-                                , '\CAN' <$ P.string "u0018"
-                                , '\EM'  <$ P.string "u0019"
-                                , '\SUB' <$ P.string "u001a"
-                                , '\ESC' <$ P.string "u001b"
-                                , '\FS'  <$ P.string "u001c"
-                                , '\GS'  <$ P.string "u001d"
-                                , '\RS'  <$ P.string "u001e"
-                                , '\US'  <$ P.string "u001f"
-                                , '\DEL' <$ P.string "u007f"
-                                , '\0' <$ PC.char '0'
-                                , '\a' <$ PC.char 'a'
-                                , '\b' <$ PC.char 'b'
-                                , '\f' <$ PC.char 'f'
-                                , '\n' <$ PC.char 'n'
-                                , '\r' <$ PC.char 'r'
-                                , '\t' <$ PC.char 't'
-                                , '\v' <$ PC.char 'v'
-                                , '\"' <$ PC.char '"'
-                                , '\'' <$ PC.char '\''
-                                , '\\' <$ PC.char '\\'
-                                , '/'  <$ PC.char '/'
-                                ])
-
-escape :: LBS.ByteString -> Builder
-escape = LBS.foldl' escapeChar mempty
-  where
-    escapeChar b w = b <> (B.lazyByteString $ case w2c w of
-      '\0' -> "\\0"
-      '\b' -> "\\b"
-      '\f' -> "\\f"
-      '\n' -> "\\n"
-      '\r' -> "\\r"
-      '\t' -> "\\t"
-      '\"' -> "\\\""
-      '\\' -> "\\\\"
-      '\SOH' -> "\\u0001"
-      '\STX' -> "\\u0002"
-      '\ETX' -> "\\u0003"
-      '\EOT' -> "\\u0004"
-      '\ENQ' -> "\\u0005"
-      '\ACK' -> "\\u0006"
-      '\BEL' -> "\\u0007"
-      '\VT'  -> "\\u000b"
-      '\SO'  -> "\\u000e"
-      '\SI'  -> "\\u000f"
-      '\DLE' -> "\\u0010"
-      '\DC1' -> "\\u0011"
-      '\DC2' -> "\\u0012"
-      '\DC3' -> "\\u0013"
-      '\DC4' -> "\\u0014"
-      '\NAK' -> "\\u0015"
-      '\SYN' -> "\\u0016"
-      '\ETB' -> "\\u0017"
-      '\CAN' -> "\\u0018"
-      '\EM'  -> "\\u0019"
-      '\SUB' -> "\\u001a"
-      '\ESC' -> "\\u001b"
-      '\FS'  -> "\\u001c"
-      '\GS'  -> "\\u001d"
-      '\RS'  -> "\\u001e"
-      '\US'  -> "\\u001f"
-      '\DEL' -> "\\u007f"
-      _ -> LBS.singleton w)
-
-lexeme :: Parser a -> Parser a
-lexeme = (<* skipSpace)
-
-notChar8 :: Char -> Parser Word8
-notChar8 c = P.satisfy (/= c2w c)
-
-between :: Char -> Char -> Parser a -> Parser a
-between a b p = lexeme (PC.char8 a) *> lexeme p <* lexeme (PC.char8 b)
-
-getTypeName :: ThriftType -> Builder
-getTypeName ty = B.string8 $ case ty of
-  T_STRUCT _ -> "rec"
-  T_MAP _ _  -> "map"
-  T_LIST _   -> "lst"
-  T_SET _    -> "set"
-  T_BOOL     -> "tf"
-  T_BYTE     -> "i8"
-  T_I16      -> "i16"
-  T_I32      -> "i32"
-  T_I64      -> "i64"
-  T_DOUBLE   -> "dbl"
-  T_STRING   -> "str"
-  T_BINARY   -> "str"
-  _ -> error "Unrecognized Type"
-
diff --git a/lib/hs/src/Thrift/Server.hs b/lib/hs/src/Thrift/Server.hs
deleted file mode 100644
index 543f338..0000000
--- a/lib/hs/src/Thrift/Server.hs
+++ /dev/null
@@ -1,66 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables #-}
---
--- 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.Server
-    ( runBasicServer
-    , runThreadedServer
-    ) where
-
-import Control.Concurrent ( forkIO )
-import Control.Exception
-import Control.Monad ( forever, when )
-
-import Network
-
-import System.IO
-
-import Thrift
-import Thrift.Transport.Handle()
-import Thrift.Protocol.Binary
-
-
--- | A threaded sever that is capable of using any Transport or Protocol
--- instances.
-runThreadedServer :: (Protocol i, Protocol o)
-                  => (Socket -> IO (i, o))
-                  -> h
-                  -> (h -> (i, o) -> IO Bool)
-                  -> PortID
-                  -> IO a
-runThreadedServer accepter hand proc_ port = do
-    socket <- listenOn port
-    acceptLoop (accepter socket) (proc_ hand)
-
--- | A basic threaded binary protocol socket server.
-runBasicServer :: h
-               -> (h -> (BinaryProtocol Handle, BinaryProtocol Handle) -> IO Bool)
-               -> PortNumber
-               -> IO a
-runBasicServer hand proc_ port = runThreadedServer binaryAccept hand proc_ (PortNumber port)
-  where binaryAccept s = do
-            (h, _, _) <- accept s
-            return (BinaryProtocol h, BinaryProtocol h)
-
-acceptLoop :: IO t -> (t -> IO Bool) -> IO a
-acceptLoop accepter proc_ = forever $
-    do ps <- accepter
-       forkIO $ handle (\(_ :: SomeException) -> return ())
-                  (loop $ proc_ ps)
-  where loop m = do { continue <- m; when continue (loop m) }
diff --git a/lib/hs/src/Thrift/Transport.hs b/lib/hs/src/Thrift/Transport.hs
deleted file mode 100644
index 306edc2..0000000
--- a/lib/hs/src/Thrift/Transport.hs
+++ /dev/null
@@ -1,65 +0,0 @@
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
---
--- 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.Transport
-  ( Transport(..)
-  , TransportExn(..)
-  , TransportExnType(..)
-  ) where
-
-import Control.Monad ( when )
-import Control.Exception ( Exception, throw )
-import Data.Functor ( (<$>) )
-import Data.Typeable ( Typeable )
-import Data.Word
-
-import qualified Data.ByteString.Lazy as LBS
-import Data.Monoid
-
-class Transport a where
-    tIsOpen :: a -> IO Bool
-    tClose  :: a -> IO ()
-    tRead   :: a -> Int -> IO LBS.ByteString
-    tPeek   :: a -> IO (Maybe Word8)
-    tWrite  :: a -> LBS.ByteString -> IO ()
-    tFlush  :: a -> IO ()
-    tReadAll :: a -> Int -> IO LBS.ByteString
-
-    tReadAll _ 0 = return mempty
-    tReadAll a len = do
-        result <- tRead a len
-        let rlen = fromIntegral $ LBS.length result
-        when (rlen == 0) (throw $ TransportExn "Cannot read. Remote side has closed." TE_UNKNOWN)
-        if len <= rlen
-          then return result
-          else (result `mappend`) <$> tReadAll a (len - rlen)
-
-data TransportExn = TransportExn String TransportExnType
-  deriving ( Show, Typeable )
-instance Exception TransportExn
-
-data TransportExnType
-    = TE_UNKNOWN
-    | TE_NOT_OPEN
-    | TE_ALREADY_OPEN
-    | TE_TIMED_OUT
-    | TE_END_OF_FILE
-      deriving ( Eq, Show, Typeable )
diff --git a/lib/hs/src/Thrift/Transport/Empty.hs b/lib/hs/src/Thrift/Transport/Empty.hs
deleted file mode 100644
index 47af5fe..0000000
--- a/lib/hs/src/Thrift/Transport/Empty.hs
+++ /dev/null
@@ -1,36 +0,0 @@
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE OverloadedStrings #-}
---
--- 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.Transport.Empty
-       ( EmptyTransport(..)
-       ) where
-
-import Thrift.Transport
-
-data EmptyTransport = EmptyTransport
-
-instance Transport EmptyTransport where
-    tIsOpen = const $ return False
-    tClose  = const $ return ()
-    tRead _ _ = return ""
-    tPeek = const $ return Nothing
-    tWrite _ _ = return ()
-    tFlush = const$ return ()
diff --git a/lib/hs/src/Thrift/Transport/Framed.hs b/lib/hs/src/Thrift/Transport/Framed.hs
deleted file mode 100644
index ad553ae..0000000
--- a/lib/hs/src/Thrift/Transport/Framed.hs
+++ /dev/null
@@ -1,99 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
---
--- 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.Transport.Framed
-    ( module Thrift.Transport
-    , FramedTransport
-    , openFramedTransport
-    ) where
-
-import Thrift.Transport
-import Thrift.Transport.IOBuffer
-
-import Data.Int (Int32)
-import qualified Data.Binary as B
-import qualified Data.ByteString.Lazy as LBS
-
-
--- | FramedTransport wraps a given transport in framed mode.
-data FramedTransport t = FramedTransport {
-      wrappedTrans :: t,           -- ^ Underlying transport.
-      writeBuffer  :: WriteBuffer, -- ^ Write buffer.
-      readBuffer   :: ReadBuffer   -- ^ Read buffer.
-    }
-
--- | Create a new framed transport which wraps the given transport.
-openFramedTransport :: Transport t => t -> IO (FramedTransport t)
-openFramedTransport trans = do
-  wbuf <- newWriteBuffer
-  rbuf <- newReadBuffer
-  return FramedTransport{ wrappedTrans = trans, writeBuffer = wbuf, readBuffer = rbuf }
-
-instance Transport t => Transport (FramedTransport t) where
-
-    tClose = tClose . wrappedTrans
-
-    tRead trans n = do
-      -- First, check the read buffer for any data.
-      bs <- readBuf (readBuffer trans) n
-      if LBS.null bs
-         then
-         -- When the buffer is empty, read another frame from the
-         -- underlying transport.
-           do len <- readFrame trans
-              if len > 0
-                 then tRead trans n
-                 else return bs
-         else return bs
-    tPeek trans = do
-      mw <- peekBuf (readBuffer trans)
-      case mw of
-        Just _ -> return mw
-        Nothing -> do
-          len <- readFrame trans
-          if len > 0
-             then tPeek trans
-             else return Nothing
-
-    tWrite = writeBuf . writeBuffer
-
-    tFlush trans = do
-      bs <- flushBuf (writeBuffer trans)
-      let szBs = B.encode $ (fromIntegral $ LBS.length bs :: Int32)
-      tWrite (wrappedTrans trans) szBs
-      tWrite (wrappedTrans trans) bs
-      tFlush (wrappedTrans trans)
-
-    tIsOpen = tIsOpen . wrappedTrans
-
-readFrame :: Transport t => FramedTransport t -> IO Int
-readFrame trans = do
-  -- Read and decode the frame size.
-  szBs <- tReadAll (wrappedTrans trans) 4
-  let sz = fromIntegral (B.decode szBs :: Int32)
-
-  -- Read the frame and stuff it into the read buffer.
-  bs <- tReadAll (wrappedTrans trans) sz
-  fillBuf (readBuffer trans) bs
-
-  -- Return the frame size so that the caller knows whether to expect
-  -- something in the read buffer or not.
-  return sz
diff --git a/lib/hs/src/Thrift/Transport/Handle.hs b/lib/hs/src/Thrift/Transport/Handle.hs
deleted file mode 100644
index 528a027..0000000
--- a/lib/hs/src/Thrift/Transport/Handle.hs
+++ /dev/null
@@ -1,85 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeSynonymInstances #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
---
--- 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.Transport.Handle
-    ( module Thrift.Transport
-    , HandleSource(..)
-    ) where
-
-import Control.Exception ( catch, throw )
-import Control.Monad ( when )
-import Data.ByteString.Internal (c2w)
-import Data.Functor
-
-import Network
-
-import System.IO
-import System.IO.Error ( isEOFError )
-
-import Thrift.Transport
-
-import qualified Data.ByteString.Lazy as LBS
-import Data.Monoid
-
-instance Transport Handle where
-    tIsOpen = hIsOpen
-    tClose = hClose
-    tRead h n = read `Control.Exception.catch` handleEOF mempty
-      where
-        read = do
-          hLookAhead h
-          LBS.hGetNonBlocking h n
-    tReadAll _ 0 = return mempty
-    tReadAll h n = do
-      result <- LBS.hGet h n `Control.Exception.catch` throwTransportExn
-      let rlen = fromIntegral $ LBS.length result
-      when (rlen == 0) (throw $ TransportExn "Cannot read. Remote side has closed." TE_UNKNOWN)
-      if n <= rlen
-        then return result
-        else (result `mappend`) <$> tReadAll h (n - rlen)
-    tPeek h = (Just . c2w <$> hLookAhead h) `Control.Exception.catch` handleEOF Nothing
-    tWrite = LBS.hPut
-    tFlush = hFlush
-
-
--- | Type class for all types that can open a Handle. This class is used to
--- replace tOpen in the Transport type class.
-class HandleSource s where
-    hOpen :: s -> IO Handle
-
-instance HandleSource FilePath where
-    hOpen s = openFile s ReadWriteMode
-
-instance HandleSource (HostName, PortID) where
-    hOpen = uncurry connectTo
-
-throwTransportExn :: IOError -> IO a
-throwTransportExn e = if isEOFError e
-    then throw $ TransportExn "Cannot read. Remote side has closed." TE_UNKNOWN
-    else throw $ TransportExn "Handle tReadAll: Could not read" TE_UNKNOWN
-
-handleEOF :: a -> IOError -> IO a
-handleEOF a e = if isEOFError e
-    then return a
-    else throw $ TransportExn "Handle: Could not read" TE_UNKNOWN
diff --git a/lib/hs/src/Thrift/Transport/Header.hs b/lib/hs/src/Thrift/Transport/Header.hs
deleted file mode 100644
index 2dacad2..0000000
--- a/lib/hs/src/Thrift/Transport/Header.hs
+++ /dev/null
@@ -1,354 +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.
---
-
-module Thrift.Transport.Header
-  ( module Thrift.Transport
-  , HeaderTransport(..)
-  , openHeaderTransport
-  , ProtocolType(..)
-  , TransformType(..)
-  , ClientType(..)
-  , tResetProtocol
-  , tSetProtocol
-  ) where
-
-import Thrift.Transport
-import Thrift.Protocol.Compact
-import Control.Applicative
-import Control.Exception ( throw )
-import Control.Monad
-import Data.Bits
-import Data.IORef
-import Data.Int
-import Data.Monoid
-import Data.Word
-
-import qualified Data.Attoparsec.ByteString as P
-import qualified Data.Binary as Binary
-import qualified Data.ByteString as BS
-import qualified Data.ByteString.Char8 as C
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.ByteString.Lazy.Builder as B
-import qualified Data.Map as Map
-
-data ProtocolType = TBinary | TCompact | TJSON deriving (Enum, Eq)
-data ClientType = HeaderClient | Framed | Unframed deriving (Enum, Eq)
-
-infoIdKeyValue = 1
-
-type Headers = Map.Map String String
-
-data TransformType = ZlibTransform deriving (Enum, Eq)
-
-fromTransportType :: TransformType -> Int16
-fromTransportType ZlibTransform = 1
-
-toTransportType :: Int16 -> TransformType
-toTransportType 1 = ZlibTransform
-toTransportType _ =  throw $ TransportExn "HeaderTransport: Unknown transform ID" TE_UNKNOWN
-
-data HeaderTransport i o = (Transport i, Transport o) => HeaderTransport
-    { readBuffer :: IORef LBS.ByteString
-    , writeBuffer :: IORef B.Builder
-    , inTrans :: i
-    , outTrans :: o
-    , clientType :: IORef ClientType
-    , protocolType :: IORef ProtocolType
-    , headers :: IORef [(String, String)]
-    , writeHeaders :: Headers
-    , transforms :: IORef [TransformType]
-    , writeTransforms :: [TransformType]
-    }
-
-openHeaderTransport :: (Transport i, Transport o) => i -> o -> IO (HeaderTransport i o)
-openHeaderTransport i o = do
-  pid <- newIORef TCompact
-  rBuf <- newIORef LBS.empty
-  wBuf <- newIORef mempty
-  cType <- newIORef HeaderClient
-  h <- newIORef []
-  trans <- newIORef []
-  return HeaderTransport
-      { readBuffer = rBuf
-      , writeBuffer = wBuf
-      , inTrans = i
-      , outTrans = o
-      , clientType = cType
-      , protocolType = pid
-      , headers = h
-      , writeHeaders = Map.empty
-      , transforms = trans
-      , writeTransforms = []
-      }
-
-isFramed t = (/= Unframed) <$> readIORef (clientType t)
-
-readFrame :: (Transport i, Transport o) => HeaderTransport i o -> IO Bool
-readFrame t = do
-  let input = inTrans t
-  let rBuf = readBuffer t
-  let cType = clientType t
-  lsz <- tRead input 4
-  let sz = LBS.toStrict lsz
-  case P.parseOnly P.endOfInput sz of
-    Right _ -> do return False
-    Left _ -> do
-      case parseBinaryMagic sz of
-        Right _ -> do
-          writeIORef rBuf $ lsz
-          writeIORef cType Unframed
-          writeIORef (protocolType t) TBinary
-          return True
-        Left _ -> do
-          case parseCompactMagic sz of
-            Right _ -> do
-              writeIORef rBuf $ lsz
-              writeIORef cType Unframed
-              writeIORef (protocolType t) TCompact
-              return True
-            Left _ -> do
-              let len = Binary.decode lsz :: Int32
-              lbuf <- tReadAll input $ fromIntegral len
-              let buf = LBS.toStrict lbuf
-              case parseBinaryMagic buf of
-                Right _ -> do
-                  writeIORef cType Framed
-                  writeIORef (protocolType t) TBinary
-                  writeIORef rBuf lbuf
-                  return True
-                Left _ -> do
-                  case parseCompactMagic buf of
-                    Right _ -> do
-                      writeIORef cType Framed
-                      writeIORef (protocolType t) TCompact
-                      writeIORef rBuf lbuf
-                      return True
-                    Left _ -> do
-                      case parseHeaderMagic buf of
-                        Right flags -> do
-                          let (flags, seqNum, header, body) = extractHeader buf
-                          writeIORef cType HeaderClient
-                          handleHeader t header
-                          payload <- untransform t body
-                          writeIORef rBuf $ LBS.fromStrict $ payload
-                          return True
-                        Left _ ->
-                          throw $ TransportExn "HeaderTransport: unkonwn client type" TE_UNKNOWN
-
-parseBinaryMagic = P.parseOnly $ P.word8 0x80 *> P.word8 0x01 *> P.word8 0x00 *> P.anyWord8
-parseCompactMagic = P.parseOnly $ P.word8 0x82 *> P.satisfy (\b -> b .&. 0x1f == 0x01)
-parseHeaderMagic = P.parseOnly $ P.word8 0x0f *> P.word8 0xff *> (P.count 2 P.anyWord8)
-
-parseI32 :: P.Parser Int32
-parseI32 = Binary.decode . LBS.fromStrict <$> P.take 4
-parseI16 :: P.Parser Int16
-parseI16 = Binary.decode . LBS.fromStrict <$> P.take 2
-
-extractHeader :: BS.ByteString -> (Int16, Int32, BS.ByteString, BS.ByteString)
-extractHeader bs =
-  case P.parse extractHeader_ bs of
-    P.Done remain (flags, seqNum, header) -> (flags, seqNum, header, remain)
-    _ -> throw $ TransportExn "HeaderTransport: Invalid header" TE_UNKNOWN
-  where
-    extractHeader_ = do
-      magic <- P.word8 0x0f *> P.word8 0xff
-      flags <- parseI16
-      seqNum <- parseI32
-      (headerSize :: Int) <- (* 4) . fromIntegral <$> parseI16
-      header <- P.take headerSize
-      return (flags, seqNum, header)
-
-handleHeader t header =
-  case P.parseOnly parseHeader header of
-    Right (pType, trans, info) -> do
-      writeIORef (protocolType t) pType
-      writeIORef (transforms t) trans
-      writeIORef (headers t) info
-    _ -> throw $ TransportExn "HeaderTransport: Invalid header" TE_UNKNOWN
-
-
-iw16 :: Int16 -> Word16
-iw16 = fromIntegral
-iw32 :: Int32 -> Word32
-iw32 = fromIntegral
-wi16 :: Word16 -> Int16
-wi16 = fromIntegral
-wi32 :: Word32 -> Int32
-wi32 = fromIntegral
-
-parseHeader :: P.Parser (ProtocolType, [TransformType], [(String, String)])
-parseHeader = do
-  protocolType <- toProtocolType <$> parseVarint wi16
-  numTrans <- fromIntegral <$> parseVarint wi16
-  trans <- replicateM numTrans parseTransform
-  info <- parseInfo
-  return (protocolType, trans, info)
-
-toProtocolType :: Int16 -> ProtocolType
-toProtocolType 0 = TBinary
-toProtocolType 1 = TJSON
-toProtocolType 2 = TCompact
-
-fromProtocolType :: ProtocolType -> Int16
-fromProtocolType TBinary = 0
-fromProtocolType TJSON = 1
-fromProtocolType TCompact = 2
-
-parseTransform :: P.Parser TransformType
-parseTransform = toTransportType <$> parseVarint wi16
-
-parseInfo :: P.Parser [(String, String)]
-parseInfo = do
-  n <- P.eitherP P.endOfInput (parseVarint wi32)
-  case n of
-    Left _ -> return []
-    Right n0 ->
-      replicateM (fromIntegral n0) $ do
-        klen <- parseVarint wi16
-        k <- P.take $ fromIntegral klen
-        vlen <- parseVarint wi16
-        v <- P.take $ fromIntegral vlen
-        return (C.unpack k, C.unpack v)
-
-parseString :: P.Parser BS.ByteString
-parseString = parseVarint wi32 >>= (P.take . fromIntegral)
-
-buildHeader :: HeaderTransport i o -> IO B.Builder
-buildHeader t = do
-  pType <- readIORef $ protocolType t
-  let pId = buildVarint $ iw16 $ fromProtocolType pType
-  let headerContent = pId <> (buildTransforms t) <> (buildInfo t)
-  let len = fromIntegral $ LBS.length $ B.toLazyByteString headerContent
-  -- TODO: length limit check
-  let padding = mconcat $ replicate (mod len 4) $ B.word8 0
-  let codedLen = B.int16BE (fromIntegral $ (quot (len - 1) 4) + 1)
-  let flags = 0
-  let seqNum = 0
-  return $ B.int16BE 0x0fff <> B.int16BE flags <> B.int32BE seqNum <> codedLen <> headerContent <> padding
-
-buildTransforms :: HeaderTransport i o -> B.Builder
--- TODO: check length limit
-buildTransforms t =
-  let trans = writeTransforms t in
-  (buildVarint $ iw16 $ fromIntegral $ length trans) <>
-  (mconcat $ map (buildVarint . iw16 . fromTransportType) trans)
-
-buildInfo :: HeaderTransport i o -> B.Builder
-buildInfo t =
-  let h = Map.assocs $ writeHeaders t in
-  -- TODO: check length limit
-  case length h of
-    0 -> mempty
-    len -> (buildVarint $ iw16 $ fromIntegral $ len) <> (mconcat $ map buildInfoEntry h)
-  where
-    buildInfoEntry (k, v) = buildVarStr k <> buildVarStr v
-    -- TODO: check length limit
-    buildVarStr s = (buildVarint $ iw16 $ fromIntegral $ length s) <> B.string8 s
-
-tResetProtocol :: (Transport i, Transport o) => HeaderTransport i o -> IO Bool
-tResetProtocol t = do
-  rBuf <- readIORef $ readBuffer t
-  writeIORef (clientType t) HeaderClient
-  readFrame t
-
-tSetProtocol :: (Transport i, Transport o) => HeaderTransport i o -> ProtocolType -> IO ()
-tSetProtocol t = writeIORef (protocolType t)
-
-transform :: HeaderTransport i o -> LBS.ByteString -> LBS.ByteString
-transform t bs =
-  foldr applyTransform bs $ writeTransforms t
-  where
-    -- applyTransform bs ZlibTransform =
-    --   throw $ TransportExn "HeaderTransport: not implemented: ZlibTransform  " TE_UNKNOWN
-    applyTransform bs _ =
-      throw $ TransportExn "HeaderTransport: Unknown transform" TE_UNKNOWN
-
-untransform :: HeaderTransport i o -> BS.ByteString -> IO BS.ByteString
-untransform t bs = do
-  trans <- readIORef $ transforms t
-  return $ foldl unapplyTransform bs trans
-  where
-    -- unapplyTransform bs ZlibTransform =
-    --   throw $ TransportExn "HeaderTransport: not implemented: ZlibTransform  " TE_UNKNOWN
-    unapplyTransform bs _ =
-      throw $ TransportExn "HeaderTransport: Unknown transform" TE_UNKNOWN
-
-instance (Transport i, Transport o) => Transport (HeaderTransport i o) where
-  tIsOpen t = do
-    tIsOpen (inTrans t)
-    tIsOpen (outTrans t)
-
-  tClose t = do
-    tClose(outTrans t)
-    tClose(inTrans t)
-
-  tRead t len = do
-    rBuf <- readIORef $ readBuffer t
-    if not $ LBS.null rBuf
-      then do
-        let (consumed, remain) = LBS.splitAt (fromIntegral len) rBuf
-        writeIORef (readBuffer t) remain
-        return consumed
-      else do
-        framed <- isFramed t
-        if not framed
-          then tRead (inTrans t) len
-          else do
-            ok <- readFrame t
-            if ok
-              then tRead t len
-              else return LBS.empty
-
-  tPeek t = do
-    rBuf <- readIORef (readBuffer t)
-    if not $ LBS.null rBuf
-      then return $ Just $ LBS.head rBuf
-      else do
-        framed <- isFramed t
-        if not framed
-          then tPeek (inTrans t)
-          else do
-            ok <- readFrame t
-            if ok
-              then tPeek t
-              else return Nothing
-
-  tWrite t buf = do
-    let wBuf = writeBuffer t
-    framed <- isFramed t
-    if framed
-      then modifyIORef wBuf (<> B.lazyByteString buf)
-      else
-        -- TODO: what should we do when switched to unframed in the middle ?
-        tWrite(outTrans t) buf
-
-  tFlush t = do
-    cType <- readIORef $ clientType t
-    case cType of
-      Unframed -> tFlush $ outTrans t
-      Framed -> flushBuffer t id mempty
-      HeaderClient -> buildHeader t >>= flushBuffer t (transform t)
-    where
-      flushBuffer t f header = do
-        wBuf <- readIORef $ writeBuffer t
-        writeIORef (writeBuffer t) mempty
-        let payload = B.toLazyByteString (header <> wBuf)
-        tWrite (outTrans t) $ Binary.encode (fromIntegral $ LBS.length payload :: Int32)
-        tWrite (outTrans t) $ f payload
-        tFlush (outTrans t)
diff --git a/lib/hs/src/Thrift/Transport/HttpClient.hs b/lib/hs/src/Thrift/Transport/HttpClient.hs
deleted file mode 100644
index edeb320..0000000
--- a/lib/hs/src/Thrift/Transport/HttpClient.hs
+++ /dev/null
@@ -1,101 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
---
--- 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.Transport.HttpClient
-    ( module Thrift.Transport
-    , HttpClient (..)
-    , openHttpClient
-) where
-
-import Thrift.Transport
-import Thrift.Transport.IOBuffer
-import Network.URI
-import Network.HTTP hiding (port, host)
-
-import Data.Maybe (fromJust)
-import Data.Monoid (mempty)
-import Control.Exception (throw)
-import qualified Data.ByteString.Lazy as LBS
-
-
--- | 'HttpClient', or THttpClient implements the Thrift Transport
--- | Layer over http or https.
-data HttpClient =
-    HttpClient {
-      hstream :: HandleStream LBS.ByteString,
-      uri :: URI,
-      writeBuffer :: WriteBuffer,
-      readBuffer :: ReadBuffer
-    }
-
-uriAuth :: URI -> URIAuth
-uriAuth = fromJust . uriAuthority
-
-host :: URI -> String
-host = uriRegName . uriAuth
-
-port :: URI -> Int
-port uri_ =
-    if portStr == mempty then
-        httpPort
-    else
-        read portStr
-    where
-      portStr = dropWhile (== ':') $ uriPort $ uriAuth uri_
-      httpPort = 80
-
--- | Use 'openHttpClient' to create an HttpClient connected to @uri@
-openHttpClient :: URI -> IO HttpClient
-openHttpClient uri_ = do
-  stream <- openTCPConnection (host uri_) (port uri_)
-  wbuf <- newWriteBuffer
-  rbuf <- newReadBuffer
-  return $ HttpClient stream uri_ wbuf rbuf
-
-instance Transport HttpClient where
-
-    tClose = close . hstream
-
-    tPeek = peekBuf . readBuffer
-
-    tRead = readBuf . readBuffer
-
-    tWrite = writeBuf . writeBuffer
-
-    tFlush hclient = do
-      body <- flushBuf $ writeBuffer hclient
-      let request = Request {
-                      rqURI = uri hclient,
-                      rqHeaders = [
-                       mkHeader HdrContentType "application/x-thrift",
-                       mkHeader HdrContentLength $  show $ LBS.length body],
-                      rqMethod = POST,
-                      rqBody = body
-                    }
-
-      res <- sendHTTP (hstream hclient) request
-      case res of
-        Right response ->
-          fillBuf (readBuffer hclient) (rspBody response)
-        Left _ ->
-            throw $ TransportExn "THttpConnection: HTTP failure from server" TE_UNKNOWN
-      return ()
-
-    tIsOpen _ = return True
diff --git a/lib/hs/src/Thrift/Transport/IOBuffer.hs b/lib/hs/src/Thrift/Transport/IOBuffer.hs
deleted file mode 100644
index 7ebd7d8..0000000
--- a/lib/hs/src/Thrift/Transport/IOBuffer.hs
+++ /dev/null
@@ -1,69 +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.
---
-
-module Thrift.Transport.IOBuffer
-       ( WriteBuffer
-       , newWriteBuffer
-       , writeBuf
-       , flushBuf
-       , ReadBuffer
-       , newReadBuffer
-       , fillBuf
-       , readBuf
-       , peekBuf
-       ) where
-
-import Data.ByteString.Lazy.Builder
-import Data.Functor
-import Data.IORef
-import Data.Monoid
-import Data.Word
-
-import qualified Data.ByteString.Lazy as LBS
-
-type WriteBuffer = IORef Builder
-type ReadBuffer = IORef LBS.ByteString
-
-newWriteBuffer :: IO WriteBuffer
-newWriteBuffer = newIORef mempty
-
-writeBuf :: WriteBuffer -> LBS.ByteString -> IO ()
-writeBuf w s = modifyIORef w ( <> lazyByteString s)
-
-flushBuf :: WriteBuffer -> IO LBS.ByteString
-flushBuf w = do
-  buf <- readIORef w
-  writeIORef w mempty
-  return $ toLazyByteString buf
-
-newReadBuffer :: IO ReadBuffer
-newReadBuffer = newIORef mempty
-
-fillBuf :: ReadBuffer -> LBS.ByteString -> IO ()
-fillBuf = writeIORef
-
-readBuf :: ReadBuffer -> Int -> IO LBS.ByteString
-readBuf r n = do
-  bs <- readIORef r
-  let (hd, tl) = LBS.splitAt (fromIntegral n) bs
-  writeIORef r tl
-  return hd
-
-peekBuf :: ReadBuffer -> IO (Maybe Word8)
-peekBuf r = (fmap fst . LBS.uncons) <$> readIORef r
diff --git a/lib/hs/src/Thrift/Transport/Memory.hs b/lib/hs/src/Thrift/Transport/Memory.hs
deleted file mode 100644
index 1c93af6..0000000
--- a/lib/hs/src/Thrift/Transport/Memory.hs
+++ /dev/null
@@ -1,77 +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.
---
-
-module Thrift.Transport.Memory
-       ( openMemoryBuffer
-       , MemoryBuffer(..)
-       ) where
-
-import Data.ByteString.Lazy.Builder
-import Data.Functor
-import Data.IORef
-import Data.Monoid
-import qualified Data.ByteString.Lazy as LBS
-
-import Thrift.Transport
-
-
-data MemoryBuffer = MemoryBuffer {
-  writeBuffer :: IORef Builder,
-  readBuffer :: IORef LBS.ByteString
-}
-
-openMemoryBuffer :: IO MemoryBuffer
-openMemoryBuffer = do
-  wbuf <- newIORef mempty
-  rbuf <- newIORef mempty
-  return MemoryBuffer {
-    writeBuffer = wbuf,
-    readBuffer = rbuf
-  }
-
-instance Transport MemoryBuffer where
-  tIsOpen = const $ return False
-  tClose  = const $ return ()
-  tFlush trans = do
-    let wBuf = writeBuffer trans
-    wb <- readIORef wBuf
-    modifyIORef (readBuffer trans) $ \rb -> mappend rb $ toLazyByteString wb
-    writeIORef wBuf mempty
-
-  tRead _ 0 = return mempty
-  tRead trans n = do
-    let rbuf = readBuffer trans
-    rb <- readIORef rbuf
-    let len = fromIntegral $ LBS.length rb
-    if len == 0
-      then do
-        tFlush trans
-        rb2 <- readIORef (readBuffer trans)
-        if (fromIntegral $ LBS.length rb2) == 0
-          then return mempty
-          else tRead trans n
-      else do
-        let (ret, remain) = LBS.splitAt (fromIntegral n) rb
-        writeIORef rbuf remain
-        return ret
-
-  tPeek trans = (fmap fst . LBS.uncons) <$> readIORef (readBuffer trans)
-
-  tWrite trans v = do
-    modifyIORef (writeBuffer trans) (<> lazyByteString v)
diff --git a/lib/hs/src/Thrift/Types.hs b/lib/hs/src/Thrift/Types.hs
deleted file mode 100644
index 2a20025..0000000
--- a/lib/hs/src/Thrift/Types.hs
+++ /dev/null
@@ -1,130 +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.
---
-
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-
-module Thrift.Types where
-
-import Data.Foldable (foldl')
-import Data.Hashable ( Hashable, hashWithSalt )
-import Data.Int
-import Test.QuickCheck.Arbitrary
-import Test.QuickCheck.Gen (elements)
-import Data.Text.Lazy (Text)
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.HashMap.Strict as Map
-import qualified Data.HashSet as Set
-import qualified Data.Vector as Vector
-
-instance (Hashable a) => Hashable (Vector.Vector a) where
-  hashWithSalt = Vector.foldl' hashWithSalt
-
-
-type TypeMap = Map.HashMap Int16 (Text, ThriftType)
-
-data ThriftVal = TStruct (Map.HashMap Int16 (Text, ThriftVal))
-               | TMap ThriftType ThriftType [(ThriftVal, ThriftVal)]
-               | TList ThriftType [ThriftVal]
-               | TSet ThriftType [ThriftVal]
-               | TBool Bool
-               | TByte Int8
-               | TI16 Int16
-               | TI32 Int32
-               | TI64 Int64
-               | TString LBS.ByteString
-               | TBinary LBS.ByteString
-               | TDouble Double
-                 deriving (Eq, Show)
-
--- Information is needed here for collection types (ie T_STRUCT, T_MAP,
--- T_LIST, and T_SET) so that we know what types those collections are
--- parameterized by.  In most protocols, this cannot be discerned directly
--- from the data being read.
-data ThriftType
-    = T_STOP
-    | T_VOID
-    | T_BOOL
-    | T_BYTE
-    | T_DOUBLE
-    | T_I16
-    | T_I32
-    | T_I64
-    | T_STRING
-    | T_BINARY
-    | T_STRUCT TypeMap
-    | T_MAP ThriftType ThriftType
-    | T_SET ThriftType
-    | T_LIST ThriftType
-      deriving ( Eq, Show )
-
--- NOTE: when using toEnum information about parametized types is NOT preserved.
--- This design choice is consistent woth the Thrift implementation in other
--- languages
-instance Enum ThriftType where
-    fromEnum T_STOP       = 0
-    fromEnum T_VOID       = 1
-    fromEnum T_BOOL       = 2
-    fromEnum T_BYTE       = 3
-    fromEnum T_DOUBLE     = 4
-    fromEnum T_I16        = 6
-    fromEnum T_I32        = 8
-    fromEnum T_I64        = 10
-    fromEnum T_STRING     = 11
-    fromEnum T_BINARY     = 11
-    fromEnum (T_STRUCT _) = 12
-    fromEnum (T_MAP _ _)  = 13
-    fromEnum (T_SET _)    = 14
-    fromEnum (T_LIST _)   = 15
-
-    toEnum 0  = T_STOP
-    toEnum 1  = T_VOID
-    toEnum 2  = T_BOOL
-    toEnum 3  = T_BYTE
-    toEnum 4  = T_DOUBLE
-    toEnum 6  = T_I16
-    toEnum 8  = T_I32
-    toEnum 10 = T_I64
-    toEnum 11 = T_STRING
-    -- toEnum 11 = T_BINARY
-    toEnum 12 = T_STRUCT Map.empty
-    toEnum 13 = T_MAP T_VOID T_VOID
-    toEnum 14 = T_SET T_VOID
-    toEnum 15 = T_LIST T_VOID
-    toEnum t = error $ "Invalid ThriftType " ++ show t
-
-data MessageType
-    = M_CALL
-    | M_REPLY
-    | M_EXCEPTION
-    | M_ONEWAY
-      deriving ( Eq, Show )
-
-instance Enum MessageType where
-    fromEnum M_CALL      =  1
-    fromEnum M_REPLY     =  2
-    fromEnum M_EXCEPTION =  3
-    fromEnum M_ONEWAY    =  4
-
-    toEnum 1 = M_CALL
-    toEnum 2 = M_REPLY
-    toEnum 3 = M_EXCEPTION
-    toEnum 4 = M_ONEWAY
-    toEnum t = error $ "Invalid MessageType " ++ show t
-
-instance Arbitrary MessageType where
-  arbitrary = elements [M_CALL, M_REPLY, M_EXCEPTION, M_ONEWAY]
diff --git a/lib/hs/test/BinarySpec.hs b/lib/hs/test/BinarySpec.hs
deleted file mode 100644
index d692fab..0000000
--- a/lib/hs/test/BinarySpec.hs
+++ /dev/null
@@ -1,91 +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.
---
-
-module BinarySpec where
-
-import Test.Hspec
-import Test.Hspec.QuickCheck (prop)
-
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.ByteString.Lazy.Char8 as C
-
-import Thrift.Types
-import Thrift.Transport
-import Thrift.Transport.Memory
-import Thrift.Protocol
-import Thrift.Protocol.Binary
-
-spec :: Spec
-spec = do
-  describe "BinaryProtocol" $ do
-    describe "double" $ do
-      it "writes in big endian order" $ do
-        let val = 2 ** 53
-        trans <- openMemoryBuffer
-        let proto = BinaryProtocol trans
-        writeVal proto (TDouble val)
-        bin <- tRead trans 8
-        (LBS.unpack bin) `shouldBe`[67, 64, 0, 0, 0, 0, 0, 0]
-
-      it "reads in big endian order" $ do
-        let bin = LBS.pack [67, 64, 0, 0, 0, 0, 0, 0]
-        trans <- openMemoryBuffer
-        let proto = BinaryProtocol trans
-        tWrite trans bin
-        val <- readVal proto T_DOUBLE
-        val `shouldBe` (TDouble $ 2 ** 53)
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = BinaryProtocol trans
-        writeVal proto $ TDouble val
-        val2 <- readVal proto T_DOUBLE
-        val2 `shouldBe` (TDouble val)
-
-    describe "string" $ do
-      it "writes" $ do
-        let val = C.pack "aaa"
-        trans <- openMemoryBuffer
-        let proto = BinaryProtocol trans
-        writeVal proto (TString val)
-        bin <- tRead trans 7
-        (LBS.unpack bin) `shouldBe` [0, 0, 0, 3, 97, 97, 97]
-
-    describe "binary" $ do
-      it "writes" $ do
-        trans <- openMemoryBuffer
-        let proto = BinaryProtocol trans
-        writeVal proto (TBinary $ LBS.pack [42, 43, 44])
-        bin <- tRead trans 100
-        (LBS.unpack bin) `shouldBe` [0, 0, 0, 3, 42, 43, 44]
-
-      it "reads" $ do
-        trans <- openMemoryBuffer
-        let proto = BinaryProtocol trans
-        tWrite trans $ LBS.pack [0, 0, 0, 3, 42, 43, 44]
-        val <- readVal proto (T_BINARY)
-        val `shouldBe` (TBinary $ LBS.pack [42, 43, 44])
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = BinaryProtocol trans
-        writeVal proto (TBinary $ LBS.pack val)
-        val2 <- readVal proto (T_BINARY)
-        val2 `shouldBe` (TBinary $ LBS.pack val)
-
diff --git a/lib/hs/test/CompactSpec.hs b/lib/hs/test/CompactSpec.hs
deleted file mode 100644
index 5540e7b..0000000
--- a/lib/hs/test/CompactSpec.hs
+++ /dev/null
@@ -1,81 +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.
---
-
-module CompactSpec where
-
-import Test.Hspec
-import Test.Hspec.QuickCheck (prop)
-
-import qualified Data.ByteString.Lazy as LBS
-
-import Thrift.Types
-import Thrift.Transport
-import Thrift.Transport.Memory
-import Thrift.Protocol
-import Thrift.Protocol.Compact
-
-spec :: Spec
-spec = do
-  describe "CompactProtocol" $ do
-    describe "double" $ do
-      it "writes in little endian order" $ do
-        let val = 2 ** 53
-        trans <- openMemoryBuffer
-        let proto = CompactProtocol trans
-        writeVal proto (TDouble val)
-        bin <- tReadAll trans 8
-        (LBS.unpack bin) `shouldBe`[0, 0, 0, 0, 0, 0, 64, 67]
-
-      it "reads in little endian order" $ do
-        let bin = LBS.pack [0, 0, 0, 0, 0, 0, 64, 67]
-        trans <- openMemoryBuffer
-        let proto = CompactProtocol trans
-        tWrite trans bin
-        val <- readVal proto T_DOUBLE
-        val `shouldBe` (TDouble $ 2 ** 53)
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = CompactProtocol trans
-        writeVal proto $ TDouble val
-        val2 <- readVal proto T_DOUBLE
-        val2 `shouldBe` (TDouble val)
-
-    describe "binary" $ do
-      it "writes" $ do
-        trans <- openMemoryBuffer
-        let proto = CompactProtocol trans
-        writeVal proto (TBinary $ LBS.pack [42, 43, 44])
-        bin <- tRead trans 100
-        (LBS.unpack bin) `shouldBe` [3, 42, 43, 44]
-
-      it "reads" $ do
-        trans <- openMemoryBuffer
-        let proto = CompactProtocol trans
-        tWrite trans $ LBS.pack [3, 42, 43, 44]
-        val <- readVal proto (T_BINARY)
-        val `shouldBe` (TBinary $ LBS.pack [42, 43, 44])
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = CompactProtocol trans
-        writeVal proto (TBinary $ LBS.pack val)
-        val2 <- readVal proto (T_BINARY)
-        val2 `shouldBe` (TBinary $ LBS.pack val)
-
diff --git a/lib/hs/test/JSONSpec.hs b/lib/hs/test/JSONSpec.hs
deleted file mode 100644
index 022c826..0000000
--- a/lib/hs/test/JSONSpec.hs
+++ /dev/null
@@ -1,225 +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.
---
-
-module JSONSpec where
-
-import Test.Hspec
-import Test.Hspec.QuickCheck (prop)
-
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.ByteString.Lazy.Char8 as C
-
-import Thrift.Types
-import Thrift.Transport
-import Thrift.Transport.Memory
-import Thrift.Protocol
-import Thrift.Protocol.JSON
-
-tString :: [Char] -> ThriftVal
-tString = TString . C.pack
-
-spec :: Spec
-spec = do
-  describe "JSONProtocol" $ do
-    describe "bool" $ do
-      it "writes true as 1" $ do
-        let val = True
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TBool val)
-        bin <-tRead trans 100
-        (C.unpack bin) `shouldBe` ['1']
-
-      it "writes false as 0" $ do
-        let val = False
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TBool val)
-        bin <- tRead trans 100
-        (C.unpack bin) `shouldBe` ['0']
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto $ TBool val
-        val2 <- readVal proto T_BOOL
-        val2 `shouldBe` (TBool val)
-
-    describe "string" $ do
-      it "writes" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TString $ C.pack "\"a")
-        bin <- tRead trans 100
-        (C.unpack bin) `shouldBe` "\"\\\"a\""
-
-      it "reads" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans $ C.pack "\"\\\"a\""
-        val <- readVal proto (T_STRING)
-        val `shouldBe` (TString $ C.pack "\"a")
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TString $ C.pack val)
-        val2 <- readVal proto (T_STRING)
-        val2 `shouldBe` (TString $ C.pack val)
-
-    describe "binary" $ do
-      it "writes with padding" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TBinary $ LBS.pack [1])
-        bin <- tRead trans 100
-        (C.unpack bin) `shouldBe` "\"AQ==\""
-
-      it "reads with padding" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans $ C.pack "\"AQ==\""
-        val <- readVal proto (T_BINARY)
-        val `shouldBe` (TBinary $ LBS.pack [1])
-
-      it "reads without padding" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans $ C.pack "\"AQ\""
-        val <- readVal proto (T_BINARY)
-        val `shouldBe` (TBinary $ LBS.pack [1])
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TBinary $ LBS.pack val)
-        val2 <- readVal proto (T_BINARY)
-        val2 `shouldBe` (TBinary $ LBS.pack val)
-
-    describe "list" $ do
-      it "writes empty list" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TList T_BYTE [])
-        bin <- tRead trans 100
-        (C.unpack bin) `shouldBe` "[\"i8\",0]"
-
-      it "reads empty" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans (C.pack "[\"i8\",0]")
-        val <- readVal proto (T_LIST T_BYTE)
-        val `shouldBe` (TList T_BYTE [])
-
-      it "writes single element" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TList T_BYTE [TByte 0])
-        bin <- tRead trans 100
-        (C.unpack bin) `shouldBe` "[\"i8\",1,0]"
-
-      it "reads single element" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans (C.pack "[\"i8\",1,0]")
-        val <- readVal proto (T_LIST T_BYTE)
-        val `shouldBe` (TList T_BYTE [TByte 0])
-
-      it "reads elements" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans (C.pack "[\"i8\",2,42, 43]")
-        val <- readVal proto (T_LIST T_BYTE)
-        val `shouldBe` (TList T_BYTE [TByte 42, TByte 43])
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto $ (TList T_STRING $ map tString val)
-        val2 <- readVal proto $ T_LIST T_STRING
-        val2 `shouldBe` (TList T_STRING $ map tString val)
-
-    describe "set" $ do
-      it "writes empty" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TSet T_BYTE [])
-        bin <- tRead trans 100
-        (C.unpack bin) `shouldBe` "[\"i8\",0]"
-
-      it "reads empty" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans (C.pack "[\"i8\",0]")
-        val <- readVal proto (T_SET T_BYTE)
-        val `shouldBe` (TSet T_BYTE [])
-
-      it "reads single element" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans (C.pack "[\"i8\",1,0]")
-        val <- readVal proto (T_SET T_BYTE)
-        val `shouldBe` (TSet T_BYTE [TByte 0])
-
-      it "reads elements" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans (C.pack "[\"i8\",2,42, 43]")
-        val <- readVal proto (T_SET T_BYTE)
-        val `shouldBe` (TSet T_BYTE [TByte 42, TByte 43])
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto $ (TSet T_STRING $ map tString val)
-        val2 <- readVal proto $ T_SET T_STRING
-        val2 `shouldBe` (TSet T_STRING $ map tString val)
-
-    describe "map" $ do
-      it "writes empty" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto (TMap T_BYTE T_BYTE [])
-        bin <- tRead trans 100
-        (C.unpack bin) `shouldBe`"[\"i8\",\"i8\",0,{}]"
-
-      it "reads empty" $ do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans (C.pack "[\"i8\",\"i8\",0,{}]")
-        val <- readVal proto (T_MAP T_BYTE T_BYTE)
-        val `shouldBe` (TMap T_BYTE T_BYTE [])
-
-      it "reads string-string" $ do
-        let bin = "[\"str\",\"str\",2,{\"a\":\"2\",\"b\":\"blah\"}]"
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        tWrite trans (C.pack bin)
-        val <- readVal proto (T_MAP T_STRING T_STRING)
-        val`shouldBe` (TMap T_STRING T_STRING [(tString "a", tString "2"), (tString "b", tString "blah")])
-
-      prop "round trip" $ \val -> do
-        trans <- openMemoryBuffer
-        let proto = JSONProtocol trans
-        writeVal proto $ (TMap T_STRING T_STRING $ map toKV val)
-        val2 <- readVal proto $ T_MAP T_STRING T_STRING
-        val2 `shouldBe` (TMap T_STRING T_STRING $ map toKV val)
-        where
-          toKV v = (tString v, tString v)
-
diff --git a/lib/hs/test/Spec.hs b/lib/hs/test/Spec.hs
deleted file mode 100644
index 7ec9a99..0000000
--- a/lib/hs/test/Spec.hs
+++ /dev/null
@@ -1,38 +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.
---
-
--- Our CI does not work well with auto discover.
--- Need to add build-time PATH variable to hspec-discover dir from CMake
--- or install hspec system-wide for the following to work.
--- {-# OPTIONS_GHC -F -pgmF hspec-discover #-}
-
-import Test.Hspec
-
-import qualified BinarySpec
-import qualified CompactSpec
-import qualified JSONSpec
-
-main :: IO ()
-main = hspec spec
-
-spec :: Spec
-spec = do
-  describe "Binary" BinarySpec.spec
-  describe "Compact" CompactSpec.spec
-  describe "JSON" JSONSpec.spec
diff --git a/lib/hs/thrift.cabal b/lib/hs/thrift.cabal
deleted file mode 100644
index d7cfad2..0000000
--- a/lib/hs/thrift.cabal
+++ /dev/null
@@ -1,84 +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.
---
-
-Name:           thrift
-Version:        0.14.2
-Cabal-Version:  1.24
-License:        Apache
-Category:       Foreign
-Build-Type:     Simple
-Synopsis:       Haskell bindings for the Apache Thrift RPC system
-Homepage:       http://thrift.apache.org
-Bug-Reports:    https://issues.apache.org/jira/browse/THRIFT
-Maintainer:     dev@thrift.apache.org
-License-File:   LICENSE
-
-Description:
-  Haskell bindings for the Apache Thrift RPC system. Requires the use of the thrift code generator.
-
-flag network-uri
-   description: Get Network.URI from the network-uri package
-   default: True
-
-Library
-  Hs-Source-Dirs:
-    src
-  Build-Depends:
-    base >= 4, base < 5, containers, ghc-prim, attoparsec, binary, bytestring >= 0.10, base64-bytestring, hashable, HTTP, text, hspec-core > 2.4.0, unordered-containers >= 0.2.6, vector >= 0.10.12.2, QuickCheck >= 2.8.2, split
-  if flag(network-uri)
-     build-depends: network-uri >= 2.6, network >= 2.6 && < 3.0
-  else
-     build-depends: network < 2.6
-  Exposed-Modules:
-    Thrift,
-    Thrift.Arbitraries
-    Thrift.Protocol,
-    Thrift.Protocol.Header,
-    Thrift.Protocol.Binary,
-    Thrift.Protocol.Compact,
-    Thrift.Protocol.JSON,
-    Thrift.Server,
-    Thrift.Transport,
-    Thrift.Transport.Empty,
-    Thrift.Transport.Framed,
-    Thrift.Transport.Handle,
-    Thrift.Transport.Header,
-    Thrift.Transport.HttpClient,
-    Thrift.Transport.IOBuffer,
-    Thrift.Transport.Memory,
-    Thrift.Types
-  Default-Language: Haskell2010
-  Default-Extensions:
-    DeriveDataTypeable,
-    ExistentialQuantification,
-    FlexibleInstances,
-    KindSignatures,
-    MagicHash,
-    RankNTypes,
-    RecordWildCards,
-    ScopedTypeVariables,
-    TypeSynonymInstances
-
-Test-Suite spec
-  Type: exitcode-stdio-1.0
-  Hs-Source-Dirs: test
-  Ghc-Options: -Wall
-  main-is: Spec.hs
-  Build-Depends: base, thrift, hspec, QuickCheck >= 2.8.2, bytestring >= 0.10, unordered-containers >= 0.2.6
-  Default-Language: Haskell2010
diff --git a/lib/java/CMakeLists.txt b/lib/java/CMakeLists.txt
index 28158c0..b9bfc81 100644
--- a/lib/java/CMakeLists.txt
+++ b/lib/java/CMakeLists.txt
@@ -48,19 +48,25 @@
         set(PRELEASE "false")
     endif ()
 
-    add_custom_target(ThriftJava ALL
+    file(GLOB_RECURSE THRIFTJAVA_SOURCES LIST_DIRECTORIES false
+        "${CMAKE_CURRENT_SOURCE_DIR}/src/*")
+    add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/build/libs/libthrift.jar"
         COMMENT "Building Java library using Gradle Wrapper"
         COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} assemble
             --console=plain --no-daemon
             -Prelease=${PRELEASE}
             -Pthrift.version=${thrift_VERSION}
             "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
+        DEPENDS ${THRIFTJAVA_SOURCES}
         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     )
+    add_custom_target(ThriftJava ALL
+        DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/build/libs/libthrift.jar")
 
     # Enable publishing from CMake if the publishing information is provided
     add_custom_target(MavenPublish
         COMMENT "Publishing Java Library to Apache Maven staging"
+        DEPENDS ThriftJava
         COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} clean uploadArchives
             --console=plain --no-daemon
             -Prelease=${PRELEASE}
@@ -83,13 +89,13 @@
 
     if(BUILD_TESTING)
         add_test(NAME JavaTest
-                COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} test
-                    --console=plain --no-daemon
-                    -Prelease=${PRELEASE}
-                    -Pthrift.version=${thrift_VERSION}
-                    "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
-                    "-Pthrift.compiler=${THRIFT_COMPILER}"
-                WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+            COMMAND ${GRADLEW_EXECUTABLE} ${GRADLE_OPTS} test
+                --console=plain --no-daemon
+                -Prelease=${PRELEASE}
+                -Pthrift.version=${thrift_VERSION}
+                "-Pbuild.dir=${CMAKE_CURRENT_BINARY_DIR}/build"
+                "-Pthrift.compiler=${THRIFT_COMPILER}"
+            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
     endif()
 
 endif()
diff --git a/lib/java/gradle.properties b/lib/java/gradle.properties
index 40c1ec2..7208807 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.14.2
+thrift.version=0.15.0
 thrift.groupid=org.apache.thrift
 release=false
 
@@ -28,9 +28,8 @@
 httpclient.version=4.5.10
 httpcore.version=4.4.12
 slf4j.version=1.7.28
-#servlet.version=2.5
-#It contains servlet3
-tomcat.embed.version=8.5.46
+servlet.version=4.0.1
+tomcat.embed.version=9.0.43
 junit.version=4.12
 mockito.version=1.10.19
 javax.annotation.version=1.3.2
diff --git a/lib/java/gradle/environment.gradle b/lib/java/gradle/environment.gradle
index 965a908..b6cfb21 100644
--- a/lib/java/gradle/environment.gradle
+++ b/lib/java/gradle/environment.gradle
@@ -44,7 +44,7 @@
 // Versions used in this project
 ext.httpclientVersion = property('httpclient.version')
 ext.httpcoreVersion = property('httpcore.version')
-//ext.servletVersion = property('servlet.version')
+ext.servletVersion = property('servlet.version')
 ext.tomcatEmbedVersion = property('tomcat.embed.version')
 ext.slf4jVersion = property('slf4j.version')
 ext.junitVersion = property('junit.version')
@@ -67,8 +67,7 @@
     compile "org.slf4j:slf4j-api:${slf4jVersion}"
     compile "org.apache.httpcomponents:httpclient:${httpclientVersion}"
     compile "org.apache.httpcomponents:httpcore:${httpcoreVersion}"
-    //compile "javax.servlet:servlet-api:${servletVersion}"
-    compile "org.apache.tomcat.embed:tomcat-embed-core:${tomcatEmbedVersion}"
+    compile "javax.servlet:javax.servlet-api:${servletVersion}"
     compile "javax.annotation:javax.annotation-api:${javaxAnnotationVersion}"
 
     testCompile "junit:junit:${junitVersion}"
diff --git a/lib/java/gradle/functionalTests.gradle b/lib/java/gradle/functionalTests.gradle
index 6a388a6..f00f74b 100644
--- a/lib/java/gradle/functionalTests.gradle
+++ b/lib/java/gradle/functionalTests.gradle
@@ -45,6 +45,7 @@
 }
 
 dependencies {
+    crossTestCompile "org.apache.tomcat.embed:tomcat-embed-core:${tomcatEmbedVersion}"
     crossTestCompile sourceSets.main.output
     crossTestCompile sourceSets.test.output
 }
diff --git a/lib/java/gradle/publishing.gradle b/lib/java/gradle/publishing.gradle
index 481fcbc..7be7de4 100644
--- a/lib/java/gradle/publishing.gradle
+++ b/lib/java/gradle/publishing.gradle
@@ -85,7 +85,7 @@
 
     pom.whenConfigured {
         // Fixup the scope for servlet-api to be 'provided' instead of 'compile'
-        dependencies.find { dep -> dep.groupId == 'javax.servlet' && dep.artifactId == 'servlet-api' }.with {
+        dependencies.find { dep -> dep.groupId == 'javax.servlet' && dep.artifactId == 'javax.servlet-api' }.with {
             if(it != null) {
               // it.optional = true
               it.scope = 'provided'
diff --git a/lib/java/gradle/sourceConfiguration.gradle b/lib/java/gradle/sourceConfiguration.gradle
index d15c117..ce0db75 100644
--- a/lib/java/gradle/sourceConfiguration.gradle
+++ b/lib/java/gradle/sourceConfiguration.gradle
@@ -86,7 +86,7 @@
             "Bundle-Description": "Apache Thrift library",
             "Bundle-License": "${project.license}",
             "Bundle-ActivationPolicy": "lazy",
-            "Export-Package": "${project.group}.async;uses:=\"${project.group}.protocol,${project.group}.transport,org.slf4j,${project.group}\";version=\"${version}\",${project.group}.protocol;uses:=\"${project.group}.transport,${project.group},${project.group}.scheme\";version=\"${version}\",${project.group}.server;uses:=\"${project.group}.transport,${project.group}.protocol,${project.group},org.slf4j,javax.servlet,javax.servlet.http\";version=\"${version}\",${project.group}.transport;uses:=\"${project.group}.protocol,${project.group},org.apache.http.client,org.apache.http.params,org.apache.http.entity,org.apache.http.client.methods,org.apache.http,org.slf4j,javax.net.ssl,javax.net,javax.security.sasl,javax.security.auth.callback\";version=\"${version}\",${project.group};uses:=\"${project.group}.protocol,${project.group}.async,${project.group}.server,${project.group}.transport,org.slf4j,org.apache.log4j,${project.group}.scheme\";version=\"${version}\",${project.group}.meta_data;uses:=\"${project.group}\";version=\"${version}\",${project.group}.scheme;uses:=\"${project.group}.protocol,${project.group}\";version=\"${version}\"",
+            "Export-Package": "${project.group}.async;uses:=\"${project.group}.protocol,${project.group}.transport,org.slf4j,${project.group}\";version=\"${version}\",${project.group}.protocol;uses:=\"${project.group}.transport,${project.group},${project.group}.scheme\";version=\"${version}\",${project.group}.server;uses:=\"${project.group}.transport,${project.group}.protocol,${project.group},org.slf4j,javax.servlet,javax.servlet.http\";version=\"${version}\",${project.group}.transport;uses:=\"${project.group}.protocol,${project.group},org.apache.http.client,org.apache.http.params,org.apache.http.entity,org.apache.http.client.methods,org.apache.http,org.slf4j,javax.net.ssl,javax.net,javax.security.sasl,javax.security.auth.callback\";version=\"${version}\",${project.group};uses:=\"${project.group}.protocol,${project.group}.async,${project.group}.server,${project.group}.transport,org.slf4j,org.apache.log4j,${project.group}.scheme\";version=\"${version}\",${project.group}.meta_data;uses:=\"${project.group}\";version=\"${version}\",${project.group}.scheme;uses:=\"${project.group}.protocol,${project.group}\";version=\"${version}\",${project.group}.annotation;version=\"${version}\"",
             "Import-Package": "javax.net,javax.net.ssl,javax.security.auth.callback,javax.security.sasl,javax.servlet;resolution:=optional,javax.servlet.http;resolution:=optional,org.slf4j;resolution:=optional;version=\"[1.4,2)\",org.apache.http.client;resolution:=optional,org.apache.http.params;resolution:=optional,org.apache.http.entity;resolution:=optional,org.apache.http.client.methods;resolution:=optional,org.apache.http;resolution:=optional"
         ])
     }
diff --git a/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java b/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java
index 763e66a..d5b459c 100644
--- a/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TIOStreamTransport.java
@@ -26,6 +26,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.SocketTimeoutException;
 
 /**
  * This is the most commonly used base transport. It takes an InputStream or
@@ -174,6 +175,8 @@
     int bytesRead;
     try {
       bytesRead = inputStream_.read(buf, off, len);
+    } catch (SocketTimeoutException ste) {
+      throw new TTransportException(TTransportException.TIMED_OUT, ste);
     } catch (IOException iox) {
       throw new TTransportException(TTransportException.UNKNOWN, iox);
     }
diff --git a/lib/java/src/org/apache/thrift/transport/TSaslTransport.java b/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
index b106c70..b22469d 100644
--- a/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
+++ b/lib/java/src/org/apache/thrift/transport/TSaslTransport.java
@@ -72,7 +72,7 @@
   /**
    * Buffer for input.
    */
-  private TMemoryInputTransport readBuffer = new TMemoryInputTransport();
+  private TMemoryInputTransport readBuffer;
 
   /**
    * Buffer for output.
@@ -89,6 +89,7 @@
   protected TSaslTransport(TTransport underlyingTransport) throws TTransportException {
     super(Objects.isNull(underlyingTransport.getConfiguration()) ? new TConfiguration() : underlyingTransport.getConfiguration());
     this.underlyingTransport = underlyingTransport;
+    this.readBuffer = new TMemoryInputTransport(underlyingTransport.getConfiguration());
   }
 
   /**
@@ -104,6 +105,7 @@
     super(Objects.isNull(underlyingTransport.getConfiguration()) ? new TConfiguration() : underlyingTransport.getConfiguration());
     sasl = new SaslParticipant(saslClient);
     this.underlyingTransport = underlyingTransport;
+    this.readBuffer = new TMemoryInputTransport(underlyingTransport.getConfiguration());
   }
 
   protected void setSaslServer(SaslServer saslServer) {
diff --git a/lib/js/CMakeLists.txt b/lib/js/CMakeLists.txt
index c312a21..115b46e 100644
--- a/lib/js/CMakeLists.txt
+++ b/lib/js/CMakeLists.txt
@@ -38,12 +38,17 @@
     WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
 )
 
-add_custom_target(ThriftJavascript ALL
+file(GLOB_RECURSE THRIFTJAVASCRIPT_SOURCES LIST_DIRECTORIES false
+    "${CMAKE_CURRENT_SOURCE_DIR}/*")
+list(FILTER THRIFTJAVASCRIPT_SOURCES EXCLUDE REGEX ".*/(dist|doc)/.*")
+add_custom_command(OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/dist/thrift.js"
     COMMENT "Building Javascript library using npx Grunt wrapper"
-    DEPENDS ThriftJavascriptPreDeps
+    DEPENDS ThriftJavascriptPreDeps ${THRIFTJAVASCRIPT_SOURCES}
     COMMAND npx grunt
     WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
 )
+add_custom_target(ThriftJavascript ALL
+    DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/dist/thrift.js")
 
 install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/dist/"
         DESTINATION "${JAVASCRIPT_INSTALL_DIR}"
diff --git a/lib/js/package-lock.json b/lib/js/package-lock.json
index ae200ac..b16e586 100644
--- a/lib/js/package-lock.json
+++ b/lib/js/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.14.2",
+  "version": "0.15.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/lib/js/package.json b/lib/js/package.json
index 48ea998..c27ac34 100644
--- a/lib/js/package.json
+++ b/lib/js/package.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.14.2",
+  "version": "0.15.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 ce58c77..808739f 100644
--- a/lib/js/src/thrift.js
+++ b/lib/js/src/thrift.js
@@ -46,7 +46,7 @@
      * @const {string} Version
      * @memberof Thrift
      */
-    Version: '0.14.2',
+    Version: '0.15.0',
 
     /**
      * Thrift IDL type string to Id mapping.
diff --git a/lib/lua/Thrift.lua b/lib/lua/Thrift.lua
index eaf0dc7..bf8d39f 100644
--- a/lib/lua/Thrift.lua
+++ b/lib/lua/Thrift.lua
@@ -48,7 +48,7 @@
   return count
 end
 
-version = '0.14.2'
+version = '0.15.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 35138d8..d55074f 100644
--- a/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj
+++ b/lib/netstd/Benchmarks/Thrift.Benchmarks/Thrift.Benchmarks.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
   <!--
     Licensed to the Apache Software Foundation(ASF) under one
     or more contributor license agreements.See the NOTICE file
@@ -20,12 +20,13 @@
   
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <TargetFrameworks>netcoreapp3.1;net48</TargetFrameworks>
+    <TargetFramework>net5.0</TargetFramework>
     <TieredCompilation>false</TieredCompilation>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
+    <PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
index 7c5639b..807f767 100644
--- a/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
+++ b/lib/netstd/Tests/Thrift.IntegrationTests/Thrift.IntegrationTests.csproj
@@ -19,9 +19,10 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
     <AssemblyName>Thrift.IntegrationTests</AssemblyName>
     <PackageId>Thrift.IntegrationTests</PackageId>
+    <Version>0.15.0.0</Version>
     <OutputType>Exe</OutputType>
     <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
     <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
@@ -32,11 +33,11 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="CompareNETObjects" Version="4.64.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
-    <PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
-    <PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
+    <PackageReference Include="CompareNETObjects" Version="4.72.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
+    <PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
+    <PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="4.8.1" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/GlobalSuppressions.cs b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/GlobalSuppressions.cs
new file mode 100644
index 0000000..77cd3fc
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/GlobalSuppressions.cs
@@ -0,0 +1,9 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Performance", "CA1822", Justification = "<Ausstehend>", Scope = "module")]
+[assembly: SuppressMessage("Style", "IDE0090", Justification = "<Ausstehend>", Scope = "module")]
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Impl/Thrift5253/MyService.cs b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Impl/Thrift5253/MyService.cs
index 342dd4a..660b2b7 100644
--- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Impl/Thrift5253/MyService.cs
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Impl/Thrift5253/MyService.cs
@@ -26,32 +26,43 @@
 {
     class MyServiceImpl : MyService.IAsync
     {
-        public Task<AsyncProcessor> AsyncProcessorAsync(AsyncProcessor input, CancellationToken cancellationToken = default)
+        public Task<AsyncProcessor> AsyncProcessor_(AsyncProcessor input, CancellationToken cancellationToken = default)
         {
             return Task.FromResult(new AsyncProcessor() { Foo = input.Foo });
         }
 
-        public Task<BrokenResult> BrokenAsync(BrokenArgs input, CancellationToken cancellationToken = default)
+        public Task<BrokenResult> Broken(BrokenArgs input, CancellationToken cancellationToken = default)
         {
             return Task.FromResult(new BrokenResult() { Foo = input.Foo });
         }
 
-        public Task<Client> ClientAsync(Client input, CancellationToken cancellationToken = default)
+        public Task<Client> Client_(Client input, CancellationToken cancellationToken = default)
         {
+            _ = cancellationToken;
             return Task.FromResult(new Client() { Foo = input.Foo });
         }
 
-        public Task<IAsync> IAsyncAsync(IAsync input, CancellationToken cancellationToken = default)
+        public Task<IAsync> IAsync_(IAsync input, CancellationToken cancellationToken = default)
         {
             return Task.FromResult(new IAsync() { Foo = input.Foo });
         }
 
-        public Task<InternalStructs> InternalStructsAsync(InternalStructs input, CancellationToken cancellationToken = default)
+        public Task<InternalStructs> InternalStructs_(InternalStructs input, CancellationToken cancellationToken = default)
         {
             return Task.FromResult(new InternalStructs() { Foo = input.Foo });
         }
 
-        public Task<WorksRslt> WorksAsync(WorksArrrgs input, CancellationToken cancellationToken = default)
+        public Task TestAsync(CancellationToken cancellationToken = default)
+        {
+            return Task.CompletedTask;
+        }
+
+        public Task TestXsync(CancellationToken cancellationToken = default)
+        {
+            return Task.CompletedTask;
+        }
+
+        public Task<WorksRslt> Works(WorksArrrgs input, CancellationToken cancellationToken = default)
         {
             return Task.FromResult(new WorksRslt() { Foo = input.Foo });
         }
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 c43c71c..d34c60a 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,10 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <ThriftVersion>0.15.0</ThriftVersion>
+    <ThriftVersionOutput>Thrift version $(ThriftVersion)</ThriftVersionOutput>
+    <TargetFramework>net5.0</TargetFramework>
+    <Version>$(ThriftVersion).0</Version>
     <AssemblyName>Thrift.PublicInterfaces.Compile.Tests</AssemblyName>
     <PackageId>Thrift.PublicInterfaces.Compile.Tests</PackageId>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
@@ -33,31 +36,49 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="4.8.1" />
   </ItemGroup>
 
   <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+    <!-- Check on the path -->
     <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true">
       <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
     </Exec>
-    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./CassandraTest.thrift" />
-    <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./CassandraTest.thrift" />
-    <Exec Condition="Exists('$(ProjectDir)/../../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./CassandraTest.thrift" />
-    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./optional_required_default.thrift" />
-    <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./optional_required_default.thrift" />
-    <Exec Condition="Exists('$(ProjectDir)/../../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./optional_required_default.thrift" />
-    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./../../../../test/ThriftTest.thrift" />
-    <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./../../../../test/ThriftTest.thrift" />
-    <Exec Condition="Exists('$(ProjectDir)/../../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./../../../../test/ThriftTest.thrift" />
-    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./../../../../contrib/fb303/if/fb303.thrift" />
-    <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./../../../../contrib/fb303/if/fb303.thrift" />
-    <Exec Condition="Exists('$(ProjectDir)/../../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./../../../../contrib/fb303/if/fb303.thrift" />
-    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./Thrift5253.thrift" />
-    <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./Thrift5253.thrift" />
-    <Exec Condition="Exists('$(ProjectDir)/../../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./Thrift5253.thrift" />
-    <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./Thrift5320.thrift" />
-    <Exec Condition="Exists('thrift')" Command="thrift -gen netstd:wcf,union,serial -r ./Thrift5320.thrift" />
-    <Exec Condition="Exists('$(ProjectDir)/../../../../compiler/cpp/thrift')" Command="$(ProjectDir)/../../../../compiler/cpp/thrift -gen netstd:wcf,union,serial -r ./Thrift5320.thrift" />
+    <Exec Condition="'$(OS)' != 'Windows_NT'" Command="which thrift || true" ConsoleToMSBuild="true">
+      <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+    </Exec>
+    <!-- Check in the current directory -->
+    <CreateProperty Condition="Exists('thrift')" Value="thrift">
+      <Output TaskParameter="Value" PropertyName="PathToThrift" />
+    </CreateProperty>
+    <!-- Check for the root projects output -->
+    <CreateProperty Condition="Exists('$(ProjectDir)/../../../../compiler/cpp/thrift')" Value="$(ProjectDir)/../../../../compiler/cpp/thrift">
+      <Output TaskParameter="Value" PropertyName="PathToThrift" />
+    </CreateProperty>
+    <Error 
+      Condition="!Exists('$(PathToThrift)')"
+      Text="Thrift executable could not be found."
+    />
+    <!-- Make sure the thrift version found is the same as the projects version -->
+    <Exec Command="$(PathToThrift) -version" ConsoleToMSBuild="true">
+      <Output TaskParameter="ConsoleOutput" PropertyName="ThriftBinaryVersion" />
+    </Exec>
+    <Error 
+      Condition="$('$(ThriftBinaryVersion)'::StartsWith('$(ThriftVersionOutput)')) == true"
+      Text="Thrift version returned: '$(ThriftBinaryVersion)' is not equal to the projects version '$(ThriftVersionOutput)'."
+    />
+    <Message
+      Importance="high"
+      Text="Generating tests with thrift binary: '$(PathToThrift)'"
+    />
+    <!-- Generate the thrift test files -->
+    <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./CassandraTest.thrift" />
+    <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./optional_required_default.thrift" />
+    <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./../../../../test/ThriftTest.thrift" />
+    <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./../../../../contrib/fb303/if/fb303.thrift" />
+    <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./Thrift5253.thrift" />
+    <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./Thrift5320.thrift" />
+    <Exec Command="$(PathToThrift) -gen netstd:wcf,union,serial -r ./Thrift5382.thrift" />
   </Target>
 
 </Project>
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5253.thrift b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5253.thrift
index ee3df9b..224ac85 100644
--- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5253.thrift
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5253.thrift
@@ -42,5 +42,9 @@
     AsyncProcessor  AsyncProcessor ( 1: AsyncProcessor  foo)
     Client          Client         ( 1: Client  foo)
     IAsync          IAsync         ( 1: IAsync  foo)
+
+    // inconsistent treatment of methods ending in "Async"
+    void TestXsync()
+    void TestAsync()
 }
 
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.objs.thrift b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.objs.thrift
new file mode 100644
index 0000000..095d7bd
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.objs.thrift
@@ -0,0 +1,24 @@
+# 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.
+
+// Testcase for THRIFT-5382 Netstd default list/set enums values are generated incorrectly
+
+namespace * Thrift5382.objs
+
+enum FoobarEnum {
+	Val_1 = 0,
+	Val_2 = 1
+}
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.thrift b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.thrift
new file mode 100644
index 0000000..db53dfa
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/Thrift5382.thrift
@@ -0,0 +1,36 @@
+# 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.
+
+// Testcase for THRIFT-5382 Netstd default list/set enums values are generated incorrectly
+
+namespace * Thrift5382
+
+include "Thrift5382.objs.thrift"
+
+struct RequestModel {
+	// Breaks
+	1: optional set<Thrift5382.objs.FoobarEnum> data_1 = [ FoobarEnum.Val_1, FoobarEnum.Val_2 ],
+	// Breaks
+	2: optional list<Thrift5382.objs.FoobarEnum> data_2 = [ FoobarEnum.Val_1, FoobarEnum.Val_2 ],
+	// Works
+	3: optional Thrift5382.objs.FoobarEnum data_3 = FoobarEnum.Val_1
+}
+
+service Test {
+    void CallMe( 
+		1 : RequestModel foo,
+	)
+}
diff --git a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
index 1f6c7ee..4a38205 100644
--- a/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
+++ b/lib/netstd/Tests/Thrift.PublicInterfaces.Compile.Tests/optional_required_default.thrift
@@ -141,3 +141,11 @@
     set<set<set<Distance>>> DoItNow( 1 : list<list<list<RaceDetails>>> rd, 2: i32 mitDefault = 42) throws (1: CrashBoomBang cbb)
 }
 
+service deprecate_everything {
+  void Foo( ) ( deprecated = "This method has neither 'x' nor \"y\"" )
+  void Bar( ) ( deprecated = "Fails to deliver 中文 колбаса" )
+  void Baz( ) ( deprecated = "Need this to work with tabs (\t) or Umlauts (äöüÄÖÜß) too" )
+  void Deprecated() ( deprecated ) // no comment
+}
+
+
diff --git a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
index 4b39e7d..4e21a26 100644
--- a/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
+++ b/lib/netstd/Tests/Thrift.Tests/Thrift.Tests.csproj
@@ -18,14 +18,15 @@
     under the License.
   -->
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
+    <Version>0.15.0.0</Version>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="CompareNETObjects" Version="4.64.0" />
-    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
-    <PackageReference Include="MSTest.TestAdapter" Version="2.0.0" />
-    <PackageReference Include="MSTest.TestFramework" Version="2.0.0" />
-    <PackageReference Include="NSubstitute" Version="4.2.1" />
+    <PackageReference Include="CompareNETObjects" Version="4.72.0" />
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
+    <PackageReference Include="MSTest.TestAdapter" Version="2.1.2" />
+    <PackageReference Include="MSTest.TestFramework" Version="2.1.2" />
+    <PackageReference Include="NSubstitute" Version="4.2.2" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\Thrift\Thrift.csproj" />
diff --git a/lib/netstd/Tests/Thrift.Tests/Transports/THttpTransportTests.cs b/lib/netstd/Tests/Thrift.Tests/Transports/THttpTransportTests.cs
new file mode 100644
index 0000000..2a2d884
--- /dev/null
+++ b/lib/netstd/Tests/Thrift.Tests/Transports/THttpTransportTests.cs
@@ -0,0 +1,40 @@
+// 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.
+
+using System.Net.Http;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Thrift.Transport.Client;
+
+namespace Thrift.Tests.Transports
+{
+    [TestClass]
+    public class THttpTransportTests
+    {
+        [TestMethod]
+        public void THttpTransport_Uses_Configured_ConnectionTimeout_Test()
+        {
+            var client = new HttpClient();
+            var httpClientTransport = new THttpTransport(client, null)
+            {
+                ConnectTimeout = 5000
+            };
+
+            Assert.IsTrue(client.Timeout.TotalMilliseconds == 5000);
+            Assert.IsTrue(httpClientTransport.ConnectTimeout == 5000);
+        }
+    }
+}
diff --git a/lib/netstd/Thrift/Collections/TCollections.cs b/lib/netstd/Thrift/Collections/TCollections.cs
index b386c37..21ee3bb 100644
--- a/lib/netstd/Thrift/Collections/TCollections.cs
+++ b/lib/netstd/Thrift/Collections/TCollections.cs
@@ -99,8 +99,7 @@
 
             foreach (var obj in enumerable)
             {
-                var enum2 = obj as IEnumerable;
-                var objHash = enum2 == null ? obj.GetHashCode() : GetHashCode(enum2);
+                var objHash = (obj is IEnumerable enum2) ? GetHashCode(enum2) : obj.GetHashCode();
 
                 unchecked
                 {
diff --git a/lib/netstd/Thrift/Collections/THashSet.cs b/lib/netstd/Thrift/Collections/THashSet.cs
index 8dfb9e3..25fcf10 100644
--- a/lib/netstd/Thrift/Collections/THashSet.cs
+++ b/lib/netstd/Thrift/Collections/THashSet.cs
@@ -32,8 +32,13 @@
 
         public THashSet(int capacity)
         {
-            // TODO: uncomment capacity when NET Standard also implements it
-            Items = new HashSet<T>(/*capacity*/);
+            #if NET5_0
+            Items = new HashSet<T>(capacity);
+            #elif NETFRAMEWORK || NETSTANDARD
+            Items = new HashSet<T>(/*capacity not supported*/);
+            #else
+            #error Unknown platform
+            #endif
         }
 
         public int Count => Items.Count;
diff --git a/lib/netstd/Thrift/Properties/AssemblyInfo.cs b/lib/netstd/Thrift/Properties/AssemblyInfo.cs
index ddebf64..c05acab 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.14.2.0")]
-[assembly: AssemblyFileVersion("0.14.2.0")]
+[assembly: AssemblyVersion("0.15.0.0")]
+[assembly: AssemblyFileVersion("0.15.0.0")]
diff --git a/lib/netstd/Thrift/Protocol/TBase.cs b/lib/netstd/Thrift/Protocol/TBase.cs
index df9dd34..09bb43f 100644
--- a/lib/netstd/Thrift/Protocol/TBase.cs
+++ b/lib/netstd/Thrift/Protocol/TBase.cs
@@ -18,6 +18,8 @@
 using System.Threading;
 using System.Threading.Tasks;
 
+#pragma warning disable IDE1006   // some interfaces here are intentionally not I-prefixed 
+
 namespace Thrift.Protocol
 {
     public interface TUnionBase
diff --git a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
index 28b7d29..9c23469 100644
--- a/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TBinaryProtocol.cs
@@ -23,6 +23,9 @@
 using Thrift.Protocol.Entities;
 using Thrift.Transport;
 
+#pragma warning disable IDE0079 // unnecessary suppression
+#pragma warning disable IDE0066 // use switch expression
+
 namespace Thrift.Protocol
 {
     // ReSharper disable once InconsistentNaming
@@ -36,7 +39,7 @@
 
         // minimize memory allocations by means of an preallocated bytes buffer
         // The value of 128 is arbitrarily chosen, the required minimum size must be sizeof(long)
-        private byte[] PreAllocatedBuffer = new byte[128];
+        private readonly byte[] PreAllocatedBuffer = new byte[128];
 
         public TBinaryProtocol(TTransport trans)
             : this(trans, false, true)
@@ -442,7 +445,7 @@
                 case TType.Map: return sizeof(int);  // element count
                 case TType.Set: return sizeof(int);  // element count
                 case TType.List: return sizeof(int);  // element count
-                default: throw new TTransportException(TTransportException.ExceptionType.Unknown, "unrecognized type code");
+                default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
             }
         }
 
diff --git a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
index 066b327..3758174 100644
--- a/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TCompactProtocol.cs
@@ -26,9 +26,11 @@
 using Thrift.Protocol.Entities;
 using Thrift.Transport;
 
+#pragma warning disable IDE0079 // unnecessary suppression
+#pragma warning disable IDE0066 // use switch expression
+
 namespace Thrift.Protocol
 {
-    //TODO: implementation of TProtocol
 
     // ReSharper disable once InconsistentNaming
     public class TCompactProtocol : TProtocol
@@ -805,7 +807,7 @@
                 case TType.Map:     return sizeof(byte);  // element count
                 case TType.Set:    return sizeof(byte);  // element count
                 case TType.List:    return sizeof(byte);  // element count
-                default: throw new TTransportException(TTransportException.ExceptionType.Unknown, "unrecognized type code");
+                default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
             }
         }
 
diff --git a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
index 2f1ccdb..081f42e 100644
--- a/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
+++ b/lib/netstd/Thrift/Protocol/TJSONProtocol.cs
@@ -27,6 +27,10 @@
 using Thrift.Protocol.Utilities;
 using Thrift.Transport;
 
+#pragma warning disable IDE0079 // unnecessary suppression
+#pragma warning disable IDE0063 // simplify using
+#pragma warning disable IDE0066 // use switch expression
+
 namespace Thrift.Protocol
 {
     /// <summary>
@@ -88,7 +92,7 @@
         ///    even in cases where the protocol instance was in an undefined state due to
         ///    dangling/stale/obsolete contexts
         /// </summary>
-        private void resetContext()
+        private void ResetContext()
         {
             ContextStack.Clear();
             Context = new JSONBaseContext(this);
@@ -277,7 +281,7 @@
 
         public override async Task WriteMessageBeginAsync(TMessage message, CancellationToken cancellationToken)
         {
-            resetContext();
+            ResetContext();
             await WriteJsonArrayStartAsync(cancellationToken);
             await WriteJsonIntegerAsync(Version, cancellationToken);
 
@@ -430,7 +434,12 @@
                     // escaped?
                     if (ch != TJSONProtocolConstants.EscSequences[0])
                     {
+#if NETSTANDARD2_0
                         await buffer.WriteAsync(new[] {ch}, 0, 1, cancellationToken);
+#else
+                        var wbuf = new[] { ch };
+                        await buffer.WriteAsync(wbuf.AsMemory(0, 1), cancellationToken);
+#endif
                         continue;
                     }
 
@@ -444,7 +453,12 @@
                             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
+                        var wbuf = new[] { ch };
+                        await buffer.WriteAsync( wbuf.AsMemory(0, 1), cancellationToken);
+#endif
                         continue;
                     }
 
@@ -473,13 +487,21 @@
 
                         codeunits.Add((char) wch);
                         var tmp = Utf8Encoding.GetBytes(codeunits.ToArray());
+#if NETSTANDARD2_0
                         await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken);
+#else
+                        await buffer.WriteAsync(tmp.AsMemory(0, tmp.Length), cancellationToken);
+#endif
                         codeunits.Clear();
                     }
                     else
                     {
-                        var tmp = Utf8Encoding.GetBytes(new[] {(char) wch});
+                        var tmp = Utf8Encoding.GetBytes(new[] { (char)wch });
+#if NETSTANDARD2_0
                         await buffer.WriteAsync(tmp, 0, tmp.Length, cancellationToken);
+#else
+                        await buffer.WriteAsync(tmp.AsMemory( 0, tmp.Length), cancellationToken);
+#endif
                     }
                 }
 
@@ -655,7 +677,7 @@
         {
             var message = new TMessage();
 
-            resetContext();
+            ResetContext();
             await ReadJsonArrayStartAsync(cancellationToken);
             if (await ReadJsonIntegerAsync(cancellationToken) != Version)
             {
@@ -816,7 +838,7 @@
                 case TType.Map: return 2;  // empty map
                 case TType.Set: return 2;  // empty set
                 case TType.List: return 2;  // empty list
-                default: throw new TTransportException(TTransportException.ExceptionType.Unknown, "unrecognized type code");
+                default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "unrecognized type code");
             }
         }
 
diff --git a/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs b/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs
index 20e659d..49593cc 100644
--- a/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs
+++ b/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs
@@ -29,6 +29,9 @@
 using System.Threading.Tasks;
 using Microsoft.Extensions.Logging;
 
+#pragma warning disable IDE0079  // remove unnecessary pragmas
+#pragma warning disable IDE0063  // using can be simplified, we don't
+
 namespace Thrift.Server
 {
     /// <summary>
@@ -125,8 +128,7 @@
             {
                 if ((threadConfig.MaxWorkerThreads > 0) || (threadConfig.MaxIOThreads > 0))
                 {
-                    int work, comm;
-                    ThreadPool.GetMaxThreads(out work, out comm);
+                    ThreadPool.GetMaxThreads(out int work, out int comm);
                     if (threadConfig.MaxWorkerThreads > 0)
                         work = threadConfig.MaxWorkerThreads;
                     if (threadConfig.MaxIOThreads > 0)
@@ -137,8 +139,7 @@
 
                 if ((threadConfig.MinWorkerThreads > 0) || (threadConfig.MinIOThreads > 0))
                 {
-                    int work, comm;
-                    ThreadPool.GetMinThreads(out work, out comm);
+                    ThreadPool.GetMinThreads(out int work, out int comm);
                     if (threadConfig.MinWorkerThreads > 0)
                         work = threadConfig.MinWorkerThreads;
                     if (threadConfig.MinIOThreads > 0)
@@ -172,19 +173,21 @@
                 if (ServerEventHandler != null)
                     await ServerEventHandler.PreServeAsync(cancellationToken);
 
-                while (!stop)
+                while (!(stop || ServerCancellationToken.IsCancellationRequested))
                 {
-                    int failureCount = 0;
                     try
                     {
                         TTransport client = await ServerTransport.AcceptAsync(cancellationToken);
-                        ThreadPool.QueueUserWorkItem(this.Execute, client);
+                        _ = Task.Run(async () => await ExecuteAsync(client), cancellationToken);  // intentionally ignoring retval
+                    }
+                    catch (TaskCanceledException)
+                    {
+                        stop = true;
                     }
                     catch (TTransportException ttx)
                     {
                         if (!stop || ttx.Type != TTransportException.ExceptionType.Interrupted)
                         {
-                            ++failureCount;
                             LogError(ttx.ToString());
                         }
 
@@ -207,7 +210,7 @@
             }
             finally
             {
-                ServerCancellationToken = default(CancellationToken);
+                ServerCancellationToken = default;
             }
         }
 
@@ -216,11 +219,11 @@
         /// threadContext will be a TTransport instance
         /// </summary>
         /// <param name="threadContext"></param>
-        private void Execute(object threadContext)
+        private async Task ExecuteAsync(TTransport client)
         {
             var cancellationToken = ServerCancellationToken;
 
-            using (TTransport client = (TTransport)threadContext)
+            using (client)
             {
                 ITAsyncProcessor processor = ProcessorFactory.GetAsyncProcessor(client, this);
                 TTransport inputTransport = null;
@@ -239,12 +242,12 @@
 
                         //Recover event handler (if any) and fire createContext server event when a client connects
                         if (ServerEventHandler != null)
-                            connectionContext = ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken).Result;
+                            connectionContext = await ServerEventHandler.CreateContextAsync(inputProtocol, outputProtocol, cancellationToken);
 
                         //Process client requests until client disconnects
                         while (!stop)
                         {
-                            if (! inputTransport.PeekAsync(cancellationToken).Result)
+                            if (! await inputTransport.PeekAsync(cancellationToken))
                                 break;
 
                             //Fire processContext server event
@@ -252,9 +255,10 @@
                             //That is to say it may be many minutes between the event firing and the client request
                             //actually arriving or the client may hang up without ever makeing a request.
                             if (ServerEventHandler != null)
-                                ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken).Wait();
+                                await ServerEventHandler.ProcessContextAsync(connectionContext, inputTransport, cancellationToken);
+
                             //Process client request (blocks until transport is readable)
-                            if (!processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken).Result)
+                            if (! await processor.ProcessAsync(inputProtocol, outputProtocol, cancellationToken))
                                 break;
                         }
                     }
@@ -270,7 +274,7 @@
 
                     //Fire deleteContext server event after client disconnects
                     if (ServerEventHandler != null)
-                        ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken).Wait();
+                        await ServerEventHandler.DeleteContextAsync(connectionContext, inputProtocol, outputProtocol, cancellationToken);
 
                 }
                 finally
diff --git a/lib/netstd/Thrift/TConfiguration.cs b/lib/netstd/Thrift/TConfiguration.cs
index c8dde10..eff78e9 100644
--- a/lib/netstd/Thrift/TConfiguration.cs
+++ b/lib/netstd/Thrift/TConfiguration.cs
@@ -1,3 +1,20 @@
+// 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.
+
 using System;
 using System.Collections.Generic;
 using System.Text;
diff --git a/lib/netstd/Thrift/Thrift.csproj b/lib/netstd/Thrift/Thrift.csproj
index c1f3915..4372334 100644
--- a/lib/netstd/Thrift/Thrift.csproj
+++ b/lib/netstd/Thrift/Thrift.csproj
@@ -19,7 +19,7 @@
   -->
 
 <PropertyGroup>
-  <TargetFrameworks>netstandard2.1;netstandard2.0</TargetFrameworks>
+  <TargetFrameworks>netstandard2.1;netstandard2.0;net5.0</TargetFrameworks>
   <AssemblyName>Thrift</AssemblyName>
   <PackageId>ApacheThrift</PackageId>
   <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
@@ -39,8 +39,8 @@
   <SignAssembly>true</SignAssembly>
   <AssemblyOriginatorKeyFile>thrift.snk</AssemblyOriginatorKeyFile>
   <DelaySign>false</DelaySign>
-  <Title>Apache Thrift 0.14.2</Title>
-  <Version>0.14.2.0</Version>
+  <Title>Apache Thrift 0.15.0</Title>
+  <Version>0.15.0.0</Version>
   <GeneratePackageOnBuild>false</GeneratePackageOnBuild>
   <PackageProjectUrl>http://thrift.apache.org/</PackageProjectUrl>
   <Authors>Apache Thrift Developers</Authors>
@@ -49,22 +49,22 @@
   <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.14.2/CHANGES.md</PackageReleaseNotes>
+  <PackageReleaseNotes>https://github.com/apache/thrift/blob/0.15.0/CHANGES.md</PackageReleaseNotes>
   <Copyright>Copyright 2021 The Apache Software Foundation</Copyright>
 </PropertyGroup>
 
   <ItemGroup>
     <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
-    <PackageReference Include="Microsoft.Extensions.Logging" Version="3.1.0" />
-    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.0" />
-    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.0" />
+    <PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="5.0.0" />
+    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="5.0.0" />
     <PackageReference Include="System.IO.Pipes" Version="[4.3,)" />
-    <PackageReference Include="System.IO.Pipes.AccessControl" Version="4.5.1" />
-    <PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.7.0" />
+    <PackageReference Include="System.IO.Pipes.AccessControl" Version="5.0.0" />
+    <PackageReference Include="System.Net.Http.WinHttpHandler" Version="5.0.0" />
     <PackageReference Include="System.Net.NameResolution" Version="[4.3,)" />
     <PackageReference Include="System.Net.Requests" Version="[4.3,)" />
     <PackageReference Include="System.Net.Security" Version="4.3.2" />
-    <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
+    <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
   </ItemGroup>
 
   <Target Name="SetTFMAssemblyAttributesPath" BeforeTargets="GenerateTargetFrameworkMonikerAttribute">
diff --git a/lib/netstd/Thrift/Transport/Client/THttpTransport.cs b/lib/netstd/Thrift/Transport/Client/THttpTransport.cs
index dcd028c..4ca439e 100644
--- a/lib/netstd/Thrift/Transport/Client/THttpTransport.cs
+++ b/lib/netstd/Thrift/Transport/Client/THttpTransport.cs
@@ -25,6 +25,9 @@
 using System.Threading;
 using System.Threading.Tasks;
 
+#pragma warning disable IDE0079 // unnecessary suppression
+#pragma warning disable IDE0063 // simplify using
+
 namespace Thrift.Transport.Client
 {
     // ReSharper disable once InconsistentNaming
@@ -89,6 +92,22 @@
         // According to RFC 2616 section 3.8, the "User-Agent" header may not carry a version number
         public readonly string UserAgent = "Thrift netstd THttpClient";
 
+        public int ConnectTimeout
+        {
+            set
+            {
+                _connectTimeout = value;
+                if(_httpClient != null)
+                    _httpClient.Timeout = TimeSpan.FromMilliseconds(_connectTimeout);
+            }
+            get
+            {
+                if (_httpClient == null)
+                    return _connectTimeout;
+                return (int)_httpClient.Timeout.TotalMilliseconds;
+            }
+        }
+
         public override bool IsOpen => true;
 
         public HttpRequestHeaders RequestHeaders => _httpClient.DefaultRequestHeaders;
@@ -133,10 +152,10 @@
 
             try
             {
-#if NETSTANDARD2_1
-                var ret = await _inputStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
-#else
+#if NETSTANDARD2_0
                 var ret = await _inputStream.ReadAsync(buffer, offset, length, cancellationToken);
+#else
+                var ret = await _inputStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
 #endif
                 if (ret == -1)
                 {
@@ -156,7 +175,11 @@
         {
             cancellationToken.ThrowIfCancellationRequested();
 
+#if NETSTANDARD2_0
             await _outputStream.WriteAsync(buffer, offset, length, cancellationToken);
+#else
+            await _outputStream.WriteAsync(buffer.AsMemory(offset, length), cancellationToken);
+#endif
         }
 
         /// <summary>
@@ -224,7 +247,11 @@
                     var response = (await _httpClient.PostAsync(_uri, contentStream, cancellationToken)).EnsureSuccessStatusCode();
 
                     _inputStream?.Dispose();
+#if NETSTANDARD2_0 || NETSTANDARD2_1
                     _inputStream = await response.Content.ReadAsStreamAsync();
+#else
+                    _inputStream = await response.Content.ReadAsStreamAsync(cancellationToken);
+#endif
                     if (_inputStream.CanSeek)
                     {
                         _inputStream.Seek(0, SeekOrigin.Begin);
diff --git a/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs b/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs
index 815983e..e6c79c4 100644
--- a/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs
+++ b/lib/netstd/Thrift/Transport/Client/TNamedPipeTransport.cs
@@ -17,6 +17,7 @@
 
 using System;
 using System.IO.Pipes;
+using System.Security.Principal;
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -39,7 +40,7 @@
             var serverName = string.IsNullOrWhiteSpace(server) ? server : ".";
             ConnectTimeout = (timeout > 0) ? timeout : Timeout.Infinite;
 
-            PipeStream = new NamedPipeClientStream(serverName, pipe, PipeDirection.InOut, PipeOptions.None);
+            PipeStream = new NamedPipeClientStream(serverName, pipe, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.Anonymous);
         }
 
         public override bool IsOpen => PipeStream != null && PipeStream.IsConnected;
@@ -72,10 +73,10 @@
             }
 
             CheckReadBytesAvailable(length);
-#if NETSTANDARD2_1
-            var numRead = await PipeStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
-#else
+#if NETSTANDARD2_0
             var numRead = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken);
+#else
+            var numRead = await PipeStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
 #endif
             CountConsumedMessageBytes(numRead);
             return numRead;
@@ -94,7 +95,11 @@
             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
+                await PipeStream.WriteAsync(buffer.AsMemory(offset, nBytes), cancellationToken);
+#endif
                 offset += nBytes;
                 length -= nBytes;
                 nBytes = Math.Min(nBytes, length);
diff --git a/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs b/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
index b397460..90794c6 100644
--- a/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
+++ b/lib/netstd/Thrift/Transport/Client/TStreamTransport.cs
@@ -80,10 +80,10 @@
                     "Cannot read from null inputstream");
             }
 
-#if NETSTANDARD2_1
-            return await InputStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
-#else
+#if NETSTANDARD2_0
             return await InputStream.ReadAsync(buffer, offset, length, cancellationToken);
+#else
+            return await InputStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
 #endif
         }
 
@@ -95,7 +95,11 @@
                     "Cannot write to null outputstream");
             }
 
+#if NETSTANDARD2_0
             await OutputStream.WriteAsync(buffer, offset, length, cancellationToken);
+#else
+            await OutputStream.WriteAsync(buffer.AsMemory(offset, length), cancellationToken);
+#endif
         }
 
         public override async Task FlushAsync(CancellationToken cancellationToken)
diff --git a/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs b/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs
index 2137ae4..4d39b39 100644
--- a/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs
+++ b/lib/netstd/Thrift/Transport/Layered/TLayeredTransport.cs
@@ -1,3 +1,20 @@
+// 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.
+
 using System;
 using System.Collections.Generic;
 using System.Text;
diff --git a/lib/netstd/Thrift/Transport/Server/THttpServerTransport.cs b/lib/netstd/Thrift/Transport/Server/THttpServerTransport.cs
index 7271f50..05efba2 100644
--- a/lib/netstd/Thrift/Transport/Server/THttpServerTransport.cs
+++ b/lib/netstd/Thrift/Transport/Server/THttpServerTransport.cs
@@ -31,8 +31,10 @@
     public class THttpServerTransport
     {
         protected const string ContentType = "application/x-thrift";
+        /* never used
         private readonly ILogger _logger;
         private readonly RequestDelegate _next;
+        */
         protected Encoding Encoding = Encoding.UTF8;
 
         protected TProtocolFactory InputProtocolFactory;
@@ -85,20 +87,23 @@
             InputTransportFactory = inputTransFactory;
             OutputTransportFactory = outputTransFactory;
 
+            // never used
+            _ = next;
+            _ = loggerFactory;
+            /* never used
             _next = next;
             _logger = (loggerFactory != null) ? loggerFactory.CreateLogger<THttpServerTransport>() : new NullLogger<THttpServerTransport>();
+            */
         }
 
         public async Task Invoke(HttpContext context)
         {
-            context.Response.ContentType = ContentType;
             await ProcessRequestAsync(context, context.RequestAborted); //TODO: check for correct logic
         }
 
         public async Task ProcessRequestAsync(HttpContext context, CancellationToken cancellationToken)
         {
             var transport = new TStreamTransport(context.Request.Body, context.Response.Body, Configuration);
-
             try
             {
                 var intrans = (InputTransportFactory != null) ? InputTransportFactory.GetTransport(transport) : transport;
@@ -107,6 +112,7 @@
                 var input = InputProtocolFactory.GetProtocol(intrans);
                 var output = OutputProtocolFactory.GetProtocol(outtrans);
 
+                context.Response.ContentType = ContentType;
                 while (await Processor.ProcessAsync(input, output, cancellationToken))
                 {
                     if (!context.Response.HasStarted)  // oneway method called
@@ -116,7 +122,12 @@
             catch (TTransportException)
             {
                 if (!context.Response.HasStarted)  // if something goes bust, let the client know
-                    context.Response.StatusCode = 500;
+                    context.Response.StatusCode = 500;   // internal server error
+            }
+            catch (TProtocolException)
+            {
+                if (!context.Response.HasStarted)  // if something goes bust, let the client know
+                    context.Response.StatusCode = 400;   // bad request, e.g. required field missing
             }
             finally
             {
diff --git a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
index 3381110..35a037d 100644
--- a/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
+++ b/lib/netstd/Thrift/Transport/Server/TNamedPipeServerTransport.cs
@@ -27,6 +27,12 @@
 
 namespace Thrift.Transport.Server
 {
+    [Flags]
+    public enum NamedPipeClientFlags {
+        None = 0x00,
+        OnlyLocalClients = 0x01
+    };
+
     // ReSharper disable once InconsistentNaming
     public class TNamedPipeServerTransport : TServerTransport
     {
@@ -37,11 +43,21 @@
         private bool _asyncMode = true;
         private volatile bool _isPending = true;
         private NamedPipeServerStream _stream = null;
+        private readonly bool _onlyLocalClients = false;  // compatibility default
 
+        public TNamedPipeServerTransport(string pipeAddress, TConfiguration config, NamedPipeClientFlags flags)
+            : base(config)
+        {
+            _pipeAddress = pipeAddress;
+            _onlyLocalClients = flags.HasFlag(NamedPipeClientFlags.OnlyLocalClients);
+        }
+
+        [Obsolete("This CTOR is deprecated, please use the other one instead.")]
         public TNamedPipeServerTransport(string pipeAddress, TConfiguration config)
             : base(config)
         {
             _pipeAddress = pipeAddress;
+            _onlyLocalClients = false;
         }
 
         public override bool IsOpen() {
@@ -96,7 +112,7 @@
 
                 try
                 {
-                    var handle = CreatePipeNative(_pipeAddress, inbuf, outbuf);
+                    var handle = CreatePipeNative(_pipeAddress, inbuf, outbuf, _onlyLocalClients);
                     if ((handle != null) && (!handle.IsInvalid))
                     {
                         _stream = new NamedPipeServerStream(PipeDirection.InOut, _asyncMode, false, handle);
@@ -139,7 +155,7 @@
 
         private const string Kernel32 = "kernel32.dll";
 
-        [DllImport(Kernel32, SetLastError = true)]
+        [DllImport(Kernel32, SetLastError = true, CharSet = CharSet.Unicode)]
         internal static extern IntPtr CreateNamedPipe(
             string lpName, uint dwOpenMode, uint dwPipeMode,
             uint nMaxInstances, uint nOutBufferSize, uint nInBufferSize, uint nDefaultTimeOut,
@@ -149,16 +165,16 @@
 
 
         // Workaround: create the pipe via API call
-        // we have to do it this way, since NamedPipeServerStream() for netstd still lacks a few CTORs
+        // we have to do it this way, since NamedPipeServerStream() for netstd still lacks a few CTORs and/or arguments
         // and _stream.SetAccessControl(pipesec); only keeps throwing ACCESS_DENIED errors at us
         // References:
         // - https://github.com/dotnet/corefx/issues/30170 (closed, continued in 31190)
         // - https://github.com/dotnet/corefx/issues/31190 System.IO.Pipes.AccessControl package does not work
         // - https://github.com/dotnet/corefx/issues/24040 NamedPipeServerStream: Provide support for WRITE_DAC
         // - https://github.com/dotnet/corefx/issues/34400 Have a mechanism for lower privileged user to connect to a privileged user's pipe
-        private SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf)
+        private static SafePipeHandle CreatePipeNative(string name, int inbuf, int outbuf, bool OnlyLocalClients)
         {
-            if (Environment.OSVersion.Platform != PlatformID.Win32NT)
+            if (! RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                 return null; // Windows only
 
             var pinningHandle = new GCHandle();
@@ -187,18 +203,25 @@
                 }
 
                 // a bunch of constants we will need shortly
-                const int PIPE_ACCESS_DUPLEX = 0x00000003;
-                const int FILE_FLAG_OVERLAPPED = 0x40000000;
-                const int WRITE_DAC = 0x00040000;
-                const int PIPE_TYPE_BYTE = 0x00000000;
-                const int PIPE_READMODE_BYTE = 0x00000000;
-                const int PIPE_UNLIMITED_INSTANCES = 255;
+                const uint PIPE_ACCESS_DUPLEX = 0x00000003;
+                const uint FILE_FLAG_OVERLAPPED = 0x40000000;
+                const uint WRITE_DAC = 0x00040000;
+                const uint PIPE_TYPE_BYTE = 0x00000000;
+                const uint PIPE_READMODE_BYTE = 0x00000000;
+                const uint PIPE_UNLIMITED_INSTANCES = 255;
+                const uint PIPE_ACCEPT_REMOTE_CLIENTS = 0x00000000;  // Connections from remote clients can be accepted and checked against the security descriptor for the pipe.
+                const uint PIPE_REJECT_REMOTE_CLIENTS = 0x00000008;  // Connections from remote clients are automatically rejected. 
+
+                // any extra flags we want to add
+                uint dwPipeModeXtra
+                    = (OnlyLocalClients ? PIPE_REJECT_REMOTE_CLIENTS : PIPE_ACCEPT_REMOTE_CLIENTS)
+                    ;
 
                 // create the pipe via API call
                 var rawHandle = CreateNamedPipe(
                     @"\\.\pipe\" + name,
                     PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC,
-                    PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
+                    PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | dwPipeModeXtra,
                     PIPE_UNLIMITED_INSTANCES, (uint)inbuf, (uint)outbuf,
                     5 * 1000,
                     secAttrs
@@ -241,6 +264,11 @@
                 Close();
                 throw;
             }
+            catch (TaskCanceledException)
+            {
+                Close();
+                throw;  // let it bubble up
+            }
             catch (Exception e)
             {
                 Close();
@@ -279,10 +307,10 @@
                 }
 
                 CheckReadBytesAvailable(length);
-#if NETSTANDARD2_1
-                var numBytes = await PipeStream.ReadAsync(new Memory<byte>(buffer, offset, length), cancellationToken);
-#else
+#if NETSTANDARD2_0
                 var numBytes = await PipeStream.ReadAsync(buffer, offset, length, cancellationToken);
+#else
+                var numBytes = await PipeStream.ReadAsync(buffer.AsMemory(offset, length), cancellationToken);
 #endif
                 CountConsumedMessageBytes(numBytes);
                 return numBytes;
@@ -301,7 +329,11 @@
                 var nBytes = Math.Min(15 * 4096, length); // 16 would exceed the limit
                 while (nBytes > 0)
                 {
+#if NET5_0
+                    await PipeStream.WriteAsync(buffer.AsMemory(offset, nBytes), cancellationToken);
+#else
                     await PipeStream.WriteAsync(buffer, offset, nBytes, cancellationToken);
+#endif
                     offset += nBytes;
                     length -= nBytes;
                     nBytes = Math.Min(nBytes, length);
diff --git a/lib/netstd/Thrift/Transport/Server/TServerTransport.cs b/lib/netstd/Thrift/Transport/Server/TServerTransport.cs
index eee50fb..5366114 100644
--- a/lib/netstd/Thrift/Transport/Server/TServerTransport.cs
+++ b/lib/netstd/Thrift/Transport/Server/TServerTransport.cs
@@ -36,19 +36,9 @@
         public abstract void Close();
         public abstract bool IsClientPending();
 
-        protected virtual async ValueTask<TTransport> AcceptImplementationAsync()
-        {
-            return await AcceptImplementationAsync(CancellationToken.None);
-        }
+        protected abstract ValueTask<TTransport> AcceptImplementationAsync(CancellationToken cancellationToken = default);
 
-        protected abstract ValueTask<TTransport> AcceptImplementationAsync(CancellationToken cancellationToken);
-
-        public async ValueTask<TTransport> AcceptAsync()
-        {
-            return await AcceptAsync(CancellationToken.None);
-        }
-
-        public async ValueTask<TTransport> AcceptAsync(CancellationToken cancellationToken)
+        public async ValueTask<TTransport> AcceptAsync(CancellationToken cancellationToken = default)
         {
             var transport = await AcceptImplementationAsync(cancellationToken);
 
diff --git a/lib/netstd/Thrift/Transport/TEndpointTransport.cs b/lib/netstd/Thrift/Transport/TEndpointTransport.cs
index fa2ac6b..51a2a17 100644
--- a/lib/netstd/Thrift/Transport/TEndpointTransport.cs
+++ b/lib/netstd/Thrift/Transport/TEndpointTransport.cs
@@ -1,3 +1,20 @@
+// 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.
+
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
diff --git a/lib/ocaml/_oasis b/lib/ocaml/_oasis
index e5b0c84..a3c1cab 100644
--- a/lib/ocaml/_oasis
+++ b/lib/ocaml/_oasis
@@ -1,5 +1,5 @@
 Name: libthrift-ocaml
-Version: 0.14.2
+Version: 0.15.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 d36942b..4e399bc 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.14.2");
+use version 0.77; our $VERSION = version->declare("v0.15.0");
 
 1;
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
index c8bc50e..c016b07 100644
--- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.cpp
@@ -85,17 +85,10 @@
 const int INVALID_DATA = 1;
 const int BAD_VERSION = 4;
 
-static zend_function_entry thrift_protocol_functions[] = {
-  PHP_FE(thrift_protocol_write_binary, nullptr)
-  PHP_FE(thrift_protocol_read_binary, nullptr)
-  PHP_FE(thrift_protocol_read_binary_after_message_begin, nullptr)
-  {nullptr, nullptr, nullptr}
-};
-
 zend_module_entry thrift_protocol_module_entry = {
   STANDARD_MODULE_HEADER,
   "thrift_protocol",
-  thrift_protocol_functions,
+  ext_functions,
   nullptr,
   nullptr,
   nullptr,
@@ -414,7 +407,7 @@
   object_and_properties_init(return_value, ce, nullptr);
   zend_function* constructor = zend_std_get_constructor(Z_OBJ_P(return_value));
   zval ctor_rv;
-  zend_call_method(return_value, ce, &constructor, nullptr, 0, &ctor_rv, nargs, arg1, arg2);
+  zend_call_method(Z4_OBJ_P(return_value), ce, &constructor, nullptr, 0, &ctor_rv, nargs, arg1, arg2);
   zval_dtor(&ctor_rv);
   if (EG(exception)) {
     zend_object *ex = EG(exception);
@@ -928,7 +921,7 @@
 
             zval* is_required = zend_hash_str_find(fieldspec, "isRequired", sizeof("isRequired")-1);
             zval rv;
-            zval* prop = zend_read_property(object_class_entry, object, varname, strlen(varname), false, &rv);
+            zval* prop = zend_read_property(object_class_entry, Z4_OBJ_P(object), varname, strlen(varname), false, &rv);
 
             if (Z_TYPE_INFO_P(is_required) == IS_TRUE && Z_TYPE_P(prop) == IS_NULL) {
                 char errbuf[128];
@@ -969,7 +962,7 @@
         ZVAL_UNDEF(&rv);
 
         binary_deserialize(ttype, transport, &rv, fieldspec);
-        zend_update_property(ce, zthis, varname, strlen(varname), &rv);
+        zend_update_property(ce, Z4_OBJ_P(zthis), varname, strlen(varname), &rv);
 
         zval_ptr_dtor(&rv);
       } else {
@@ -1010,7 +1003,7 @@
     int8_t ttype = Z_LVAL_P(val_ptr);
 
     zval rv;
-    zval* prop = zend_read_property(Z_OBJCE_P(zthis), zthis, varname, strlen(varname), false, &rv);
+    zval* prop = zend_read_property(Z_OBJCE_P(zthis), Z4_OBJ_P(zthis), varname, strlen(varname), false, &rv);
 
     if (Z_TYPE_P(prop) == IS_REFERENCE){
       ZVAL_DEREF(prop);
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h
index 0420997..b8dc7de 100644
--- a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.h
@@ -19,10 +19,58 @@
 
 #pragma once
 
-PHP_FUNCTION(thrift_protocol_write_binary);
-PHP_FUNCTION(thrift_protocol_read_binary);
-PHP_FUNCTION(thrift_protocol_read_binary_after_message_begin);
+/* backward compat macros */
 
-extern zend_module_entry thrift_protocol_module_entry;
-#define phpext_thrift_protocol_ptr &thrift_protocol_module_entry
+#if PHP_VERSION_ID >= 80000
+# define Z4_OBJ_P(zval)       (Z_OBJ_P(zval))
+#else
+# define Z4_OBJ_P(zval)       (zval)
+#endif
 
+#ifndef IS_MIXED
+# define IS_MIXED 0
+#endif
+
+#ifndef ZEND_PARSE_PARAMETERS_NONE
+#define ZEND_PARSE_PARAMETERS_NONE() \
+  ZEND_PARSE_PARAMETERS_START(0, 0) \
+  ZEND_PARSE_PARAMETERS_END()
+#endif
+#ifndef ZEND_ARG_INFO_WITH_DEFAULT_VALUE
+#define ZEND_ARG_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, default_value) \
+  ZEND_ARG_INFO(pass_by_ref, name)
+#endif
+
+#if PHP_VERSION_ID < 70200
+#undef ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX
+#define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
+  static const zend_internal_arg_info name[] = { \
+    { (const char*)(zend_uintptr_t)(required_num_args), ( #class_name ), 0, return_reference, allow_null, 0 },
+#endif
+
+#ifndef ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX
+# define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(name, return_reference, required_num_args, class_name, allow_null) \
+  ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(name, return_reference, required_num_args, class_name, allow_null)
+#endif
+
+#ifndef ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX
+# define ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(name, return_reference, num_args, type) \
+  ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, num_args)
+#endif
+
+#ifndef ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX
+# define ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(name, return_reference, required_num_args, class_name, type) \
+  ZEND_BEGIN_ARG_INFO_EX(name, 0, return_reference, required_num_args)
+#endif
+
+#ifndef ZEND_ARG_TYPE_MASK
+# define ZEND_ARG_TYPE_MASK(pass_by_ref, name, type_mask, default_value) \
+  ZEND_ARG_TYPE_INFO(pass_by_ref, name, 0, 0)
+#endif
+
+#ifndef ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE
+# define ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(pass_by_ref, name, type_hint, allow_null, default_value) \
+  ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null)
+#endif
+
+#include "php_thrift_protocol_arginfo.h"
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol.stub.php b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.stub.php
new file mode 100644
index 0000000..e9601c3
--- /dev/null
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol.stub.php
@@ -0,0 +1,10 @@
+<?php
+/** @generate-function-entries */
+
+// php /path/to/php-src/build/gen_stub.php lib/php/src/ext/thrift_protocol/php_thrift_protocol.stub.php
+
+function thrift_protocol_write_binary(object $protocol, string $method_name, int $msgtype, object $request_struct, int $seqID, bool $strict_write): void {}
+
+function thrift_protocol_read_binary(object $protocol, string $obj_typename, bool $strict_read, int $buffer_size=8192): object {}
+
+function thrift_protocol_read_binary_after_message_begin(object $protocol, string $obj_typename, bool $strict_read, int $buffer_size=8192): object {}
diff --git a/lib/php/src/ext/thrift_protocol/php_thrift_protocol_arginfo.h b/lib/php/src/ext/thrift_protocol/php_thrift_protocol_arginfo.h
new file mode 100644
index 0000000..a727db0
--- /dev/null
+++ b/lib/php/src/ext/thrift_protocol/php_thrift_protocol_arginfo.h
@@ -0,0 +1,33 @@
+/* This is a generated file, edit the .stub.php file instead.
+ * Stub hash: 3bd6e0bc99143d614ddb80ee0aec192e385c8927 */
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_thrift_protocol_write_binary, 0, 6, IS_VOID, 0)
+	ZEND_ARG_TYPE_INFO(0, protocol, IS_OBJECT, 0)
+	ZEND_ARG_TYPE_INFO(0, method_name, IS_STRING, 0)
+	ZEND_ARG_TYPE_INFO(0, msgtype, IS_LONG, 0)
+	ZEND_ARG_TYPE_INFO(0, request_struct, IS_OBJECT, 0)
+	ZEND_ARG_TYPE_INFO(0, seqID, IS_LONG, 0)
+	ZEND_ARG_TYPE_INFO(0, strict_write, _IS_BOOL, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_thrift_protocol_read_binary, 0, 3, IS_OBJECT, 0)
+	ZEND_ARG_TYPE_INFO(0, protocol, IS_OBJECT, 0)
+	ZEND_ARG_TYPE_INFO(0, obj_typename, IS_STRING, 0)
+	ZEND_ARG_TYPE_INFO(0, strict_read, _IS_BOOL, 0)
+	ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, buffer_size, IS_LONG, 0, "8192")
+ZEND_END_ARG_INFO()
+
+#define arginfo_thrift_protocol_read_binary_after_message_begin arginfo_thrift_protocol_read_binary
+
+
+ZEND_FUNCTION(thrift_protocol_write_binary);
+ZEND_FUNCTION(thrift_protocol_read_binary);
+ZEND_FUNCTION(thrift_protocol_read_binary_after_message_begin);
+
+
+static const zend_function_entry ext_functions[] = {
+	ZEND_FE(thrift_protocol_write_binary, arginfo_thrift_protocol_write_binary)
+	ZEND_FE(thrift_protocol_read_binary, arginfo_thrift_protocol_read_binary)
+	ZEND_FE(thrift_protocol_read_binary_after_message_begin, arginfo_thrift_protocol_read_binary_after_message_begin)
+	ZEND_FE_END
+};
diff --git a/lib/py/setup.py b/lib/py/setup.py
index efce17d..caa7147 100644
--- a/lib/py/setup.py
+++ b/lib/py/setup.py
@@ -91,7 +91,7 @@
     twisted_deps = ['twisted']
 
     setup(name='thrift',
-          version='0.14.2',
+          version='0.15.0',
           description='Python bindings for the Apache Thrift RPC system',
           author='Apache Thrift Developers',
           author_email='dev@thrift.apache.org',
diff --git a/lib/rb/Rakefile b/lib/rb/Rakefile
index 5e5e5ac..b509281 100644
--- a/lib/rb/Rakefile
+++ b/lib/rb/Rakefile
@@ -54,7 +54,7 @@
 
   task :'flat_spec' do
     dir = File.dirname(__FILE__) + '/spec'
-    mkdir_p("#{dir}/gen-rb/flat")
+    FileUtils.mkdir_p("#{dir}/gen-rb/flat")
     sh THRIFT, '--gen', 'rb', '--recurse', '-out', "#{dir}/gen-rb/flat", "#{dir}/ThriftNamespacedSpec.thrift"
   end
 
diff --git a/lib/rb/ext/compact_protocol.c b/lib/rb/ext/compact_protocol.c
index c0f46b9..fab2170 100644
--- a/lib/rb/ext/compact_protocol.c
+++ b/lib/rb/ext/compact_protocol.c
@@ -567,6 +567,7 @@
 
 static void Init_constants() {
   thrift_compact_protocol_class = rb_const_get(thrift_module, rb_intern("CompactProtocol"));
+  rb_global_variable(&thrift_compact_protocol_class);
 
   VERSION = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION")));
   VERSION_MASK = rb_num2ll(rb_const_get(thrift_compact_protocol_class, rb_intern("VERSION_MASK")));
diff --git a/lib/rb/ext/struct.c b/lib/rb/ext/struct.c
index e3aa855..79cbabe 100644
--- a/lib/rb/ext/struct.c
+++ b/lib/rb/ext/struct.c
@@ -698,14 +698,23 @@
   rb_define_method(struct_module, "read", rb_thrift_struct_read, 1);
 
   thrift_union_class = rb_const_get(thrift_module, rb_intern("Union"));
+  rb_global_variable(&thrift_union_class);
 
   rb_define_method(thrift_union_class, "write", rb_thrift_union_write, 1);
   rb_define_method(thrift_union_class, "read", rb_thrift_union_read, 1);
 
   setfield_id = rb_intern("@setfield");
+  rb_global_variable(&setfield_id);
+
   setvalue_id = rb_intern("@value");
+  rb_global_variable(&setvalue_id);
 
   to_s_method_id = rb_intern("to_s");
+  rb_global_variable(&to_s_method_id);
+
   name_to_id_method_id = rb_intern("name_to_id");
+  rb_global_variable(&name_to_id_method_id);
+
   sorted_field_ids_method_id = rb_intern("sorted_field_ids");
+  rb_global_variable(&sorted_field_ids_method_id);
 }
diff --git a/lib/rb/ext/thrift_native.c b/lib/rb/ext/thrift_native.c
index 3430b7c..d535454 100644
--- a/lib/rb/ext/thrift_native.c
+++ b/lib/rb/ext/thrift_native.c
@@ -112,10 +112,19 @@
 void Init_thrift_native() {
   // cached classes
   thrift_module = rb_const_get(rb_cObject, rb_intern("Thrift"));
+  rb_global_variable(&thrift_module);
+
   thrift_bytes_module = rb_const_get(thrift_module, rb_intern("Bytes"));
+  rb_global_variable(&thrift_bytes_module);
+
   thrift_types_module = rb_const_get(thrift_module, rb_intern("Types"));
+  rb_global_variable(&thrift_types_module);
+
   rb_cSet = rb_const_get(rb_cObject, rb_intern("Set"));
+  rb_global_variable(&rb_cSet);
+
   protocol_exception_class = rb_const_get(thrift_module, rb_intern("ProtocolException"));
+  rb_global_variable(&protocol_exception_class);
 
   // Init ttype constants
   TTYPE_BOOL = FIX2INT(rb_const_get(thrift_types_module, rb_intern("BOOL")));
@@ -194,6 +203,14 @@
   class_sym = ID2SYM(rb_intern("class"));
   binary_sym = ID2SYM(rb_intern("binary"));
 
+  rb_global_variable(&type_sym);
+  rb_global_variable(&name_sym);
+  rb_global_variable(&key_sym);
+  rb_global_variable(&value_sym);
+  rb_global_variable(&element_sym);
+  rb_global_variable(&class_sym);
+  rb_global_variable(&binary_sym);
+
   Init_struct();
   Init_binary_protocol_accelerated();
   Init_compact_protocol();
diff --git a/lib/rb/spec/spec_helper.rb b/lib/rb/spec/spec_helper.rb
index 5bf98d0..7c16507 100644
--- a/lib/rb/spec/spec_helper.rb
+++ b/lib/rb/spec/spec_helper.rb
@@ -62,3 +62,8 @@
 
 $:.unshift File.join(File.dirname(__FILE__), *%w[gen-rb/flat])
 
+if defined?(GC.verify_compaction_references) == 'method'
+  # This method was added in Ruby 3.0.0. Calling it this way asks the GC to
+  # move objects around, helping to find object movement bugs.
+  GC.verify_compaction_references(double_heap: true, toward: :empty)
+end
diff --git a/lib/rb/thrift.gemspec b/lib/rb/thrift.gemspec
index fe1b543..d0366a7 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.14.2'
+  s.version     = '0.15.0'
   s.authors     = ['Apache Thrift Developers']
   s.email       = ['dev@thrift.apache.org']
   s.homepage    = 'http://thrift.apache.org'
@@ -27,7 +27,7 @@
 
   s.require_paths = %w[lib ext]
 
-  s.add_development_dependency 'bundler',            '~> 1.11'
+  s.add_development_dependency 'bundler',            '>= 1.11'
   s.add_development_dependency 'pry',                '~> 0.11.3'
   s.add_development_dependency 'pry-byebug',         '~> 3.6'
   s.add_development_dependency 'pry-stack_explorer', '~> 0.4.9.2'
@@ -35,6 +35,7 @@
   s.add_development_dependency 'rack-test',          '~> 0.8.3'
   s.add_development_dependency 'rake',               '~> 12.3'
   s.add_development_dependency 'rspec',              '~> 3.7'
+  s.add_development_dependency 'srv',                '~> 1.0'
   s.add_development_dependency 'thin',               '~> 1.7'
 end
 
diff --git a/lib/rs/Cargo.toml b/lib/rs/Cargo.toml
index 05dfe03..505b9a9 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 = "2018"
-version = "0.14.2"
+version = "0.15.0"
 license = "Apache-2.0"
 authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
 homepage = "http://thrift.apache.org"
diff --git a/lib/rs/Makefile.am b/lib/rs/Makefile.am
index 6d74348..7a9b30a 100644
--- a/lib/rs/Makefile.am
+++ b/lib/rs/Makefile.am
@@ -21,6 +21,7 @@
 
 if WITH_TESTS
 SUBDIRS += test
+SUBDIRS += test_recursive
 endif
 
 install:
@@ -31,9 +32,13 @@
 	@echo '##############################################################'
 
 check-local:
+	$(CARGO) fmt --all -- --check
+	$(CARGO) clippy --all -- -D warnings
 	$(CARGO) test
 
 all-local:
+	$(CARGO) fmt --all -- --check
+	$(CARGO) clippy --all -- -D warnings
 	$(CARGO) build
 
 clean-local:
diff --git a/lib/rs/README.md b/lib/rs/README.md
index 555d219..30e36d4 100644
--- a/lib/rs/README.md
+++ b/lib/rs/README.md
@@ -46,6 +46,135 @@
 
 Breaking changes are minimized. When they are made they will be outlined below with transition guidelines.
 
+##### Thrift 0.15.0
+
+* **[THRIFT-5360]** - No longer define OR generate `description()` methods for `Error` types.
+
+  `Error.description()` was soft-deprecated in 1.27, and deprecated as of 1.41.
+  Library error types also do not implement `Error.description()`. Also, as a result of this change
+  the generated Rust representation of an Error no longer implements the `Error.description()` method.
+  Instead, it generates a `Display` impl with the same information.
+
+  For example:
+
+  ```thrift
+  exception Xception {
+    1: i32 errorCode,
+    2: string message
+  }
+  ```
+
+  used to generate:
+
+  ```rust
+  use std::error::Error;
+  use std::fmt;
+  use std::fmt::{Display, Formatter};
+
+  // auto-generated by the Thrift compiler
+  #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
+  pub struct Xception {
+    pub error_code: Option<i32>,
+    pub message: Option<String>,
+  }
+
+  // auto-generated by the Thrift compiler
+  impl Error for Xception {
+    fn description(&self) -> &str {
+      "remote service threw Xception"
+    }
+  }
+
+  // auto-generated by the Thrift compiler
+  impl From<Xception> for thrift::Error {
+    fn from(e: Xception) -> Self {
+      thrift::Error::User(Box::new(e))
+    }
+  }
+
+  // auto-generated by the Thrift compiler
+  impl Display for Xception {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+      self.description().format(f)
+    }
+  }
+  ```
+
+  It *now* generates:
+
+  ```rust
+  use std::error::Error;
+  use std::fmt;
+  use std::fmt::{Display, Formatter};
+
+  // auto-generated by the Thrift compiler
+  #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
+  pub struct Xception {
+    pub error_code: Option<i32>,
+    pub message: Option<String>,
+  }
+
+  // auto-generated by the Thrift compiler
+  impl Error for Xception { }
+
+  // auto-generated by the Thrift compiler
+  impl From<Xception> for thrift::Error {
+    fn from(e: Xception) -> Self {
+      thrift::Error::User(Box::new(e))
+    }
+  }
+
+  // auto-generated by the Thrift compiler
+  impl Display for Xception {
+    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+      write!(f, "remote service threw Xception")
+    }
+  }
+  ```
+
+* **[THRIFT-5314]** - Generate enums implementations that are forward compatible (i.e. don't error on unknown values)
+
+  As a result of this change the Rust representation of an enum changes from a standard
+  Rust enum into a newtype struct with associated constants.
+  
+  For example:
+
+  ```thrift
+    // THRIFT
+    enum Operation {
+      ADD,
+      SUBTRACT,
+      MULTIPLY,
+      DIVIDE,
+    }
+  ```
+
+  used to generate:
+  
+  ```rust
+    // OLD AUTO-GENERATED RUST
+    pub enum Operation {
+       Add,
+       Subtract,
+       Multiply,
+       Divide,
+     }
+  ```
+
+  It *now* generates:
+  
+  ```rust
+    // NEW AUTO-GENERATED RUST
+    pub struct Operation(pub i32);
+  
+    impl Operation {
+      pub const ADD: Operation = Operation(0);
+      pub const SUBTRACT: Operation = Operation(1);
+      pub const MULTIPLY: Operation = Operation(2);
+      pub const DIVIDE: Operation = Operation(3);
+    }
+  ```
+
 ##### Thrift 0.14.0
 
 * **[THRIFT-5158]** - Rust library and generator now support Rust 2018 only. Required rust 1.40.0 or higher
@@ -91,7 +220,9 @@
        DIVIDE,
      }
     ```
+  
     It *now* generates:
+  
     ```rust
     // NEW AUTO-GENERATED RUST
     pub enum Operation {
diff --git a/lib/rs/src/errors.rs b/lib/rs/src/errors.rs
index 41a055e..fc26330 100644
--- a/lib/rs/src/errors.rs
+++ b/lib/rs/src/errors.rs
@@ -15,13 +15,14 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use std::convert::TryFrom;
 use std::convert::{From, Into};
-use std::error::Error as StdError;
 use std::fmt::{Debug, Display, Formatter};
 use std::{error, fmt, io, string};
-use std::convert::TryFrom;
 
-use crate::protocol::{TFieldIdentifier, TInputProtocol, TOutputProtocol, TStructIdentifier, TType};
+use crate::protocol::{
+    TFieldIdentifier, TInputProtocol, TOutputProtocol, TStructIdentifier, TType,
+};
 
 // FIXME: should all my error structs impl error::Error as well?
 // FIXME: should all fields in TransportError, ProtocolError and ApplicationError be optional?
@@ -144,11 +145,7 @@
 /// }
 ///
 /// // auto-generated by the Thrift compiler
-/// impl Error for Xception {
-///   fn description(&self) -> &str {
-///     "remote service threw Xception"
-///   }
-/// }
+/// impl Error for Xception { }
 ///
 /// // auto-generated by the Thrift compiler
 /// impl From<Xception> for thrift::Error {
@@ -160,7 +157,7 @@
 /// // auto-generated by the Thrift compiler
 /// impl Display for Xception {
 ///   fn fmt(&self, f: &mut Formatter) -> fmt::Result {
-///     self.description().fmt(f)
+///     write!(f, "remote service threw Xception")
 ///   }
 /// }
 ///
@@ -235,10 +232,7 @@
 
         i.read_struct_end()?;
 
-        Ok(ApplicationError {
-            kind,
-            message,
-        })
+        Ok(ApplicationError { kind, message })
     }
 
     /// Convert an `ApplicationError` into its wire representation and write
@@ -271,16 +265,7 @@
     }
 }
 
-impl error::Error for Error {
-    fn description(&self) -> &str {
-        match *self {
-            Error::Transport(ref e) => TransportError::description(e),
-            Error::Protocol(ref e) => ProtocolError::description(e),
-            Error::Application(ref e) => ApplicationError::description(e),
-            Error::User(ref e) => e.description(),
-        }
-    }
-}
+impl error::Error for Error {}
 
 impl Debug for Error {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
@@ -371,6 +356,7 @@
 /// I/O error categories.
 ///
 /// This list may grow, and it is not recommended to match against it.
+#[non_exhaustive]
 #[derive(Clone, Copy, Eq, Debug, PartialEq)]
 pub enum TransportErrorKind {
     /// Catch-all I/O error.
@@ -389,9 +375,9 @@
     SizeLimit = 6,
 }
 
-impl TransportError {
-    fn description(&self) -> &str {
-        match self.kind {
+impl Display for TransportError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        let error_text = match self.kind {
             TransportErrorKind::Unknown => "transport error",
             TransportErrorKind::NotOpen => "not open",
             TransportErrorKind::AlreadyOpen => "already open",
@@ -399,13 +385,9 @@
             TransportErrorKind::EndOfFile => "end of file",
             TransportErrorKind::NegativeSize => "negative size message",
             TransportErrorKind::SizeLimit => "message too long",
-        }
-    }
-}
+        };
 
-impl Display for TransportError {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.description())
+        write!(f, "{}", error_text)
     }
 }
 
@@ -435,24 +417,24 @@
             | io::ErrorKind::ConnectionRefused
             | io::ErrorKind::NotConnected => Error::Transport(TransportError {
                 kind: TransportErrorKind::NotOpen,
-                message: err.description().to_owned(),
+                message: err.to_string(),
             }),
             io::ErrorKind::AlreadyExists => Error::Transport(TransportError {
                 kind: TransportErrorKind::AlreadyOpen,
-                message: err.description().to_owned(),
+                message: err.to_string(),
             }),
             io::ErrorKind::TimedOut => Error::Transport(TransportError {
                 kind: TransportErrorKind::TimedOut,
-                message: err.description().to_owned(),
+                message: err.to_string(),
             }),
             io::ErrorKind::UnexpectedEof => Error::Transport(TransportError {
                 kind: TransportErrorKind::EndOfFile,
-                message: err.description().to_owned(),
+                message: err.to_string(),
             }),
             _ => {
                 Error::Transport(TransportError {
                     kind: TransportErrorKind::Unknown,
-                    message: err.description().to_owned(), // FIXME: use io error's debug string
+                    message: err.to_string(), // FIXME: use io error's debug string
                 })
             }
         }
@@ -463,7 +445,7 @@
     fn from(err: string::FromUtf8Error) -> Self {
         Error::Protocol(ProtocolError {
             kind: ProtocolErrorKind::InvalidData,
-            message: err.description().to_owned(), // FIXME: use fmt::Error's debug string
+            message: err.to_string(), // FIXME: use fmt::Error's debug string
         })
     }
 }
@@ -499,6 +481,7 @@
 /// Runtime library error categories.
 ///
 /// This list may grow, and it is not recommended to match against it.
+#[non_exhaustive]
 #[derive(Clone, Copy, Eq, Debug, PartialEq)]
 pub enum ProtocolErrorKind {
     /// Catch-all runtime-library error.
@@ -519,9 +502,9 @@
     DepthLimit = 6,
 }
 
-impl ProtocolError {
-    fn description(&self) -> &str {
-        match self.kind {
+impl Display for ProtocolError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        let error_text = match self.kind {
             ProtocolErrorKind::Unknown => "protocol error",
             ProtocolErrorKind::InvalidData => "bad data",
             ProtocolErrorKind::NegativeSize => "negative message size",
@@ -529,13 +512,9 @@
             ProtocolErrorKind::BadVersion => "invalid thrift version",
             ProtocolErrorKind::NotImplemented => "not implemented",
             ProtocolErrorKind::DepthLimit => "maximum skip depth reached",
-        }
-    }
-}
+        };
 
-impl Display for ProtocolError {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.description())
+        write!(f, "{}", error_text)
     }
 }
 
@@ -590,6 +569,7 @@
 /// Auto-generated or user-implemented code error categories.
 ///
 /// This list may grow, and it is not recommended to match against it.
+#[non_exhaustive]
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum ApplicationErrorKind {
     /// Catch-all application error.
@@ -619,9 +599,9 @@
     UnsupportedClientType = 10, // ??
 }
 
-impl ApplicationError {
-    fn description(&self) -> &str {
-        match self.kind {
+impl Display for ApplicationError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
+        let error_text = match self.kind {
             ApplicationErrorKind::Unknown => "service error",
             ApplicationErrorKind::UnknownMethod => "unknown service method",
             ApplicationErrorKind::InvalidMessageType => "wrong message type received",
@@ -633,13 +613,9 @@
             ApplicationErrorKind::InvalidTransform => "invalid transform",
             ApplicationErrorKind::InvalidProtocol => "invalid protocol requested",
             ApplicationErrorKind::UnsupportedClientType => "unsupported protocol client",
-        }
-    }
-}
+        };
 
-impl Display for ApplicationError {
-    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        write!(f, "{}", self.description())
+        write!(f, "{}", error_text)
     }
 }
 
diff --git a/lib/rs/src/lib.rs b/lib/rs/src/lib.rs
index f71c3e8..ddc7b0d 100644
--- a/lib/rs/src/lib.rs
+++ b/lib/rs/src/lib.rs
@@ -44,6 +44,13 @@
 //! | transport |
 //! +-----------+
 //! ```
+//!
+//! # Tutorial
+//!
+//! For an example of how to setup a simple client and server using this crate
+//! see the [tutorial].
+//!
+//! [tutorial]: https://github.com/apache/thrift/tree/master/tutorial/rs
 
 #![crate_type = "lib"]
 #![doc(test(attr(allow(unused_variables), deny(warnings))))]
@@ -80,4 +87,5 @@
 pub type Result<T> = std::result::Result<T, self::Error>;
 
 // Re-export ordered-float, since it is used by the generator
-pub use ordered_float::OrderedFloat as OrderedFloat;
\ No newline at end of file
+// FIXME: check the guidance around type reexports
+pub use ordered_float::OrderedFloat;
diff --git a/lib/rs/src/protocol/binary.rs b/lib/rs/src/protocol/binary.rs
index 22b496c..8509c34 100644
--- a/lib/rs/src/protocol/binary.rs
+++ b/lib/rs/src/protocol/binary.rs
@@ -68,10 +68,7 @@
     /// Set `strict` to `true` if all incoming messages contain the protocol
     /// version number in the protocol header.
     pub fn new(transport: T, strict: bool) -> TBinaryInputProtocol<T> {
-        TBinaryInputProtocol {
-            strict,
-            transport,
-        }
+        TBinaryInputProtocol { strict, transport }
     }
 }
 
@@ -294,10 +291,7 @@
     /// Set `strict` to `true` if all outgoing messages should contain the
     /// protocol version number in the protocol header.
     pub fn new(transport: T, strict: bool) -> TBinaryOutputProtocol<T> {
-        TBinaryOutputProtocol {
-            strict,
-            transport,
-        }
+        TBinaryOutputProtocol { strict, transport }
     }
 }
 
@@ -453,7 +447,10 @@
 }
 
 impl TOutputProtocolFactory for TBinaryOutputProtocolFactory {
-    fn create(&self, transport: Box<dyn TWriteTransport + Send>) -> Box<dyn TOutputProtocol + Send> {
+    fn create(
+        &self,
+        transport: Box<dyn TWriteTransport + Send>,
+    ) -> Box<dyn TOutputProtocol + Send> {
         Box::new(TBinaryOutputProtocol::new(transport, true))
     }
 }
diff --git a/lib/rs/src/protocol/compact.rs b/lib/rs/src/protocol/compact.rs
index 6fa364f..e08a30b 100644
--- a/lib/rs/src/protocol/compact.rs
+++ b/lib/rs/src/protocol/compact.rs
@@ -128,7 +128,8 @@
 
         // NOTE: unsigned right shift will pad with 0s
         let message_type: TMessageType = TMessageType::try_from(type_and_byte >> 5)?;
-        let sequence_number = self.read_i32()?;
+        // writing side wrote signed sequence number as u32 to avoid zigzag encoding
+        let sequence_number = self.transport.read_varint::<u32>()? as i32;
         let service_call_name = self.read_string()?;
 
         self.last_read_field_id = 0;
@@ -247,7 +248,9 @@
     }
 
     fn read_double(&mut self) -> crate::Result<f64> {
-        self.transport.read_f64::<LittleEndian>().map_err(From::from)
+        self.transport
+            .read_f64::<LittleEndian>()
+            .map_err(From::from)
     }
 
     fn read_string(&mut self) -> crate::Result<String> {
@@ -388,7 +391,11 @@
         Ok(())
     }
 
-    fn write_list_set_begin(&mut self, element_type: TType, element_count: i32) -> crate::Result<()> {
+    fn write_list_set_begin(
+        &mut self,
+        element_type: TType,
+        element_count: i32,
+    ) -> crate::Result<()> {
         let elem_identifier = collection_type_to_u8(element_type);
         if element_count <= 14 {
             let header = (element_count as u8) << 4 | elem_identifier;
@@ -396,6 +403,8 @@
         } else {
             let header = 0xF0 | elem_identifier;
             self.write_byte(header)?;
+            // element count is strictly positive as per the spec, so
+            // cast i32 as u32 so that varint writing won't use zigzag encoding
             self.transport
                 .write_varint(element_count as u32)
                 .map_err(From::from)
@@ -417,7 +426,9 @@
     fn write_message_begin(&mut self, identifier: &TMessageIdentifier) -> crate::Result<()> {
         self.write_byte(COMPACT_PROTOCOL_ID)?;
         self.write_byte((u8::from(identifier.message_type) << 5) | COMPACT_VERSION)?;
-        self.write_i32(identifier.sequence_number)?;
+        // cast i32 as u32 so that varint writing won't use zigzag encoding
+        self.transport
+            .write_varint(identifier.sequence_number as u32)?;
         self.write_string(&identifier.name)?;
         Ok(())
     }
@@ -491,6 +502,8 @@
     }
 
     fn write_bytes(&mut self, b: &[u8]) -> crate::Result<()> {
+        // length is strictly positive as per the spec, so
+        // cast i32 as u32 so that varint writing won't use zigzag encoding
         self.transport.write_varint(b.len() as u32)?;
         self.transport.write_all(b).map_err(From::from)
     }
@@ -521,7 +534,9 @@
     }
 
     fn write_double(&mut self, d: f64) -> crate::Result<()> {
-        self.transport.write_f64::<LittleEndian>(d).map_err(From::from)
+        self.transport
+            .write_f64::<LittleEndian>(d)
+            .map_err(From::from)
     }
 
     fn write_string(&mut self, s: &str) -> crate::Result<()> {
@@ -548,6 +563,8 @@
         if identifier.size == 0 {
             self.write_byte(0)
         } else {
+            // element count is strictly positive as per the spec, so
+            // cast i32 as u32 so that varint writing won't use zigzag encoding
             self.transport.write_varint(identifier.size as u32)?;
 
             let key_type = identifier
@@ -593,7 +610,10 @@
 }
 
 impl TOutputProtocolFactory for TCompactOutputProtocolFactory {
-    fn create(&self, transport: Box<dyn TWriteTransport + Send>) -> Box<dyn TOutputProtocol + Send> {
+    fn create(
+        &self,
+        transport: Box<dyn TWriteTransport + Send>,
+    ) -> Box<dyn TOutputProtocol + Send> {
         Box::new(TCompactOutputProtocol::new(transport))
     }
 }
@@ -655,6 +675,8 @@
 #[cfg(test)]
 mod tests {
 
+    use std::i32;
+
     use crate::protocol::{
         TFieldIdentifier, TInputProtocol, TListIdentifier, TMapIdentifier, TMessageIdentifier,
         TMessageType, TOutputProtocol, TSetIdentifier, TStructIdentifier, TType,
@@ -664,7 +686,62 @@
     use super::*;
 
     #[test]
-    fn must_write_message_begin_0() {
+    fn must_write_message_begin_largest_maximum_positive_sequence_number() {
+        let (_, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
+            "bar",
+            TMessageType::Reply,
+            i32::MAX
+        )));
+
+        #[rustfmt::skip]
+        let expected: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x41, /* message type | protocol version */
+            0xFF,
+            0xFF,
+            0xFF,
+            0xFF,
+            0x07, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x62,
+            0x61,
+            0x72 /* "bar" */,
+        ];
+
+        assert_eq_written_bytes!(o_prot, expected);
+    }
+
+    #[test]
+    fn must_read_message_begin_largest_maximum_positive_sequence_number() {
+        let (mut i_prot, _) = test_objects();
+
+        #[rustfmt::skip]
+        let source_bytes: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x41, /* message type | protocol version */
+            0xFF,
+            0xFF,
+            0xFF,
+            0xFF,
+            0x07, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x62,
+            0x61,
+            0x72 /* "bar" */,
+        ];
+
+        i_prot.transport.set_readable_bytes(&source_bytes);
+
+        let expected = TMessageIdentifier::new("bar", TMessageType::Reply, i32::MAX);
+        let res = assert_success!(i_prot.read_message_begin());
+
+        assert_eq!(&expected, &res);
+    }
+
+    #[test]
+    fn must_write_message_begin_positive_sequence_number_0() {
         let (_, mut o_prot) = test_objects();
 
         assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
@@ -677,8 +754,8 @@
         let expected: [u8; 8] = [
             0x82, /* protocol ID */
             0x21, /* message type | protocol version */
-            0xDE,
-            0x06, /* zig-zag varint sequence number */
+            0xAF,
+            0x03, /* non-zig-zag varint sequence number */
             0x03, /* message-name length */
             0x66,
             0x6F,
@@ -689,7 +766,31 @@
     }
 
     #[test]
-    fn must_write_message_begin_1() {
+    fn must_read_message_begin_positive_sequence_number_0() {
+        let (mut i_prot, _) = test_objects();
+
+        #[rustfmt::skip]
+        let source_bytes: [u8; 8] = [
+            0x82, /* protocol ID */
+            0x21, /* message type | protocol version */
+            0xAF,
+            0x03, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x66,
+            0x6F,
+            0x6F /* "foo" */,
+        ];
+
+        i_prot.transport.set_readable_bytes(&source_bytes);
+
+        let expected = TMessageIdentifier::new("foo", TMessageType::Call, 431);
+        let res = assert_success!(i_prot.read_message_begin());
+
+        assert_eq!(&expected, &res);
+    }
+
+    #[test]
+    fn must_write_message_begin_positive_sequence_number_1() {
         let (_, mut o_prot) = test_objects();
 
         assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
@@ -702,9 +803,9 @@
         let expected: [u8; 9] = [
             0x82, /* protocol ID */
             0x41, /* message type | protocol version */
-            0xA8,
-            0x89,
-            0x79, /* zig-zag varint sequence number */
+            0xD4,
+            0xC4,
+            0x3C, /* non-zig-zag varint sequence number */
             0x03, /* message-name length */
             0x62,
             0x61,
@@ -715,6 +816,306 @@
     }
 
     #[test]
+    fn must_read_message_begin_positive_sequence_number_1() {
+        let (mut i_prot, _) = test_objects();
+
+        #[rustfmt::skip]
+        let source_bytes: [u8; 9] = [
+            0x82, /* protocol ID */
+            0x41, /* message type | protocol version */
+            0xD4,
+            0xC4,
+            0x3C, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x62,
+            0x61,
+            0x72 /* "bar" */,
+        ];
+
+        i_prot.transport.set_readable_bytes(&source_bytes);
+
+        let expected = TMessageIdentifier::new("bar", TMessageType::Reply, 991_828);
+        let res = assert_success!(i_prot.read_message_begin());
+
+        assert_eq!(&expected, &res);
+    }
+
+    #[test]
+    fn must_write_message_begin_zero_sequence_number() {
+        let (_, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
+            "bar",
+            TMessageType::Reply,
+            0
+        )));
+
+        #[rustfmt::skip]
+        let expected: [u8; 7] = [
+            0x82, /* protocol ID */
+            0x41, /* message type | protocol version */
+            0x00, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x62,
+            0x61,
+            0x72 /* "bar" */,
+        ];
+
+        assert_eq_written_bytes!(o_prot, expected);
+    }
+
+    #[test]
+    fn must_read_message_begin_zero_sequence_number() {
+        let (mut i_prot, _) = test_objects();
+
+        #[rustfmt::skip]
+        let source_bytes: [u8; 7] = [
+            0x82, /* protocol ID */
+            0x41, /* message type | protocol version */
+            0x00, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x62,
+            0x61,
+            0x72 /* "bar" */,
+        ];
+
+        i_prot.transport.set_readable_bytes(&source_bytes);
+
+        let expected = TMessageIdentifier::new("bar", TMessageType::Reply, 0);
+        let res = assert_success!(i_prot.read_message_begin());
+
+        assert_eq!(&expected, &res);
+    }
+
+    #[test]
+    fn must_write_message_begin_largest_minimum_negative_sequence_number() {
+        let (_, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
+            "bar",
+            TMessageType::Reply,
+            i32::MIN
+        )));
+
+        // two's complement notation of i32::MIN = 1000_0000_0000_0000_0000_0000_0000_0000
+        #[rustfmt::skip]
+        let expected: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x41, /* message type | protocol version */
+            0x80,
+            0x80,
+            0x80,
+            0x80,
+            0x08, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x62,
+            0x61,
+            0x72 /* "bar" */,
+        ];
+
+        assert_eq_written_bytes!(o_prot, expected);
+    }
+
+    #[test]
+    fn must_read_message_begin_largest_minimum_negative_sequence_number() {
+        let (mut i_prot, _) = test_objects();
+
+        // two's complement notation of i32::MIN = 1000_0000_0000_0000_0000_0000_0000_0000
+        #[rustfmt::skip]
+        let source_bytes: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x41, /* message type | protocol version */
+            0x80,
+            0x80,
+            0x80,
+            0x80,
+            0x08, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x62,
+            0x61,
+            0x72 /* "bar" */,
+        ];
+
+        i_prot.transport.set_readable_bytes(&source_bytes);
+
+        let expected = TMessageIdentifier::new("bar", TMessageType::Reply, i32::MIN);
+        let res = assert_success!(i_prot.read_message_begin());
+
+        assert_eq!(&expected, &res);
+    }
+
+    #[test]
+    fn must_write_message_begin_negative_sequence_number_0() {
+        let (_, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
+            "foo",
+            TMessageType::Call,
+            -431
+        )));
+
+        // signed two's complement of -431 = 1111_1111_1111_1111_1111_1110_0101_0001
+        #[rustfmt::skip]
+        let expected: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x21, /* message type | protocol version */
+            0xD1,
+            0xFC,
+            0xFF,
+            0xFF,
+            0x0F, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x66,
+            0x6F,
+            0x6F /* "foo" */,
+        ];
+
+        assert_eq_written_bytes!(o_prot, expected);
+    }
+
+    #[test]
+    fn must_read_message_begin_negative_sequence_number_0() {
+        let (mut i_prot, _) = test_objects();
+
+        // signed two's complement of -431 = 1111_1111_1111_1111_1111_1110_0101_0001
+        #[rustfmt::skip]
+        let source_bytes: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x21, /* message type | protocol version */
+            0xD1,
+            0xFC,
+            0xFF,
+            0xFF,
+            0x0F, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x66,
+            0x6F,
+            0x6F /* "foo" */,
+        ];
+
+        i_prot.transport.set_readable_bytes(&source_bytes);
+
+        let expected = TMessageIdentifier::new("foo", TMessageType::Call, -431);
+        let res = assert_success!(i_prot.read_message_begin());
+
+        assert_eq!(&expected, &res);
+    }
+
+    #[test]
+    fn must_write_message_begin_negative_sequence_number_1() {
+        let (_, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
+            "foo",
+            TMessageType::Call,
+            -73_184_125
+        )));
+
+        // signed two's complement of -73184125 = 1111_1011_1010_0011_0100_1100_1000_0011
+        #[rustfmt::skip]
+        let expected: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x21, /* message type | protocol version */
+            0x83,
+            0x99,
+            0x8D,
+            0xDD,
+            0x0F, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x66,
+            0x6F,
+            0x6F /* "foo" */,
+        ];
+
+        assert_eq_written_bytes!(o_prot, expected);
+    }
+
+    #[test]
+    fn must_read_message_begin_negative_sequence_number_1() {
+        let (mut i_prot, _) = test_objects();
+
+        // signed two's complement of -73184125 = 1111_1011_1010_0011_0100_1100_1000_0011
+        #[rustfmt::skip]
+        let source_bytes: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x21, /* message type | protocol version */
+            0x83,
+            0x99,
+            0x8D,
+            0xDD,
+            0x0F, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x66,
+            0x6F,
+            0x6F /* "foo" */,
+        ];
+
+        i_prot.transport.set_readable_bytes(&source_bytes);
+
+        let expected = TMessageIdentifier::new("foo", TMessageType::Call, -73_184_125);
+        let res = assert_success!(i_prot.read_message_begin());
+
+        assert_eq!(&expected, &res);
+    }
+
+    #[test]
+    fn must_write_message_begin_negative_sequence_number_2() {
+        let (_, mut o_prot) = test_objects();
+
+        assert_success!(o_prot.write_message_begin(&TMessageIdentifier::new(
+            "foo",
+            TMessageType::Call,
+            -1_073_741_823
+        )));
+
+        // signed two's complement of -1073741823 = 1100_0000_0000_0000_0000_0000_0000_0001
+        #[rustfmt::skip]
+        let expected: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x21, /* message type | protocol version */
+            0x81,
+            0x80,
+            0x80,
+            0x80,
+            0x0C, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x66,
+            0x6F,
+            0x6F /* "foo" */,
+        ];
+
+        assert_eq_written_bytes!(o_prot, expected);
+    }
+
+    #[test]
+    fn must_read_message_begin_negative_sequence_number_2() {
+        let (mut i_prot, _) = test_objects();
+
+        // signed two's complement of -1073741823 = 1100_0000_0000_0000_0000_0000_0000_0001
+        #[rustfmt::skip]
+        let source_bytes: [u8; 11] = [
+            0x82, /* protocol ID */
+            0x21, /* message type | protocol version */
+            0x81,
+            0x80,
+            0x80,
+            0x80,
+            0x0C, /* non-zig-zag varint sequence number */
+            0x03, /* message-name length */
+            0x66,
+            0x6F,
+            0x6F, /* "foo" */
+        ];
+
+        i_prot.transport.set_readable_bytes(&source_bytes);
+
+        let expected = TMessageIdentifier::new("foo", TMessageType::Call, -1_073_741_823);
+        let res = assert_success!(i_prot.read_message_begin());
+
+        assert_eq!(&expected, &res);
+    }
+
+    #[test]
     fn must_round_trip_upto_i64_maxvalue() {
         // See https://issues.apache.org/jira/browse/THRIFT-5131
         for i in 0..64 {
@@ -722,11 +1123,7 @@
             let val: i64 = ((1u64 << i) - 1) as i64;
 
             o_prot
-                .write_field_begin(&TFieldIdentifier::new(
-                    "val",
-                    TType::I64,
-                    1
-                ))
+                .write_field_begin(&TFieldIdentifier::new("val", TType::I64, 1))
                 .unwrap();
             o_prot.write_i64(val).unwrap();
             o_prot.write_field_end().unwrap();
diff --git a/lib/rs/src/protocol/mod.rs b/lib/rs/src/protocol/mod.rs
index f9c1f72..e11a104 100644
--- a/lib/rs/src/protocol/mod.rs
+++ b/lib/rs/src/protocol/mod.rs
@@ -577,14 +577,18 @@
 /// ```
 pub trait TOutputProtocolFactory {
     /// Create a `TOutputProtocol` that writes bytes to `transport`.
-    fn create(&self, transport: Box<dyn TWriteTransport + Send>) -> Box<dyn TOutputProtocol + Send>;
+    fn create(&self, transport: Box<dyn TWriteTransport + Send>)
+        -> Box<dyn TOutputProtocol + Send>;
 }
 
 impl<T> TOutputProtocolFactory for Box<T>
 where
     T: TOutputProtocolFactory + ?Sized,
 {
-    fn create(&self, transport: Box<dyn TWriteTransport + Send>) -> Box<dyn TOutputProtocol + Send> {
+    fn create(
+        &self,
+        transport: Box<dyn TWriteTransport + Send>,
+    ) -> Box<dyn TOutputProtocol + Send> {
         (**self).create(transport)
     }
 }
@@ -679,10 +683,7 @@
     /// Create a `TListIdentifier` for a list with `size` elements of type
     /// `element_type`.
     pub fn new(element_type: TType, size: i32) -> TListIdentifier {
-        TListIdentifier {
-            element_type,
-            size,
-        }
+        TListIdentifier { element_type, size }
     }
 }
 
@@ -699,10 +700,7 @@
     /// Create a `TSetIdentifier` for a set with `size` elements of type
     /// `element_type`.
     pub fn new(element_type: TType, size: i32) -> TSetIdentifier {
-        TSetIdentifier {
-            element_type,
-            size,
-        }
+        TSetIdentifier { element_type, size }
     }
 }
 
@@ -878,7 +876,10 @@
 /// `actual`.
 ///
 /// Return `()` if `actual == expected`, `Err` otherwise.
-pub fn verify_expected_message_type(expected: TMessageType, actual: TMessageType) -> crate::Result<()> {
+pub fn verify_expected_message_type(
+    expected: TMessageType,
+    actual: TMessageType,
+) -> crate::Result<()> {
     if expected == actual {
         Ok(())
     } else {
diff --git a/lib/rs/src/protocol/multiplexed.rs b/lib/rs/src/protocol/multiplexed.rs
index 83498fb..697b7e6 100644
--- a/lib/rs/src/protocol/multiplexed.rs
+++ b/lib/rs/src/protocol/multiplexed.rs
@@ -191,7 +191,9 @@
 #[cfg(test)]
 mod tests {
 
-    use crate::protocol::{TBinaryOutputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol};
+    use crate::protocol::{
+        TBinaryOutputProtocol, TMessageIdentifier, TMessageType, TOutputProtocol,
+    };
     use crate::transport::{TBufferChannel, TIoChannel, WriteHalf};
 
     use super::*;
diff --git a/lib/rs/src/server/mod.rs b/lib/rs/src/server/mod.rs
index 050feee..64c6da2 100644
--- a/lib/rs/src/server/mod.rs
+++ b/lib/rs/src/server/mod.rs
@@ -91,7 +91,8 @@
     /// the response to `o`.
     ///
     /// Returns `()` if the handler was executed; `Err` otherwise.
-    fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol) -> crate::Result<()>;
+    fn process(&self, i: &mut dyn TInputProtocol, o: &mut dyn TOutputProtocol)
+        -> crate::Result<()>;
 }
 
 /// Convenience function used in generated `TProcessor` implementations to
diff --git a/lib/rs/src/server/multiplexed.rs b/lib/rs/src/server/multiplexed.rs
index 4f41f24..8331d91 100644
--- a/lib/rs/src/server/multiplexed.rs
+++ b/lib/rs/src/server/multiplexed.rs
@@ -136,7 +136,11 @@
 }
 
 impl TProcessor for TMultiplexedProcessor {
-    fn process(&self, i_prot: &mut dyn TInputProtocol, o_prot: &mut dyn TOutputProtocol) -> crate::Result<()> {
+    fn process(
+        &self,
+        i_prot: &mut dyn TInputProtocol,
+        o_prot: &mut dyn TOutputProtocol,
+    ) -> crate::Result<()> {
         let msg_ident = i_prot.read_message_begin()?;
 
         debug!("process incoming msg id:{:?}", &msg_ident);
@@ -183,7 +187,9 @@
     use std::sync::atomic::{AtomicBool, Ordering};
     use std::sync::Arc;
 
-    use crate::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TMessageIdentifier, TMessageType};
+    use crate::protocol::{
+        TBinaryInputProtocol, TBinaryOutputProtocol, TMessageIdentifier, TMessageType,
+    };
     use crate::transport::{ReadHalf, TBufferChannel, TIoChannel, WriteHalf};
     use crate::{ApplicationError, ApplicationErrorKind};
 
@@ -261,7 +267,11 @@
     }
 
     impl TProcessor for Service {
-        fn process(&self, _: &mut dyn TInputProtocol, _: &mut dyn TOutputProtocol) -> crate::Result<()> {
+        fn process(
+            &self,
+            _: &mut dyn TInputProtocol,
+            _: &mut dyn TOutputProtocol,
+        ) -> crate::Result<()> {
             let res = self
                 .invoked
                 .compare_and_swap(false, true, Ordering::Relaxed);
diff --git a/lib/rs/src/server/threaded.rs b/lib/rs/src/server/threaded.rs
index 64bf8bb..897235c 100644
--- a/lib/rs/src/server/threaded.rs
+++ b/lib/rs/src/server/threaded.rs
@@ -21,7 +21,9 @@
 use std::sync::Arc;
 use threadpool::ThreadPool;
 
-use crate::protocol::{TInputProtocol, TInputProtocolFactory, TOutputProtocol, TOutputProtocolFactory};
+use crate::protocol::{
+    TInputProtocol, TInputProtocolFactory, TOutputProtocol, TOutputProtocolFactory,
+};
 use crate::transport::{TIoChannel, TReadTransportFactory, TTcpChannel, TWriteTransportFactory};
 use crate::{ApplicationError, ApplicationErrorKind};
 
@@ -196,7 +198,10 @@
     fn new_protocols_for_connection(
         &mut self,
         stream: TcpStream,
-    ) -> crate::Result<(Box<dyn TInputProtocol + Send>, Box<dyn TOutputProtocol + Send>)> {
+    ) -> crate::Result<(
+        Box<dyn TInputProtocol + Send>,
+        Box<dyn TOutputProtocol + Send>,
+    )> {
         // create the shared tcp stream
         let channel = TTcpChannel::with_stream(stream);
 
@@ -227,10 +232,11 @@
     let mut o_prot = o_prot;
     loop {
         match processor.process(&mut *i_prot, &mut *o_prot) {
-            Ok(()) => {},
+            Ok(()) => {}
             Err(err) => {
                 match err {
-                    crate::Error::Transport(ref transport_err) if transport_err.kind == TransportErrorKind::EndOfFile => {},
+                    crate::Error::Transport(ref transport_err)
+                        if transport_err.kind == TransportErrorKind::EndOfFile => {}
                     other => warn!("processor completed with error: {:?}", other),
                 }
                 break;
diff --git a/lib/rs/src/transport/buffered.rs b/lib/rs/src/transport/buffered.rs
index ebdcdc2..a54f823 100644
--- a/lib/rs/src/transport/buffered.rs
+++ b/lib/rs/src/transport/buffered.rs
@@ -365,7 +365,7 @@
         assert_eq!(&buf, &[0, 1, 2, 3, 4, 5, 6, 7]);
 
         // let's clear out the buffer and try read again
-        for b in &mut buf{
+        for b in &mut buf {
             *b = 0;
         }
         let read_result = t.read(&mut buf);
diff --git a/lib/rs/src/transport/mod.rs b/lib/rs/src/transport/mod.rs
index d02a87c..2b5733f 100644
--- a/lib/rs/src/transport/mod.rs
+++ b/lib/rs/src/transport/mod.rs
@@ -111,7 +111,12 @@
     /// Returned halves may share the underlying OS channel or buffer resources.
     /// Implementations **should ensure** that these two halves can be safely
     /// used independently by concurrent threads.
-    fn split(self) -> crate::Result<(crate::transport::ReadHalf<Self>, crate::transport::WriteHalf<Self>)>
+    fn split(
+        self,
+    ) -> crate::Result<(
+        crate::transport::ReadHalf<Self>,
+        crate::transport::WriteHalf<Self>,
+    )>
     where
         Self: Sized;
 }
diff --git a/lib/rs/test/Makefile.am b/lib/rs/test/Makefile.am
index 5dc4f56..017a2c4 100644
--- a/lib/rs/test/Makefile.am
+++ b/lib/rs/test/Makefile.am
@@ -28,6 +28,8 @@
 	$(THRIFT) -out src --gen rs $(top_builddir)/test/Identifiers.thrift #THRIFT-4953
 
 check: stubs
+	$(CARGO) fmt --all -- --check
+	$(CARGO) clippy --all -- -D warnings
 	$(CARGO) build
 	$(CARGO) test
 	[ -d bin ] || mkdir bin
diff --git a/lib/rs/test/src/bin/kitchen_sink_server.rs b/lib/rs/test/src/bin/kitchen_sink_server.rs
index 6df39e4..8b910b3 100644
--- a/lib/rs/test/src/bin/kitchen_sink_server.rs
+++ b/lib/rs/test/src/bin/kitchen_sink_server.rs
@@ -209,12 +209,12 @@
 impl FullMealAndDrinksServiceSyncHandler for FullHandler {
     fn handle_full_meal_and_drinks(&self) -> thrift::Result<FullMealAndDrinks> {
         println!("full_meal_and_drinks: handling full meal and drinks call");
-        Ok(FullMealAndDrinks::new(full_meal(), Drink::CanadianWhisky))
+        Ok(FullMealAndDrinks::new(full_meal(), Drink::CANADIAN_WHISKY))
     }
 
     fn handle_best_pie(&self) -> thrift::Result<Pie> {
         println!("full_meal_and_drinks: handling pie call");
-        Ok(Pie::MississippiMud) // I prefer Pie::Pumpkin, but I have to check that casing works
+        Ok(Pie::MISSISSIPPI_MUD) // I prefer Pie::Pumpkin, but I have to check that casing works
     }
 }
 
@@ -259,7 +259,7 @@
 }
 
 fn ramen() -> Ramen {
-    Ramen::new("Mr Ramen".to_owned(), 72, BrothType::Miso)
+    Ramen::new("Mr Ramen".to_owned(), 72, BrothType::MISO)
 }
 
 fn napkin() -> Napkin {
diff --git a/lib/rs/test_recursive/Cargo.toml b/lib/rs/test_recursive/Cargo.toml
new file mode 100644
index 0000000..6b2aa85
--- /dev/null
+++ b/lib/rs/test_recursive/Cargo.toml
@@ -0,0 +1,9 @@
+[package]
+name = "thrift_4098_custom_rust_namespace_support"
+description = "Test namespace support in generated thrift files using recursive Make generation"
+version = "0.1.0"
+authors = ["Allen George <allengeorge@apache.org>"]
+edition = "2018"
+
+[dependencies]
+thrift = { path = "../" }
diff --git a/build/cmake/FindCabal.cmake b/lib/rs/test_recursive/Makefile.am
similarity index 69%
copy from build/cmake/FindCabal.cmake
copy to lib/rs/test_recursive/Makefile.am
index fed337b..e676ccd 100644
--- a/build/cmake/FindCabal.cmake
+++ b/lib/rs/test_recursive/Makefile.am
@@ -17,14 +17,17 @@
 # under the License.
 #
 
+SUBDIRS = src
 
-#  Cabal_FOUND - system has Cabal
-#  Cabal - the Cabal executable
-#
-# It will search the environment variable CABAL_HOME if it is set
+check:
+	$(CARGO) fmt --all -- --check
+	$(CARGO) clippy --all -- -D warnings
+	$(CARGO) build
+	$(CARGO) test
 
-include(FindPackageHandleStandardArgs)
+clean-local:
+	$(CARGO) clean
+	-$(RM) Cargo.lock
 
-find_program(CABAL NAMES cabal PATHS $ENV{HOME}/.cabal/bin $ENV{CABAL_HOME}/bin)
-find_package_handle_standard_args(CABAL DEFAULT_MSG CABAL)
-mark_as_advanced(CABAL)
+EXTRA_DIST = \
+	Cargo.toml
diff --git a/build/cmake/FindCabal.cmake b/lib/rs/test_recursive/src/Makefile.am
similarity index 69%
copy from build/cmake/FindCabal.cmake
copy to lib/rs/test_recursive/src/Makefile.am
index fed337b..c21a94c 100644
--- a/build/cmake/FindCabal.cmake
+++ b/lib/rs/test_recursive/src/Makefile.am
@@ -17,14 +17,17 @@
 # under the License.
 #
 
+SUBDIRS = . transit maintenance
 
-#  Cabal_FOUND - system has Cabal
-#  Cabal - the Cabal executable
-#
-# It will search the environment variable CABAL_HOME if it is set
+THRIFT = $(top_builddir)/compiler/cpp/thrift
 
-include(FindPackageHandleStandardArgs)
+stubs: Vehicles.thrift $(THRIFT)
+	$(THRIFT) -I . -out . --gen rs Vehicles.thrift
 
-find_program(CABAL NAMES cabal PATHS $ENV{HOME}/.cabal/bin $ENV{CABAL_HOME}/bin)
-find_package_handle_standard_args(CABAL DEFAULT_MSG CABAL)
-mark_as_advanced(CABAL)
+check: stubs
+
+clean-local:
+	-$(RM) vehicles.rs
+
+EXTRA_DIST = \
+	Vehicles.thrift
diff --git a/lib/as3/src/org/apache/thrift/TFieldRequirementType.as b/lib/rs/test_recursive/src/Vehicles.thrift
similarity index 71%
copy from lib/as3/src/org/apache/thrift/TFieldRequirementType.as
copy to lib/rs/test_recursive/src/Vehicles.thrift
index 6fb4e58..5cce21c 100644
--- a/lib/as3/src/org/apache/thrift/TFieldRequirementType.as
+++ b/lib/rs/test_recursive/src/Vehicles.thrift
@@ -15,18 +15,21 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
  */
 
-package org.apache.thrift {
+typedef i16 Capacity
 
-  /**
-   * Requirement type constants.
-   *
-   */
-  public class TFieldRequirementType {
-    public static const REQUIRED:int  = 1;
-    public static const OPTIONAL:int = 2;
-    public static const DEFAULT:int = 3;
-  }
-  
+enum Material {
+  Steel = 0
+  Aluminum = 1
+}
+
+struct VehicleIdentifier {
+  1: string manufacturer
+  2: string model
+  3: list<string> qualifiers
 }
diff --git a/lib/rs/test_recursive/src/lib.rs b/lib/rs/test_recursive/src/lib.rs
new file mode 100644
index 0000000..bac37b4
--- /dev/null
+++ b/lib/rs/test_recursive/src/lib.rs
@@ -0,0 +1,276 @@
+// 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.
+
+#![allow(dead_code)]
+
+pub mod transit;
+pub mod vehicles;
+pub mod maintenance;
+
+mod server {
+    use crate::maintenance::maintenance_facility::{
+        BigBarnSyncHandler, MultimodalFacilitySyncHandler,
+    };
+    use crate::transit::buses::{Bus, GarageSyncHandler};
+    use crate::transit::buses::{Powertrain, Route as BusRoute};
+    use crate::transit::light::streetcars::{
+        BarnSyncHandler, Flexity, RollingStock, Route, RouteNumber, Streetcar,
+    };
+    use crate::transit::services::city_services::TransitImprovements;
+    use crate::transit::trains::Locomotive;
+    use crate::transit::transporters::{FlatcarConsist, SingleVehicleTransporter};
+    use crate::vehicles::Material;
+    use thrift::Result;
+
+    //
+    // implement a whole bunch of handler methods just to make sure I can, and that everything compiles
+    //
+
+    pub struct AllInOneHandler;
+
+    impl BigBarnSyncHandler for AllInOneHandler {
+        fn handle_add_streetcar(&self, route: Route) -> Result<Streetcar> {
+            if let Some(route_number) = route.id {
+                match route_number {
+                    RouteNumber::LAKESHORE => Ok(Streetcar {
+                        id: Some(4417),
+                        stock: Some(RollingStock::Flexity(Flexity {
+                            materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+                            locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+                        })),
+                        route: Some(Route {
+                            id: Some(RouteNumber::LAKESHORE),
+                            improvements: None,
+                        }),
+                    }),
+                    _ => Err(thrift::Error::from(format!(
+                        "Cannot create streetcar for route number {}",
+                        route_number.0
+                    ))),
+                }
+            } else {
+                Err(thrift::Error::from("Can't add a streetcar"))
+            }
+        }
+    }
+
+    impl BarnSyncHandler for AllInOneHandler {
+        fn handle_upgrade_streetcar(&self, streetcar: Streetcar) -> Result<Streetcar> {
+            if let Some(rolling_stock) = streetcar.stock {
+                match rolling_stock {
+                    RollingStock::Clrv(_) => Ok(Streetcar {
+                        stock: Some(RollingStock::Flexity(Flexity {
+                            materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+                            locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+                        })),
+                        ..streetcar
+                    }),
+                    RollingStock::Flexity(_) => {
+                        Err(thrift::Error::from("Streetcar already upgraded"))
+                    }
+                }
+            } else {
+                Err(thrift::Error::from("Can't upgrade streetcar"))
+            }
+        }
+    }
+
+    impl MultimodalFacilitySyncHandler for AllInOneHandler {
+        fn handle_build_transporter(
+            &self,
+            source: String,
+            destination: String,
+            consist: FlatcarConsist,
+        ) -> Result<SingleVehicleTransporter> {
+            Ok(SingleVehicleTransporter {
+                consist: Some(consist),
+                source: Some(source),
+                destination: Some(destination),
+            })
+        }
+    }
+
+    impl GarageSyncHandler for AllInOneHandler {
+        fn handle_upgrade_bus(&self, bus: Bus) -> Result<Bus> {
+            if let Some(p) = bus.powertrain {
+                match p {
+                    Powertrain::COMPRESSED_NATURAL_GAS => Ok(Bus {
+                        powertrain: Some(Powertrain::DIESEL),
+                        ..bus
+                    }),
+                    _ => Err(thrift::Error::from("Cannot upgrade from this powertrain")),
+                }
+            } else {
+                Err(thrift::Error::from("Cannot upgrade bus"))
+            }
+        }
+
+        fn handle_improvements_for_route(
+            &self,
+            route: BusRoute,
+        ) -> Result<Vec<TransitImprovements>> {
+            Ok(route
+                .improvements
+                .expect("Expecting a list of improvements"))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+
+    //
+    // TODO: consider using the generated client/server and doing a round-trip
+    //
+
+    use crate::server::AllInOneHandler;
+    use crate::transit::buses::{Bus, Powertrain, Route as BusRoute, DEFAULT4WHEELCAPACITY};
+    use crate::transit::light::light_rail::Lrt;
+    use crate::transit::light::streetcars::{
+        BarnSyncHandler, Flexity, RollingStock, Route, RouteNumber, Streetcar, CLRV,
+    };
+    use crate::transit::services::city_services::TransitImprovements;
+    use crate::transit::trains::Locomotive;
+    use crate::transit::transporters::{FlatcarConsist, SingleVehicleTransporter};
+    use crate::vehicles::{Material, VehicleIdentifier};
+
+    use crate::maintenance::maintenance_facility::{
+        BigBarnSyncHandler, MultimodalFacilitySyncHandler,
+    };
+    use crate::transit::buses::GarageSyncHandler;
+
+    #[test]
+    fn handle_add_streetcar_compiles_and_returns_expected_value() {
+        let expected = Streetcar {
+            id: Some(4417),
+            stock: Some(RollingStock::Flexity(Flexity {
+                materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+                locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+            })),
+            route: Some(Route {
+                id: Some(RouteNumber::LAKESHORE),
+                improvements: None,
+            }),
+        };
+
+        let handler = AllInOneHandler {};
+        let actual = handler
+            .handle_add_streetcar(Route {
+                id: Some(RouteNumber::LAKESHORE),
+                improvements: None,
+            })
+            .expect("Expected a result");
+
+        assert_eq!(expected, actual)
+    }
+
+    #[test]
+    fn handle_upgrade_streetcar_compiles_and_returns_expected_value() {
+        let input = Streetcar {
+            stock: Some(RollingStock::Clrv(CLRV {
+                materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+                locomotive: Some(Locomotive::ELECTRIC_POLE),
+            })),
+            id: Some(4415),
+            route: Some(Route {
+                id: Some(RouteNumber::SPADINA),
+                improvements: Some(vec![TransitImprovements::DEDICATED_RIGHT_OF_WAY]),
+            }),
+        };
+
+        let expected = Streetcar {
+            stock: Some(RollingStock::Flexity(Flexity {
+                materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+                locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+            })),
+            id: Some(4415),
+            route: Some(Route {
+                id: Some(RouteNumber::SPADINA),
+                improvements: Some(vec![TransitImprovements::DEDICATED_RIGHT_OF_WAY]),
+            }),
+        };
+
+        let handler = AllInOneHandler {};
+        let actual = handler
+            .handle_upgrade_streetcar(input)
+            .expect("Expected an upgraded streetcar");
+
+        assert_eq!(expected, actual)
+    }
+
+    #[test]
+    fn handle_build_transporter_compiles_and_returns_expected_value() {
+        let consist = FlatcarConsist::Lrt(Lrt {
+            materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+            locomotive: Some(Locomotive::ELECTRIC_PANTOGRAPH),
+        });
+        let expected = SingleVehicleTransporter {
+            consist: Some(consist.clone()),
+            source: Some("905".to_owned()),
+            destination: Some("416".to_owned()),
+        };
+
+        let handler = AllInOneHandler {};
+        let actual = handler
+            .handle_build_transporter("905".to_owned(), "416".to_owned(), consist)
+            .expect("Expected a transporter");
+
+        assert_eq!(expected, actual)
+    }
+
+    #[test]
+    fn handle_upgrade_bus_compiles_and_returns_expected_value() {
+        let bus = Bus {
+            identifier: Some(VehicleIdentifier {
+                manufacturer: Some("Orion".to_owned()),
+                model: Some("Orion 07.501 NG HEV".to_owned()),
+                qualifiers: None,
+            }),
+            capacity: Some(DEFAULT4WHEELCAPACITY),
+            powertrain: Some(Powertrain::COMPRESSED_NATURAL_GAS),
+            materials: Some(vec![Material::STEEL, Material::ALUMINUM]),
+        };
+
+        let expected = Bus {
+            powertrain: Some(Powertrain::DIESEL),
+            ..(bus.clone())
+        };
+
+        let handler = AllInOneHandler {};
+        let actual = handler
+            .handle_upgrade_bus(bus)
+            .expect("Expected improved bus");
+
+        assert_eq!(expected, actual)
+    }
+
+    #[test]
+    fn handle_improvements_for_route_compiles_and_returns_expected_value() {
+        let expected = vec![TransitImprovements::TRANSIT_SIGNAL_PRIORITY];
+        let bus_route = BusRoute {
+            route_id: Some("320".to_owned()),
+            improvements: Some(expected.clone()),
+        };
+
+        let handler = AllInOneHandler {};
+        let actual = handler
+            .handle_improvements_for_route(bus_route)
+            .expect("Expected list of transit improvements");
+
+        assert_eq!(expected, actual)
+    }
+}
diff --git a/lib/rs/test_recursive/src/maintenance/MaintenanceFacility.thrift b/lib/rs/test_recursive/src/maintenance/MaintenanceFacility.thrift
new file mode 100644
index 0000000..bed0b8d
--- /dev/null
+++ b/lib/rs/test_recursive/src/maintenance/MaintenanceFacility.thrift
@@ -0,0 +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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace rs maintenance
+
+include "Buses.thrift"
+include "LightRail.thrift"
+include "Streetcars.thrift"
+include "Transporters.thrift"
+
+service BigBarn extends Streetcars.Barn {
+    Streetcars.Streetcar addStreetcar(1: Streetcars.Route route)
+}
+
+service MultimodalFacility extends Buses.Garage {
+    Transporters.SingleVehicleTransporter buildTransporter(1: string source, 2: string destination, 3: Transporters.FlatcarConsist consist)
+}
\ No newline at end of file
diff --git a/lib/hs/Makefile.am b/lib/rs/test_recursive/src/maintenance/Makefile.am
similarity index 62%
copy from lib/hs/Makefile.am
copy to lib/rs/test_recursive/src/maintenance/Makefile.am
index ba156a1..c24813a 100644
--- a/lib/hs/Makefile.am
+++ b/lib/rs/test_recursive/src/maintenance/Makefile.am
@@ -17,37 +17,17 @@
 # under the License.
 #
 
-EXTRA_DIST = \
-	coding_standards.md \
-	CMakeLists.txt \
-	LICENSE \
-	README.md \
-	Setup.lhs \
-	TODO \
-	thrift.cabal \
-	src \
-	test
+SUBDIRS = .
 
-all-local:
-	$(CABAL) update
-	$(CABAL) install
+THRIFT = $(top_builddir)/compiler/cpp/thrift
 
-install-exec-hook:
-	$(CABAL) install
+stubs: ../Vehicles.thrift ../transit/Buses.thrift ../transit/Trains.thrift ../transit/Transporters.thrift ../transit/services/CityServices.thrift ../transit/light/LightRail.thrift ../transit/light/Streetcars.thrift $(THRIFT)
+	$(THRIFT) -I . -I ../ -I ../transit -I ../transit/services -I ../transit/light -out . --gen rs MaintenanceFacility.thrift
 
-# Make sure this doesn't fail if Haskell is not configured.
+check: stubs
+
 clean-local:
-	$(CABAL) clean
+	-$(RM) maintenance_facility.rs
 
-dist-local:
-	$(CABAL) sdist
-
-maintainer-clean-local:
-	$(CABAL) clean
-
-check-local:
-	$(CABAL) check
-	$(CABAL) install --only-dependencies --enable-tests
-	$(CABAL) configure --enable-tests
-	$(CABAL) build
-	$(CABAL) test
+EXTRA_DIST = \
+	MaintenanceFacility.thrift
diff --git a/lib/dart/tool/dev.dart b/lib/rs/test_recursive/src/maintenance/mod.rs
similarity index 62%
copy from lib/dart/tool/dev.dart
copy to lib/rs/test_recursive/src/maintenance/mod.rs
index 27f8b8f..a75b6e1 100644
--- a/lib/dart/tool/dev.dart
+++ b/lib/rs/test_recursive/src/maintenance/mod.rs
@@ -6,7 +6,7 @@
 // "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
+//   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
@@ -15,19 +15,4 @@
 // specific language governing permissions and limitations
 // under the License.
 
-library tool.dev;
-
-import 'package:dart_dev/dart_dev.dart' show dev, config;
-
-main(List<String> args) async {
-  // https://github.com/Workiva/dart_dev
-
-  var directories = ['lib/', 'test/', 'tool/'];
-  config.analyze.entryPoints = directories;
-  config.format.directories = directories;
-  config.copyLicense
-    ..licensePath = 'LICENSE_HEADER'
-    ..directories = directories;
-
-  await dev(args);
-}
+pub mod maintenance_facility;
diff --git a/lib/rs/test_recursive/src/transit/Buses.thrift b/lib/rs/test_recursive/src/transit/Buses.thrift
new file mode 100644
index 0000000..29dc5fe
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/Buses.thrift
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+namespace rs transit
+
+include "CityServices.thrift"
+include "Vehicles.thrift"
+
+const Vehicles.Capacity DEFAULT4WHEELCAPACITY = 30
+
+enum Powertrain {
+  DIESEL = 0
+  BIO_DIESEL = 1
+  COMPRESSED_NATURAL_GAS = 2
+  TROLLEY = 3
+  HYBRID = 4
+  BATTERY = 5
+}
+
+struct Bus {
+  1: Vehicles.VehicleIdentifier identifier
+  2: Vehicles.Capacity capacity
+  3: Powertrain powertrain
+  4: list<Vehicles.Material> materials
+}
+
+struct Route {
+  1: string routeId
+  2: list<CityServices.TransitImprovements> improvements
+}
+
+service Garage {
+    Bus upgradeBus(1: Bus bus)
+
+    list<CityServices.TransitImprovements> improvementsForRoute(1: Route route)
+}
\ No newline at end of file
diff --git a/lib/rs/test_recursive/src/transit/Makefile.am b/lib/rs/test_recursive/src/transit/Makefile.am
new file mode 100644
index 0000000..7318265
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/Makefile.am
@@ -0,0 +1,40 @@
+#
+# 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.
+#
+
+# intentionally added a cyclic dependency between '.' and 'light'
+SUBDIRS = . light services
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+stubs: ../Vehicles.thrift Buses.thrift Trains.thrift Transporters.thrift services/CityServices.thrift light/LightRail.thrift light/Streetcars.thrift $(THRIFT)
+	$(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Buses.thrift
+	$(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Trains.thrift
+	$(THRIFT) -I . -I ../ -I ./services -I ./light -out . --gen rs Transporters.thrift
+
+check: stubs
+
+clean-local:
+	-$(RM) buses.rs
+	-$(RM) trains.rs
+	-$(RM) transporters.rs
+
+EXTRA_DIST = \
+	Buses.thrift \
+	Trains.thrift \
+	Transporters.thrift
diff --git a/lib/as3/src/org/apache/thrift/TFieldRequirementType.as b/lib/rs/test_recursive/src/transit/Trains.thrift
similarity index 71%
copy from lib/as3/src/org/apache/thrift/TFieldRequirementType.as
copy to lib/rs/test_recursive/src/transit/Trains.thrift
index 6fb4e58..6f97b53 100644
--- a/lib/as3/src/org/apache/thrift/TFieldRequirementType.as
+++ b/lib/rs/test_recursive/src/transit/Trains.thrift
@@ -15,18 +15,19 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
  */
 
-package org.apache.thrift {
+namespace rs transit
 
-  /**
-   * Requirement type constants.
-   *
-   */
-  public class TFieldRequirementType {
-    public static const REQUIRED:int  = 1;
-    public static const OPTIONAL:int = 2;
-    public static const DEFAULT:int = 3;
-  }
-  
+enum Locomotive {
+  Steam = 0
+  ElectricPole = 1
+  ElectricPantograph = 2
+  ElectricThirdRail = 3
+  DieselMechanical = 4
+  DieselElectric = 5
 }
diff --git a/lib/as3/src/org/apache/thrift/TFieldRequirementType.as b/lib/rs/test_recursive/src/transit/Transporters.thrift
similarity index 63%
copy from lib/as3/src/org/apache/thrift/TFieldRequirementType.as
copy to lib/rs/test_recursive/src/transit/Transporters.thrift
index 6fb4e58..540f1bb 100644
--- a/lib/as3/src/org/apache/thrift/TFieldRequirementType.as
+++ b/lib/rs/test_recursive/src/transit/Transporters.thrift
@@ -15,18 +15,26 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
  */
 
-package org.apache.thrift {
+namespace rs transit
 
-  /**
-   * Requirement type constants.
-   *
-   */
-  public class TFieldRequirementType {
-    public static const REQUIRED:int  = 1;
-    public static const OPTIONAL:int = 2;
-    public static const DEFAULT:int = 3;
-  }
-  
+include "Buses.thrift"
+include "LightRail.thrift"
+include "Streetcars.thrift"
+
+union FlatcarConsist {
+  1: LightRail.Lrt lrt
+  2: Streetcars.Streetcar streetcar
+  3: Buses.Bus bus
+}
+
+struct SingleVehicleTransporter {
+  1: FlatcarConsist consist
+  2: string source
+  3: string destination
 }
diff --git a/lib/rs/test_recursive/src/transit/light/LightRail.thrift b/lib/rs/test_recursive/src/transit/light/LightRail.thrift
new file mode 100644
index 0000000..0d887ab
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/light/LightRail.thrift
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+include "CityServices.thrift"
+include "Trains.thrift"
+include "Vehicles.thrift"
+
+namespace rs transit.light
+
+struct Lrt {
+  1: list<Vehicles.Material> materials
+  2: Trains.Locomotive locomotive
+}
+
+enum Route {
+  EglintonCrosstown = 0
+  FinchWest = 1
+}
+
+struct Line {
+  1: Lrt lrt
+  2: Route route
+  3: list<CityServices.TransitImprovements> improvements = [] // ABSOLUTELY NONE BY DEFAULT!
+}
+
+service Msf {
+    Lrt fixLrt(1: Lrt lrt)
+}
\ No newline at end of file
diff --git a/lib/hs/Makefile.am b/lib/rs/test_recursive/src/transit/light/Makefile.am
similarity index 62%
rename from lib/hs/Makefile.am
rename to lib/rs/test_recursive/src/transit/light/Makefile.am
index ba156a1..c09c39d 100644
--- a/lib/hs/Makefile.am
+++ b/lib/rs/test_recursive/src/transit/light/Makefile.am
@@ -17,37 +17,20 @@
 # under the License.
 #
 
-EXTRA_DIST = \
-	coding_standards.md \
-	CMakeLists.txt \
-	LICENSE \
-	README.md \
-	Setup.lhs \
-	TODO \
-	thrift.cabal \
-	src \
-	test
+SUBDIRS = .
 
-all-local:
-	$(CABAL) update
-	$(CABAL) install
+THRIFT = $(top_builddir)/compiler/cpp/thrift
 
-install-exec-hook:
-	$(CABAL) install
+stubs: ../../Vehicles.thrift ../Trains.thrift ../services/CityServices.thrift LightRail.thrift Streetcars.thrift $(THRIFT)
+	$(THRIFT) -I . -I ../../ -I ../ -I ../services -out . --gen rs LightRail.thrift
+	$(THRIFT) -I . -I ../../ -I ../ -I ../services -out . --gen rs Streetcars.thrift
 
-# Make sure this doesn't fail if Haskell is not configured.
+check: stubs
+
 clean-local:
-	$(CABAL) clean
+	-$(RM) light_rail.rs
+	-$(RM) streetcars.rs
 
-dist-local:
-	$(CABAL) sdist
-
-maintainer-clean-local:
-	$(CABAL) clean
-
-check-local:
-	$(CABAL) check
-	$(CABAL) install --only-dependencies --enable-tests
-	$(CABAL) configure --enable-tests
-	$(CABAL) build
-	$(CABAL) test
+EXTRA_DIST = \
+	LightRail.thrift \
+	Streetcars.thrift
diff --git a/lib/rs/test_recursive/src/transit/light/Streetcars.thrift b/lib/rs/test_recursive/src/transit/light/Streetcars.thrift
new file mode 100644
index 0000000..31d3ad4
--- /dev/null
+++ b/lib/rs/test_recursive/src/transit/light/Streetcars.thrift
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
+ */
+
+include "CityServices.thrift"
+include "Trains.thrift"
+include "Vehicles.thrift"
+
+namespace rs transit.light
+
+struct CLRV {
+  1: list<Vehicles.Material> materials
+  2: Trains.Locomotive locomotive
+}
+
+struct Flexity {
+  1: list<Vehicles.Material> materials
+  2: Trains.Locomotive locomotive
+}
+
+union RollingStock {
+  1: CLRV clrv
+  2: Flexity flexity
+}
+
+enum RouteNumber {
+  Queen = 501
+  Downtowner = 502
+  Kingston = 503
+  King = 504
+  Dundas = 505
+  Carlton = 506
+  Lakeshore = 508
+  Harbourfront = 509
+  Spadina = 510
+  Bathurst = 511
+  StClair = 512
+}
+
+struct Route {
+  1: RouteNumber id
+  2: list<CityServices.TransitImprovements> improvements = []  // ABSOLUTELY NONE!
+}
+
+struct Streetcar {
+  1: i16 id
+  2: RollingStock stock
+  3: Route route
+}
+
+service Barn {
+    Streetcar upgradeStreetcar(1: Streetcar streetcar)
+}
\ No newline at end of file
diff --git a/lib/dart/tool/dev.dart b/lib/rs/test_recursive/src/transit/light/mod.rs
similarity index 62%
copy from lib/dart/tool/dev.dart
copy to lib/rs/test_recursive/src/transit/light/mod.rs
index 27f8b8f..f68d099 100644
--- a/lib/dart/tool/dev.dart
+++ b/lib/rs/test_recursive/src/transit/light/mod.rs
@@ -6,7 +6,7 @@
 // "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
+//   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
@@ -15,19 +15,5 @@
 // specific language governing permissions and limitations
 // under the License.
 
-library tool.dev;
-
-import 'package:dart_dev/dart_dev.dart' show dev, config;
-
-main(List<String> args) async {
-  // https://github.com/Workiva/dart_dev
-
-  var directories = ['lib/', 'test/', 'tool/'];
-  config.analyze.entryPoints = directories;
-  config.format.directories = directories;
-  config.copyLicense
-    ..licensePath = 'LICENSE_HEADER'
-    ..directories = directories;
-
-  await dev(args);
-}
+pub mod light_rail;
+pub mod streetcars;
diff --git a/lib/dart/tool/dev.dart b/lib/rs/test_recursive/src/transit/mod.rs
similarity index 62%
copy from lib/dart/tool/dev.dart
copy to lib/rs/test_recursive/src/transit/mod.rs
index 27f8b8f..e144b38 100644
--- a/lib/dart/tool/dev.dart
+++ b/lib/rs/test_recursive/src/transit/mod.rs
@@ -6,7 +6,7 @@
 // "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
+//   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
@@ -15,19 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
-library tool.dev;
-
-import 'package:dart_dev/dart_dev.dart' show dev, config;
-
-main(List<String> args) async {
-  // https://github.com/Workiva/dart_dev
-
-  var directories = ['lib/', 'test/', 'tool/'];
-  config.analyze.entryPoints = directories;
-  config.format.directories = directories;
-  config.copyLicense
-    ..licensePath = 'LICENSE_HEADER'
-    ..directories = directories;
-
-  await dev(args);
-}
+pub mod buses;
+pub mod light;
+pub mod services;
+pub mod trains;
+pub mod transporters;
diff --git a/lib/as3/src/org/apache/thrift/TFieldRequirementType.as b/lib/rs/test_recursive/src/transit/services/CityServices.thrift
similarity index 74%
rename from lib/as3/src/org/apache/thrift/TFieldRequirementType.as
rename to lib/rs/test_recursive/src/transit/services/CityServices.thrift
index 6fb4e58..2ca559a 100644
--- a/lib/as3/src/org/apache/thrift/TFieldRequirementType.as
+++ b/lib/rs/test_recursive/src/transit/services/CityServices.thrift
@@ -15,18 +15,15 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations
  * under the License.
+ *
+ * Contains some contributions under the Thrift Software License.
+ * Please see doc/old-thrift-license.txt in the Thrift distribution for
+ * details.
  */
 
-package org.apache.thrift {
+namespace rs transit.services
 
-  /**
-   * Requirement type constants.
-   *
-   */
-  public class TFieldRequirementType {
-    public static const REQUIRED:int  = 1;
-    public static const OPTIONAL:int = 2;
-    public static const DEFAULT:int = 3;
-  }
-  
+enum TransitImprovements {
+  TransitSignalPriority = 1
+  DedicatedRightOfWay = 2
 }
diff --git a/build/cmake/FindCabal.cmake b/lib/rs/test_recursive/src/transit/services/Makefile.am
similarity index 69%
rename from build/cmake/FindCabal.cmake
rename to lib/rs/test_recursive/src/transit/services/Makefile.am
index fed337b..f70e919 100644
--- a/build/cmake/FindCabal.cmake
+++ b/lib/rs/test_recursive/src/transit/services/Makefile.am
@@ -17,14 +17,17 @@
 # under the License.
 #
 
+SUBDIRS = .
 
-#  Cabal_FOUND - system has Cabal
-#  Cabal - the Cabal executable
-#
-# It will search the environment variable CABAL_HOME if it is set
+THRIFT = $(top_builddir)/compiler/cpp/thrift
 
-include(FindPackageHandleStandardArgs)
+stubs: CityServices.thrift $(THRIFT)
+	$(THRIFT) -I . -out . --gen rs CityServices.thrift
 
-find_program(CABAL NAMES cabal PATHS $ENV{HOME}/.cabal/bin $ENV{CABAL_HOME}/bin)
-find_package_handle_standard_args(CABAL DEFAULT_MSG CABAL)
-mark_as_advanced(CABAL)
+check: stubs
+
+clean-local:
+	-$(RM) city_services.rs
+
+EXTRA_DIST = \
+	CityServices.thrift
diff --git a/lib/dart/tool/dev.dart b/lib/rs/test_recursive/src/transit/services/mod.rs
similarity index 62%
rename from lib/dart/tool/dev.dart
rename to lib/rs/test_recursive/src/transit/services/mod.rs
index 27f8b8f..2cb171a 100644
--- a/lib/dart/tool/dev.dart
+++ b/lib/rs/test_recursive/src/transit/services/mod.rs
@@ -6,7 +6,7 @@
 // "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
+//   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
@@ -15,19 +15,4 @@
 // specific language governing permissions and limitations
 // under the License.
 
-library tool.dev;
-
-import 'package:dart_dev/dart_dev.dart' show dev, config;
-
-main(List<String> args) async {
-  // https://github.com/Workiva/dart_dev
-
-  var directories = ['lib/', 'test/', 'tool/'];
-  config.analyze.entryPoints = directories;
-  config.format.directories = directories;
-  config.copyLicense
-    ..licensePath = 'LICENSE_HEADER'
-    ..directories = directories;
-
-  await dev(args);
-}
+pub mod city_services;
diff --git a/lib/st/package.xml b/lib/st/package.xml
index 45e9dfb..5d1c627 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.14.2 -->
+<!-- Apache Thrift Smalltalk library version 0.15.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 e2a494c..49cdab0 100644
--- a/lib/swift/Sources/Thrift.swift
+++ b/lib/swift/Sources/Thrift.swift
@@ -1,3 +1,3 @@
 class Thrift {
-	let version = "0.14.2"
+	let version = "0.15.0"
 }
diff --git a/lib/swift/Tests/ThriftTests/ThriftTests.swift b/lib/swift/Tests/ThriftTests/ThriftTests.swift
index e166425..1a0bb1d 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.14.2")
+    XCTAssertEqual(Thrift().version, "0.15.0")
   }
 
   static var allTests : [(String, (ThriftTests) -> () throws -> Void)] {
diff --git a/lib/ts/package-lock.json b/lib/ts/package-lock.json
index 34b0931..f617553 100644
--- a/lib/ts/package-lock.json
+++ b/lib/ts/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.14.2",
+  "version": "0.15.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/lib/ts/package.json b/lib/ts/package.json
index 8c1313e..e79a075 100644
--- a/lib/ts/package.json
+++ b/lib/ts/package.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.14.2",
+  "version": "0.15.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 9da40f2..e0bcf04 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "thrift",
-  "version": "0.14.2",
+  "version": "0.15.0",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
diff --git a/package.json b/package.json
index 291835c..4c085fe 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,7 @@
     "type": "git",
     "url": "https://github.com/apache/thrift.git"
   },
-  "version": "0.14.2",
+  "version": "0.15.0",
   "author": {
     "name": "Apache Thrift Developers",
     "email": "dev@thrift.apache.org",
diff --git a/rust-toolchain b/rust-toolchain
new file mode 100644
index 0000000..32b7211
--- /dev/null
+++ b/rust-toolchain
@@ -0,0 +1 @@
+1.40.0
diff --git a/sonar-project.properties b/sonar-project.properties
index cae5d99..f9c9e05 100755
--- 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.14.2
+sonar.projectVersion=0.15.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
@@ -37,7 +37,7 @@
 sonar.cxx.cppcheck.reportPath=cppcheck-result.xml
 
 # List of the module identifiers
-sonar.modules=module1,module3,module4,module5,module6,module7,module8,module9,module10,module11,module12,module14
+sonar.modules=module1,module3,module4,module5,module6,module7,module8,module9,module10,module11,module12
 
 
 
@@ -48,13 +48,13 @@
 #sonar.modules=module13
 
 # phpunit plugin is broken
-#sonar.modules=module15
+#sonar.modules=module14
 
 module1.sonar.projectName=Apache Thrift - Java Library
 module1.sonar.projectBaseDir=lib/java
 module1.sonar.sources=src
 module1.sonar.tests=test
-module1.sonar.binaries=build/libs/libthrift-0.14.2.jar
+module1.sonar.binaries=build/libs/libthrift-0.15.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.14.2.jar
+module2.sonar.libraries=lib/java/build/deps/*.jar,lib/java/build/libs/libthrift-0.15.0.jar
 module2.sonar.language=java
 
 module3.sonar.projectName=Apache Thrift - JavaScript Library
@@ -126,15 +126,10 @@
 module13.sonar.tests=test
 module13.sonar.language=delph
 
-module14.sonar.projectName=Apache Thrift - Flex (as3) Library
-module14.sonar.projectBaseDir=lib/as3
+module14.sonar.projectName=Apache Thrift - PHP Library
+module14.sonar.projectBaseDir=lib/php
 module14.sonar.sources=src
-module14.sonar.language=flex
-
-module15.sonar.projectName=Apache Thrift - PHP Library
-module15.sonar.projectBaseDir=lib/php
-module15.sonar.sources=src
-module15.sonar.language=php
+module14.sonar.language=php
 
 # TODO add some more languages here
 
diff --git a/test/Makefile.am b/test/Makefile.am
index 4ef12e0..15e2f1b 100755
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -64,10 +64,6 @@
 PRECROSS_TARGET += precross-rb
 endif
 
-if WITH_HASKELL
-SUBDIRS += hs
-endif
-
 if WITH_HAXE
 SUBDIRS += haxe
 endif
@@ -127,7 +123,6 @@
 	crossrunner \
 	dart \
 	erl \
-	hs \
 	keys \
 	lua \
 	ocaml \
diff --git a/test/c_glib/CMakeLists.txt b/test/c_glib/CMakeLists.txt
index 7a7daad..2e2d687 100644
--- a/test/c_glib/CMakeLists.txt
+++ b/test/c_glib/CMakeLists.txt
@@ -41,8 +41,12 @@
 add_library(crosstestgencglib STATIC ${crosstestgencglib_SOURCES})
 LINK_AGAINST_THRIFT_LIBRARY(crosstestgencglib thrift_c_glib)
 
+if (WITH_ZLIB)
+  LINK_AGAINST_THRIFT_LIBRARY(crosstestgencglib thrift_c_glib_zlib) 
+endif ()
+
 add_executable(test_server src/test_server.c src/thrift_test_handler.c src/thrift_second_service_handler.c)
-target_link_libraries(test_server crosstestgencglib)
+target_link_libraries(test_server crosstestgencglib ${ZLIB_LIBRARIES})
 
 add_executable(test_client src/test_client.c)
 target_link_libraries(test_client crosstestgencglib "${OPENSSL_LIBRARIES}")
diff --git a/test/c_glib/src/test_server.c b/test/c_glib/src/test_server.c
index c949530..c57e1cf 100644
--- a/test/c_glib/src/test_server.c
+++ b/test/c_glib/src/test_server.c
@@ -32,6 +32,8 @@
 #include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>
 #include <thrift/c_glib/transport/thrift_framed_transport.h>
 #include <thrift/c_glib/transport/thrift_framed_transport_factory.h>
+#include <thrift/c_glib/transport/thrift_zlib_transport.h>
+#include <thrift/c_glib/transport/thrift_zlib_transport_factory.h>
 #include <thrift/c_glib/transport/thrift_server_socket.h>
 #include <thrift/c_glib/transport/thrift_server_transport.h>
 #include <thrift/c_glib/transport/thrift_transport.h>
@@ -85,7 +87,7 @@
     { "server-type",     0, 0, G_OPTION_ARG_STRING,   &server_type_option,
       "Type of server: simple (=simple)", NULL },
     { "transport",       0, 0, G_OPTION_ARG_STRING,   &transport_option,
-      "Transport: buffered, framed (=buffered)", NULL },
+      "Transport: buffered, framed, zlib (=buffered)", NULL },
     { "protocol",        0, 0, G_OPTION_ARG_STRING,   &protocol_option,
       "Protocol: binary, compact (=binary)", NULL },
     { "string-limit",    0, 0, G_OPTION_ARG_INT,      &string_limit,
@@ -167,6 +169,10 @@
       transport_factory_type = THRIFT_TYPE_FRAMED_TRANSPORT_FACTORY;
       transport_name = "framed";
     }
+    else if (strncmp (transport_option, "zlib", 5) == 0) {
+      transport_factory_type = THRIFT_TYPE_ZLIB_TRANSPORT_FACTORY;
+      transport_name = "zlib";
+    }
     else if (strncmp (transport_option, "buffered", 9) != 0) {
       fprintf (stderr, "Unknown transport type %s\n", transport_option);
       options_valid = FALSE;
diff --git a/test/cpp/CMakeLists.txt b/test/cpp/CMakeLists.txt
index 9ecc171..969019d 100755
--- a/test/cpp/CMakeLists.txt
+++ b/test/cpp/CMakeLists.txt
@@ -64,20 +64,17 @@
 LINK_AGAINST_THRIFT_LIBRARY(crossspecificnamegencpp thrift)
 
 add_executable(TestServer src/TestServer.cpp)
-target_link_libraries(TestServer crosstestgencpp ${Boost_LIBRARIES} ${LIBEVENT_LIB})
-LINK_AGAINST_THRIFT_LIBRARY(TestServer thrift)
+target_link_libraries(TestServer crosstestgencpp ${Boost_LIBRARIES})
 LINK_AGAINST_THRIFT_LIBRARY(TestServer thriftnb)
 LINK_AGAINST_THRIFT_LIBRARY(TestServer thriftz)
 
 add_executable(TestClient src/TestClient.cpp)
-target_link_libraries(TestClient crosstestgencpp ${Boost_LIBRARIES} ${LIBEVENT_LIB})
-LINK_AGAINST_THRIFT_LIBRARY(TestClient thrift)
+target_link_libraries(TestClient crosstestgencpp ${Boost_LIBRARIES})
 LINK_AGAINST_THRIFT_LIBRARY(TestClient thriftnb)
 LINK_AGAINST_THRIFT_LIBRARY(TestClient thriftz)
 
 add_executable(StressTest src/StressTest.cpp)
-target_link_libraries(StressTest crossstressgencpp ${Boost_LIBRARIES} ${LIBEVENT_LIB})
-LINK_AGAINST_THRIFT_LIBRARY(StressTest thrift)
+target_link_libraries(StressTest crossstressgencpp ${Boost_LIBRARIES})
 LINK_AGAINST_THRIFT_LIBRARY(StressTest thriftnb)
 add_test(NAME StressTest COMMAND StressTest)
 add_test(NAME StressTestConcurrent COMMAND StressTest --client-type=concurrent)
@@ -86,8 +83,7 @@
 # is broken on Windows. Contributions welcome.
 if (NOT WIN32 AND NOT CYGWIN)
     add_executable(StressTestNonBlocking src/StressTestNonBlocking.cpp)
-    target_link_libraries(StressTestNonBlocking crossstressgencpp ${Boost_LIBRARIES} ${LIBEVENT_LIB})
-    LINK_AGAINST_THRIFT_LIBRARY(StressTestNonBlocking thrift)
+    target_link_libraries(StressTestNonBlocking crossstressgencpp ${Boost_LIBRARIES})
     LINK_AGAINST_THRIFT_LIBRARY(StressTestNonBlocking thriftnb)
     LINK_AGAINST_THRIFT_LIBRARY(StressTestNonBlocking thriftz)
     add_test(NAME StressTestNonBlocking COMMAND StressTestNonBlocking)
diff --git a/test/dart/test_client/.analysis_options b/test/dart/test_client/.analysis_options
deleted file mode 100644
index a10d4c5..0000000
--- a/test/dart/test_client/.analysis_options
+++ /dev/null
@@ -1,2 +0,0 @@
-analyzer:
-  strong-mode: true
diff --git a/test/dart/test_client/pubspec.yaml b/test/dart/test_client/pubspec.yaml
index f447b50..7d7e3b6 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.14.2
+version: 0.15.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/Makefile.am b/test/erl/Makefile.am
index 81913ee..145a763 100644
--- a/test/erl/Makefile.am
+++ b/test/erl/Makefile.am
@@ -19,11 +19,7 @@
 
 THRIFT_FILES = $(wildcard ../*.thrift)
 
-if ERLANG_OTP16
-ERL_FLAG = erl:otp16
-else
 ERL_FLAG = erl
-endif
 # make sure ThriftTest.thrift is generated last to prevent conflicts with other *.thrift files
 .generated: $(THRIFT_FILES)
 	for f in $(THRIFT_FILES) ; do \
diff --git a/test/erl/src/thrift_test.app.src b/test/erl/src/thrift_test.app.src
index 27f44c1..920211e 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.14.2"},
+  {vsn, "0.15.0"},
 
   % All modules used by the application.
   {modules, [
diff --git a/test/go/Makefile.am b/test/go/Makefile.am
index eae153c..d7db957 100644
--- a/test/go/Makefile.am
+++ b/test/go/Makefile.am
@@ -19,7 +19,7 @@
 
 BUILT_SOURCES = gopath
 
-THRIFTCMD = $(THRIFT) -out src/gen --gen go:thrift_import=thrift$(COMPILER_EXTRAFLAG)
+THRIFTCMD = $(THRIFT) -out src/gen --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/test/go/src/gen/$(COMPILER_EXTRAFLAG)
 THRIFTTEST = $(top_srcdir)/test/ThriftTest.thrift
 
 precross: bin/testclient bin/testserver
@@ -34,20 +34,16 @@
 	mkdir -p src/gen
 	$(THRIFTCMD) ThriftTest.thrift
 	$(THRIFTCMD) ../StressTest.thrift
-	GOPATH=`pwd` $(GO) get github.com/golang/mock/gomock || true
-	sed -i 's/\"context\"/\"golang.org\/x\/net\/context\"/g' src/github.com/golang/mock/gomock/controller.go || true
-	GOPATH=`pwd` $(GO) get github.com/golang/mock/gomock
-	ln -nfs ../../../lib/go/thrift src/thrift
 	touch gopath
 
 bin/testclient: gopath
-	GOPATH=`pwd` $(GO) install bin/testclient
+	GOPATH=`pwd` $(GO) install -mod=mod ./src/bin/testclient
 
 bin/testserver: gopath
-	GOPATH=`pwd` $(GO) install bin/testserver
+	GOPATH=`pwd` $(GO) install -mod=mod ./src/bin/testserver
 
 bin/stress: gopath
-	GOPATH=`pwd` $(GO) install bin/stress
+	GOPATH=`pwd` $(GO) install -mod=mod ./src/bin/stress
 
 clean-local:
 	$(RM) -r src/gen src/github.com/golang src/thrift bin pkg gopath ThriftTest.thrift
@@ -55,7 +51,7 @@
 check_PROGRAMS: bin/testclient bin/testserver bin/stress
 
 check: gopath genmock
-	GOPATH=`pwd` $(GO) test -v common/...
+	$(GO) test -mod=mod -v ./src/common/...
 
 genmock: gopath
 	sh genmock.sh
diff --git a/test/go/genmock.sh b/test/go/genmock.sh
index 3ba41b9..bccfdf3 100644
--- a/test/go/genmock.sh
+++ b/test/go/genmock.sh
@@ -1,15 +1,12 @@
 #!/bin/sh
+
 set -e
 
-export GOPATH=`pwd`
-export GOBIN=`pwd`/bin
-export GO111MODULE=off
+export GOPATH=$(mktemp -d -t gopath-XXXXXXXXXX)
 
-mkdir -p src/github.com/golang/mock
-cd src/github.com/golang
-curl -fsSL https://github.com/golang/mock/archive/v1.2.0.tar.gz -o mock.tar.gz
-tar -xzvf mock.tar.gz -C mock --strip-components=1
-cd mock/mockgen
-go install .
-cd ../../../../../
-bin/mockgen -destination=src/common/mock_handler.go -package=common gen/thrifttest ThriftTest
+# TODO: Once we dropped support to go 1.15, add "@v1.5.0" suffix to go install
+GO111MODULE=on go install -mod=mod github.com/golang/mock/mockgen
+
+`go env GOPATH`/bin/mockgen -build_flags "-mod=mod" -destination=src/common/mock_handler.go -package=common github.com/apache/thrift/test/go/src/gen/thrifttest ThriftTest
+
+rm -Rf $GOPATH
diff --git a/test/go/src/bin/stress/main.go b/test/go/src/bin/stress/main.go
index f2e0f20..3ff0a39 100644
--- a/test/go/src/bin/stress/main.go
+++ b/test/go/src/bin/stress/main.go
@@ -23,7 +23,6 @@
 	"context"
 	"flag"
 	"fmt"
-	"gen/stress"
 	"log"
 	_ "net/http/pprof"
 	"os"
@@ -31,8 +30,10 @@
 	"runtime/pprof"
 	"sync"
 	"sync/atomic"
-	"thrift"
 	"time"
+
+	"github.com/apache/thrift/lib/go/thrift"
+	"github.com/apache/thrift/test/go/src/gen/stress"
 )
 
 var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to this file")
diff --git a/test/go/src/bin/testclient/main.go b/test/go/src/bin/testclient/main.go
index 4357ee8..39ee95b 100644
--- a/test/go/src/bin/testclient/main.go
+++ b/test/go/src/bin/testclient/main.go
@@ -20,13 +20,14 @@
 package main
 
 import (
-	"common"
 	"context"
 	"flag"
-	"gen/thrifttest"
 	t "log"
 	"reflect"
-	"thrift"
+
+	"github.com/apache/thrift/lib/go/thrift"
+	"github.com/apache/thrift/test/go/src/common"
+	"github.com/apache/thrift/test/go/src/gen/thrifttest"
 )
 
 var host = flag.String("host", "localhost", "Host to connect")
@@ -50,8 +51,8 @@
 }
 
 var rmapmap = map[int32]map[int32]int32{
-	-4: map[int32]int32{-4: -4, -3: -3, -2: -2, -1: -1},
-	4:  map[int32]int32{4: 4, 3: 3, 2: 2, 1: 1},
+	-4: {-4: -4, -3: -3, -2: -2, -1: -1},
+	4:  {4: 4, 3: 3, 2: 2, 1: 1},
 }
 
 var xxs = &thrifttest.Xtruct{
diff --git a/test/go/src/bin/testserver/main.go b/test/go/src/bin/testserver/main.go
index 6fc1185..d4bd8b4 100644
--- a/test/go/src/bin/testserver/main.go
+++ b/test/go/src/bin/testserver/main.go
@@ -20,12 +20,13 @@
 package main
 
 import (
-	"common"
 	"flag"
 	"fmt"
 	"log"
 	"net/http"
-	"thrift"
+
+	"github.com/apache/thrift/lib/go/thrift"
+	"github.com/apache/thrift/test/go/src/common"
 )
 
 var host = flag.String("host", "localhost", "Host to connect")
diff --git a/test/go/src/common/client.go b/test/go/src/common/client.go
index ed820ae..15973d8 100644
--- a/test/go/src/common/client.go
+++ b/test/go/src/common/client.go
@@ -24,9 +24,10 @@
 	"crypto/tls"
 	"flag"
 	"fmt"
-	"gen/thrifttest"
 	"net/http"
-	"thrift"
+
+	"github.com/apache/thrift/lib/go/thrift"
+	"github.com/apache/thrift/test/go/src/gen/thrifttest"
 )
 
 var debugClientProtocol bool
diff --git a/test/go/src/common/clientserver_test.go b/test/go/src/common/clientserver_test.go
index 9f93c4c..d5e3c43 100644
--- a/test/go/src/common/clientserver_test.go
+++ b/test/go/src/common/clientserver_test.go
@@ -22,13 +22,14 @@
 import (
 	"context"
 	"errors"
-	"gen/thrifttest"
 	"reflect"
 	"sync"
 	"testing"
-	"thrift"
 
 	"github.com/golang/mock/gomock"
+
+	"github.com/apache/thrift/lib/go/thrift"
+	"github.com/apache/thrift/test/go/src/gen/thrifttest"
 )
 
 type test_unit struct {
@@ -84,8 +85,8 @@
 }
 
 var rmapmap = map[int32]map[int32]int32{
-	-4: map[int32]int32{-4: -4, -3: -3, -2: -2, -1: -1},
-	4:  map[int32]int32{4: 4, 3: 3, 2: 2, 1: 1},
+	-4: {-4: -4, -3: -3, -2: -2, -1: -1},
+	4:  {4: 4, 3: 3, 2: 2, 1: 1},
 }
 
 var xxs = &thrifttest.Xtruct{
diff --git a/test/go/src/common/context_test.go b/test/go/src/common/context_test.go
index e64dbb9..3e21a54 100644
--- a/test/go/src/common/context_test.go
+++ b/test/go/src/common/context_test.go
@@ -28,8 +28,9 @@
 	"os"
 	"syscall"
 	"testing"
-	"thrift"
 	"time"
+
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 type slowHttpHandler struct{}
diff --git a/test/go/src/common/printing_handler.go b/test/go/src/common/printing_handler.go
index 2b22d0c..d91dde4 100644
--- a/test/go/src/common/printing_handler.go
+++ b/test/go/src/common/printing_handler.go
@@ -24,8 +24,9 @@
 	"encoding/hex"
 	"errors"
 	"fmt"
-	. "gen/thrifttest"
 	"time"
+
+	. "github.com/apache/thrift/test/go/src/gen/thrifttest"
 )
 
 var PrintingHandler = &printingHandler{}
@@ -192,7 +193,7 @@
 func (p *printingHandler) TestSet(ctx context.Context, thing []int32) (r []int32, err error) {
 	fmt.Printf("testSet({")
 	first := true
-	for k, _ := range thing {
+	for k := range thing {
 		if first {
 			first = false
 		} else {
@@ -256,8 +257,8 @@
 	fmt.Printf("testMapMap(%d)\n", hello)
 
 	r = map[int32]map[int32]int32{
-		-4: map[int32]int32{-4: -4, -3: -3, -2: -2, -1: -1},
-		4:  map[int32]int32{4: 4, 3: 3, 2: 2, 1: 1},
+		-4: {-4: -4, -3: -3, -2: -2, -1: -1},
+		4:  {4: 4, 3: 3, 2: 2, 1: 1},
 	}
 	return
 }
diff --git a/test/go/src/common/server.go b/test/go/src/common/server.go
index c6674ae..6e3a5d3 100644
--- a/test/go/src/common/server.go
+++ b/test/go/src/common/server.go
@@ -24,8 +24,9 @@
 	"crypto/tls"
 	"flag"
 	"fmt"
-	"gen/thrifttest"
-	"thrift"
+
+	"github.com/apache/thrift/lib/go/thrift"
+	"github.com/apache/thrift/test/go/src/gen/thrifttest"
 )
 
 var (
diff --git a/test/go/src/common/simple_handler.go b/test/go/src/common/simple_handler.go
index 0c9463d..971f17e 100644
--- a/test/go/src/common/simple_handler.go
+++ b/test/go/src/common/simple_handler.go
@@ -21,8 +21,9 @@
 
 import (
 	"errors"
-	. "gen/thrifttest"
 	"time"
+
+	. "github.com/apache/thrift/test/go/src/gen/thrifttest"
 )
 
 var SimpleHandler = &simpleHandler{}
@@ -96,8 +97,8 @@
 func (p *simpleHandler) TestMapMap(hello int32) (r map[int32]map[int32]int32, err error) {
 
 	r = map[int32]map[int32]int32{
-		-4: map[int32]int32{-4: -4, -3: -3, -2: -2, -1: -1},
-		4:  map[int32]int32{4: 4, 3: 3, 2: 2, 1: 1},
+		-4: {-4: -4, -3: -3, -2: -2, -1: -1},
+		4:  {4: 4, 3: 3, 2: 2, 1: 1},
 	}
 	return
 }
diff --git a/test/haxe/Makefile.am b/test/haxe/Makefile.am
index 6c0483e..d37aaa7 100644
--- a/test/haxe/Makefile.am
+++ b/test/haxe/Makefile.am
@@ -34,6 +34,13 @@
 		../../lib/haxe/src/org/apache/thrift/**/*.hx \
 		gen-haxe/thrift/test/ThriftTest.hx
 	$(HAXE) --cwd .  cpp.hxml
+	
+#	$(HAXE) --cwd .  csharp
+#	$(HAXE) --cwd .  flash
+#	$(HAXE) --cwd .  java
+#	$(HAXE) --cwd .  javascript
+#	$(HAXE) --cwd .  neko
+#	$(HAXE) --cwd .  python
 
 $(BIN_PHP): \
 		src/*.hx \
@@ -49,15 +56,6 @@
 
 
 
-#TODO: other haxe targets
-#    $(HAXE)  --cwd .  csharp
-#    $(HAXE)  --cwd .  flash
-#    $(HAXE)  --cwd .  java
-#    $(HAXE)  --cwd .  javascript
-#    $(HAXE)  --cwd .  neko
-#    $(HAXE)  --cwd .  python  # needs Haxe 3.2.0
-
-
 clean-local:
 	$(RM) -r gen-haxe bin
 
diff --git a/test/haxe/TestClientServer.hxproj b/test/haxe/TestClientServer.hxproj
index 6696d80..44faa37 100644
--- a/test/haxe/TestClientServer.hxproj
+++ b/test/haxe/TestClientServer.hxproj
@@ -4,7 +4,7 @@
   <output>
     <movie outputType="Application" />
     <movie input="" />
-    <movie path="bin/TestClientServer" />
+    <movie path="bin\TestClientServer" />
     <movie fps="30" />
     <movie width="800" />
     <movie height="600" />
@@ -17,7 +17,7 @@
   <classpaths>
     <class path="src" />
     <class path="gen-haxe" />
-    <class path="../../lib/haxe/src" />
+    <class path="..\..\lib\haxe\src" />
   </classpaths>
   <!-- Build options -->
   <build>
diff --git a/test/haxe/make_all.bat b/test/haxe/make_all.bat
index eaeba89..966bfa5 100644
--- a/test/haxe/make_all.bat
+++ b/test/haxe/make_all.bat
@@ -30,16 +30,19 @@
 if errorlevel 1 goto STOP
 
 rem # invoke Haxe compiler for all targets
+rd .buildtemp /S /Q
 for %%a in (*.hxml) do (
-	rem * filter Python, as it is not supported by Haxe 3.1.3 (but will be in 3.1.4)
-	if not "%%a"=="python.hxml" (
-		echo --------------------------
-		echo Building %%a ...
-		echo --------------------------
-		haxe  --cwd .  %%a
-	)
+	echo --------------------------
+	echo Building %%a ...
+	echo --------------------------
+	haxe  --cwd .  %%a
+	if not exist ".buildtemp" mkdir ".buildtemp"
+	move bin ".buildtemp\%%a"
+	if errorlevel 1 pause
 )
 
+rd bin /S /Q
+rename .buildtemp bin
 
 echo.
 echo done.
diff --git a/test/haxe/php-web-server.hxml b/test/haxe/php-web-server.hxml
index 395a852..f628c3a 100644
--- a/test/haxe/php-web-server.hxml
+++ b/test/haxe/php-web-server.hxml
@@ -26,8 +26,8 @@
 -main Main
 
 #PHP target
--php bin/php-web-server/
---php-front Main-debug.php
+-php bin/php-web-server
+-D php-front=Main-debug.php
 
 #defines
 -D phpwebserver
diff --git a/test/haxe/php.hxml b/test/haxe/php.hxml
index 9651898..c3aa97f 100644
--- a/test/haxe/php.hxml
+++ b/test/haxe/php.hxml
@@ -26,8 +26,8 @@
 -main Main
 
 #PHP target
--php bin/php/
---php-front Main-debug.php
+-php bin/php
+-D php-front=Main-debug.php
 
 
 #Add debug information
diff --git a/test/haxe/src/Arguments.hx b/test/haxe/src/Arguments.hx
index 56e5253..023f250 100644
--- a/test/haxe/src/Arguments.hx
+++ b/test/haxe/src/Arguments.hx
@@ -92,7 +92,7 @@
     #if sys
 
     private static function GetHelp() : String {
-        var sProg = Path.withoutDirectory( Sys.executablePath());
+        var sProg = Path.withoutDirectory( Sys.programPath());
         return "\n"
             +sProg+"  [client|server]  [options]\n"
             +"\n"
diff --git a/test/haxe/src/TestClient.hx b/test/haxe/src/TestClient.hx
index 853319e..579dc00 100644
--- a/test/haxe/src/TestClient.hx
+++ b/test/haxe/src/TestClient.hx
@@ -35,7 +35,7 @@
 import org.apache.thrift.meta_data.*;
 
 #if cpp
-import cpp.vm.Thread;
+import sys.thread.Thread;
 #else
 // no thread support (yet)
 #end
diff --git a/test/haxe/src/TestServer.hx b/test/haxe/src/TestServer.hx
index 450c8f2..d44c68c 100644
--- a/test/haxe/src/TestServer.hx
+++ b/test/haxe/src/TestServer.hx
@@ -39,20 +39,24 @@
             switch( args.transport) {
             case socket:
                 trace("- socket port "+args.port);
+				#if (flash || html5 || js)
+				throw "Transport not supported on this platform";
+                #else
                 transport = new TServerSocket( args.port);
+				#end
             case http:
                 trace("- http");
-                #if !phpwebserver
-                  throw "HTTP server not implemented yet";
-                 //transport = new THttpServer( targetHost);
+                #if phpwebserver
+                transport = new TWrappingServerTransport( 
+					new TStreamTransport(
+						new TFileStream("php://input", Read),
+						new TFileStream("php://output", Append),
+						null
+					)
+				);
                 #else
-                transport =    new TWrappingServerTransport(
-                        new TStreamTransport(
-                          new TFileStream("php://input", Read),
-                          new TFileStream("php://output", Append)
-                          )
-                        );
-
+				throw "Transport not supported on this platform";
+                //transport = new THttpServer( targetHost);
                 #end
             default:
                 throw "Unhandled transport";
@@ -86,7 +90,7 @@
 
 
             // Processor
-            var handler = new TestServerHandler();
+            var handler : ThriftTest_service = new TestServerHandler();
             var processor = new ThriftTestProcessor(handler);
 
             // Simple Server
diff --git a/test/haxe/src/TestServerHandler.hx b/test/haxe/src/TestServerHandler.hx
index b8a2590..0e19105 100644
--- a/test/haxe/src/TestServerHandler.hx
+++ b/test/haxe/src/TestServerHandler.hx
@@ -36,7 +36,7 @@
 import thrift.test.*;  // generated code
 
 
-class TestServerHandler implements ThriftTest {
+class TestServerHandler implements ThriftTest_service {
 
     public var server:TServer;
 
@@ -465,8 +465,10 @@
     */
     public function testOneway(secondsToSleep:haxe.Int32):Void
     {
+		#if sys
         trace("testOneway(" + secondsToSleep + "), sleeping...");
         Sys.sleep(secondsToSleep);
+		#end
         trace("testOneway finished");
     }
 
diff --git a/test/hs/CMakeLists.txt b/test/hs/CMakeLists.txt
deleted file mode 100644
index eaca3fa..0000000
--- a/test/hs/CMakeLists.txt
+++ /dev/null
@@ -1,114 +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.
-#
-
-set(hs_test_gen
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ConstantsDemo_Consts.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ConstantsDemo_Types.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/DebugProtoTest_Consts.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/DebugProtoTest_Types.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/EmptyService_Client.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/EmptyService.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/EmptyService_Iface.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Include_Consts.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Include_Types.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Inherited_Client.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Inherited.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Inherited_Iface.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ReverseOrderService_Client.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ReverseOrderService.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ReverseOrderService_Iface.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/SecondService_Client.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/SecondService.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/SecondService_Iface.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ServiceForExceptionWithAMap_Client.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ServiceForExceptionWithAMap.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ServiceForExceptionWithAMap_Iface.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Srv_Client.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Srv.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Srv_Iface.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ThriftTest_Client.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ThriftTest_Consts.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ThriftTest.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ThriftTest_Iface.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/ThriftTest_Types.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Yowza_Client.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Yowza.hs
-    ${CMAKE_CURRENT_BINARY_DIR}/gen-hs/Yowza_Iface.hs
-)
-
-set(hs_crosstest_apps
-    ${CMAKE_CURRENT_BINARY_DIR}/TestServer
-    ${CMAKE_CURRENT_BINARY_DIR}/TestClient
-)
-set(hs_crosstest_args
-    -igen-hs
-    -odir=${CMAKE_CURRENT_BINARY_DIR}
-    -hidir=${CMAKE_CURRENT_BINARY_DIR}
-)
-
-if (CMAKE_BUILD_TYPE STREQUAL "Debug")
-  set(hs_optimize -O0)
-else()
-  set(hs_optimize -O1)
-endif()
-
-add_custom_command(
-    OUTPUT ${hs_crosstest_apps}
-    COMMAND ${GHC} ${hs_optimize} ${hs_crosstest_args} ${CMAKE_CURRENT_SOURCE_DIR}/TestServer.hs -o TestServer
-    COMMAND ${GHC} ${hs_optimize} ${hs_crosstest_args} ${CMAKE_CURRENT_SOURCE_DIR}/TestClient.hs -o TestClient
-    DEPENDS ${hs_test_gen} haskell_library TestServer.hs TestClient.hs
-)
-add_custom_target(haskell_crosstest ALL
-    COMMENT "Building Haskell cross test executables"
-    DEPENDS ${hs_crosstest_apps}
-)
-
-set(hs_test_sources
-    ConstantsDemo_Main.hs
-    DebugProtoTest_Main.hs
-    Include_Main.hs
-    ThriftTest_Main.hs
-)
-set(hs_test_args
-    -Wall
-    -XScopedTypeVariables
-    -i${PROJECT_SOURCE_DIR}/lib/hs/src
-    -i${CMAKE_CURRENT_BINARY_DIR}/gen-hs
-)
-add_custom_target(haskell_tests ALL DEPENDS ${hs_test_gen})
-foreach(SRC ${hs_test_sources})
-    get_filename_component(BASE ${SRC} NAME_WE)
-    add_test(NAME HaskellTests-${BASE}
-        COMMAND ${RUN_HASKELL} ${hs_test_args} ${SRC}
-        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
-endforeach()
-
-set(hs_test_gen_sources
-    ${PROJECT_SOURCE_DIR}/test/ConstantsDemo.thrift
-    ${PROJECT_SOURCE_DIR}/test/DebugProtoTest.thrift
-    ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
-    ${PROJECT_SOURCE_DIR}/test/Include.thrift
-)
-add_custom_command(OUTPUT ${hs_test_gen}
-    COMMAND ${THRIFT_COMPILER} --gen hs ${PROJECT_SOURCE_DIR}/test/ConstantsDemo.thrift
-    COMMAND ${THRIFT_COMPILER} --gen hs ${PROJECT_SOURCE_DIR}/test/DebugProtoTest.thrift
-    COMMAND ${THRIFT_COMPILER} --gen hs ${PROJECT_SOURCE_DIR}/test/ThriftTest.thrift
-    COMMAND ${THRIFT_COMPILER} --gen hs ${PROJECT_SOURCE_DIR}/test/Include.thrift
-    DEPENDS ${hs_test_gen_sources}
-)
diff --git a/test/hs/ConstantsDemo_Main.hs b/test/hs/ConstantsDemo_Main.hs
deleted file mode 100644
index 28de4f7..0000000
--- a/test/hs/ConstantsDemo_Main.hs
+++ /dev/null
@@ -1,68 +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.
---
-
-module Main where
-
-
-import qualified Control.Exception
-import qualified Network
-
-import Thrift.Protocol.Binary
-import Thrift.Server
-import Thrift.Transport.Handle
-
-import qualified ThriftTestUtils
-
-import qualified Yowza
-import qualified Yowza_Client as Client
-import qualified Yowza_Iface as Iface
-
-
-data YowzaHandler = YowzaHandler
-instance Iface.Yowza_Iface YowzaHandler where
-    blingity _ = do
-        ThriftTestUtils.serverLog "SERVER: Got blingity"
-        return ()
-
-    blangity _ = do
-        ThriftTestUtils.serverLog "SERVER: Got blangity"
-        return $ 31
-
-
-client :: (String, Network.PortID) -> IO ()
-client addr = do
-    to <- hOpen addr
-    let ps = (BinaryProtocol to, BinaryProtocol to)
-
-    Client.blingity ps
-
-    rv <- Client.blangity ps
-    ThriftTestUtils.clientLog $ show rv
-
-    tClose to
-
-server :: Network.PortNumber -> IO ()
-server port = do 
-    ThriftTestUtils.serverLog "Ready..."
-    (runBasicServer YowzaHandler Yowza.process port)
-    `Control.Exception.catch`
-    (\(TransportExn s _) -> error $ "FAILURE: " ++ show s)
-
-main :: IO ()
-main = ThriftTestUtils.runTest server client
diff --git a/test/hs/DebugProtoTest_Main.hs b/test/hs/DebugProtoTest_Main.hs
deleted file mode 100644
index 97d4347..0000000
--- a/test/hs/DebugProtoTest_Main.hs
+++ /dev/null
@@ -1,172 +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.
---
-
-{-# LANGUAGE OverloadedStrings #-}
-
-module Main where
-
-
-import qualified Control.Exception
-import qualified Data.ByteString.Lazy as DBL
-import qualified Data.HashMap.Strict as Map
-import qualified Data.HashSet as Set
-import qualified Data.Vector as Vector
-import qualified Network
-
-import Thrift.Protocol.Binary
-import Thrift.Server
-import Thrift.Transport.Handle
-
-import qualified ThriftTestUtils
-
-import qualified DebugProtoTest_Types as Types
-import qualified Inherited
-import qualified Inherited_Client as IClient
-import qualified Inherited_Iface as IIface
-import qualified Srv_Client as SClient
-import qualified Srv_Iface as SIface
-
--- we don't actually need this import, but force it to check the code generator exports proper Haskell syntax
-import qualified Srv()
-
-
-data InheritedHandler = InheritedHandler
-instance SIface.Srv_Iface InheritedHandler where
-    janky _ arg = do
-        ThriftTestUtils.serverLog $ "Got janky method call: " ++ show arg
-        return $ 31
-
-    voidMethod _ = do
-        ThriftTestUtils.serverLog "Got voidMethod method call"
-        return ()
-
-    primitiveMethod _ = do
-        ThriftTestUtils.serverLog "Got primitiveMethod call"
-        return $ 42
-
-    structMethod _ = do
-        ThriftTestUtils.serverLog "Got structMethod call"
-        return $ Types.CompactProtoTestStruct {
-            Types.compactProtoTestStruct_a_byte = 0x01,
-            Types.compactProtoTestStruct_a_i16 = 0x02,
-            Types.compactProtoTestStruct_a_i32 = 0x03,
-            Types.compactProtoTestStruct_a_i64 = 0x04,
-            Types.compactProtoTestStruct_a_double = 0.1,
-            Types.compactProtoTestStruct_a_string = "abcdef",
-            Types.compactProtoTestStruct_a_binary = DBL.empty,
-            Types.compactProtoTestStruct_true_field = True,
-            Types.compactProtoTestStruct_false_field = False,
-            Types.compactProtoTestStruct_empty_struct_field = Types.Empty,
-            
-            Types.compactProtoTestStruct_byte_list = Vector.empty,
-            Types.compactProtoTestStruct_i16_list = Vector.empty,
-            Types.compactProtoTestStruct_i32_list = Vector.empty,
-            Types.compactProtoTestStruct_i64_list = Vector.empty,
-            Types.compactProtoTestStruct_double_list = Vector.empty,
-            Types.compactProtoTestStruct_string_list = Vector.empty,
-            Types.compactProtoTestStruct_binary_list = Vector.empty,
-            Types.compactProtoTestStruct_boolean_list = Vector.empty,
-            Types.compactProtoTestStruct_struct_list = Vector.empty,
-
-            Types.compactProtoTestStruct_byte_set = Set.empty,
-            Types.compactProtoTestStruct_i16_set = Set.empty,
-            Types.compactProtoTestStruct_i32_set = Set.empty,
-            Types.compactProtoTestStruct_i64_set = Set.empty,
-            Types.compactProtoTestStruct_double_set = Set.empty,
-            Types.compactProtoTestStruct_string_set = Set.empty,
-            Types.compactProtoTestStruct_binary_set = Set.empty,
-            Types.compactProtoTestStruct_boolean_set = Set.empty,
-            Types.compactProtoTestStruct_struct_set = Set.empty,
-
-            Types.compactProtoTestStruct_byte_byte_map = Map.empty,
-            Types.compactProtoTestStruct_i16_byte_map = Map.empty,
-            Types.compactProtoTestStruct_i32_byte_map = Map.empty,
-            Types.compactProtoTestStruct_i64_byte_map = Map.empty,
-            Types.compactProtoTestStruct_double_byte_map = Map.empty,
-            Types.compactProtoTestStruct_string_byte_map = Map.empty,
-            Types.compactProtoTestStruct_binary_byte_map = Map.empty,
-            Types.compactProtoTestStruct_boolean_byte_map = Map.empty,
-
-            Types.compactProtoTestStruct_byte_i16_map = Map.empty,
-            Types.compactProtoTestStruct_byte_i32_map = Map.empty,
-            Types.compactProtoTestStruct_byte_i64_map = Map.empty,
-            Types.compactProtoTestStruct_byte_double_map = Map.empty,
-            Types.compactProtoTestStruct_byte_string_map = Map.empty,
-            Types.compactProtoTestStruct_byte_binary_map = Map.empty,
-            Types.compactProtoTestStruct_byte_boolean_map = Map.empty,
-
-            Types.compactProtoTestStruct_list_byte_map = Map.empty,
-            Types.compactProtoTestStruct_set_byte_map = Map.empty,
-            Types.compactProtoTestStruct_map_byte_map = Map.empty,
-
-            Types.compactProtoTestStruct_byte_map_map = Map.empty,
-            Types.compactProtoTestStruct_byte_set_map = Map.empty,
-            Types.compactProtoTestStruct_byte_list_map = Map.empty,
-
-            Types.compactProtoTestStruct_field500 = 500,
-            Types.compactProtoTestStruct_field5000 = 5000,
-            Types.compactProtoTestStruct_field20000 = 20000 }
-
-    methodWithDefaultArgs _ arg = do
-        ThriftTestUtils.serverLog $ "Got methodWithDefaultArgs: " ++ show arg
-        return ()
-
-    onewayMethod _ = do
-        ThriftTestUtils.serverLog "Got onewayMethod"
-
-instance IIface.Inherited_Iface InheritedHandler where
-    identity _ arg = do
-        ThriftTestUtils.serverLog $ "Got identity method: " ++ show arg
-        return arg
-
-client :: (String, Network.PortID) -> IO ()
-client addr = do
-    to <- hOpen addr
-    let p =  BinaryProtocol to
-    let ps = (p,p)
-
-    v1 <- SClient.janky ps 42
-    ThriftTestUtils.clientLog $ show v1
-
-    SClient.voidMethod ps
-
-    v2 <- SClient.primitiveMethod ps
-    ThriftTestUtils.clientLog $ show v2
-
-    v3 <- SClient.structMethod ps
-    ThriftTestUtils.clientLog $ show v3
-
-    SClient.methodWithDefaultArgs ps 42
-
-    SClient.onewayMethod ps
-
-    v4 <- IClient.identity ps 42
-    ThriftTestUtils.clientLog $ show v4
-
-    return ()
-
-server :: Network.PortNumber -> IO ()
-server port = do 
-    ThriftTestUtils.serverLog "Ready..."
-    (runBasicServer InheritedHandler Inherited.process port)
-    `Control.Exception.catch`
-    (\(TransportExn s _) -> error $ "FAILURE: " ++ show s)
-
-main :: IO ()
-main = ThriftTestUtils.runTest server client
diff --git a/test/hs/Include_Main.hs b/test/hs/Include_Main.hs
deleted file mode 100644
index d3977a1..0000000
--- a/test/hs/Include_Main.hs
+++ /dev/null
@@ -1,7 +0,0 @@
-module Main where
-
-import Include_Types
-import ThriftTest_Types
-
-main :: IO ()
-main = putStrLn ("Includes work: " ++ (show (IncludeTest $ Bools True False)))
diff --git a/test/hs/Makefile.am b/test/hs/Makefile.am
deleted file mode 100644
index 817070d..0000000
--- a/test/hs/Makefile.am
+++ /dev/null
@@ -1,50 +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.
-#
-
-stubs: $(THRIFT) ../ConstantsDemo.thrift ../DebugProtoTest.thrift ../ThriftTest.thrift ../Include.thrift
-	$(THRIFT) --gen hs ../ConstantsDemo.thrift
-	$(THRIFT) --gen hs ../DebugProtoTest.thrift
-	$(THRIFT) --gen hs ../ThriftTest.thrift
-	$(THRIFT) --gen hs ../Include.thrift
-
-check: stubs
-	sh run-test.sh ConstantsDemo
-	sh run-test.sh DebugProtoTest
-	sh run-test.sh ThriftTest
-	sh run-test.sh Include
-
-clean-local:
-	$(RM) -r gen-hs/
-	$(RM) *.hi
-	$(RM) *.o
-	$(RM) TestClient
-	$(RM) TestServer
-
-dist-hook:
-	$(RM) -r $(distdir)/gen-hs/
-	$(RM) $(distdir)/*.hi
-	$(RM) $(distdir)/*.o
-	$(RM) $(destdir)/TestClient
-	$(RM) $(destdir)/TestServer
-
-all-local: stubs
-	ghc -igen-hs TestServer.hs
-	ghc -igen-hs TestClient.hs
-
-precross: all-local
diff --git a/test/hs/TestClient.hs b/test/hs/TestClient.hs
deleted file mode 100644
index d014e08..0000000
--- a/test/hs/TestClient.hs
+++ /dev/null
@@ -1,306 +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.
---
-
-{-# LANGUAGE OverloadedStrings, RecordWildCards, ScopedTypeVariables #-}
-module Main where
-
-import Control.Exception
-import Control.Monad
-import Data.Functor
-import Data.List.Split
-import Data.String
-import Network
-import Network.URI
-import System.Environment
-import System.Exit
-import qualified Data.ByteString.Lazy as LBS
-import qualified Data.HashMap.Strict as Map
-import qualified Data.HashSet as Set
-import qualified Data.Vector as Vector
-import qualified System.IO as IO
-
-import ThriftTest_Iface
-import ThriftTest_Types
-import qualified ThriftTest_Client as Client
-
-import Thrift.Transport
-import Thrift.Transport.Framed
-import Thrift.Transport.Handle
-import Thrift.Transport.HttpClient
-import Thrift.Protocol
-import Thrift.Protocol.Binary
-import Thrift.Protocol.Compact
-import Thrift.Protocol.Header
-import Thrift.Protocol.JSON
-
-data Options = Options
-  { host         :: String
-  , port         :: Int
-  , domainSocket :: String
-  , transport    :: String
-  , protocol     :: ProtocolType
-  -- TODO: Haskell lib does not have SSL support
-  , ssl          :: Bool
-  , testLoops    :: Int
-  }
-  deriving (Show, Eq)
-
-data TransportType = Buffered IO.Handle
-                   | Framed (FramedTransport IO.Handle)
-                   | Http HttpClient
-                   | NoTransport String
-
-getTransport :: String -> String -> Int -> (IO TransportType)
-getTransport "buffered" host port = do
-  h <- hOpen (host, PortNumber $ fromIntegral port)
-  IO.hSetBuffering h $ IO.BlockBuffering Nothing
-  return $ Buffered h
-getTransport "framed" host port = do
-  h <- hOpen (host, PortNumber $ fromIntegral port)
-  t <- openFramedTransport h
-  return $ Framed t
-getTransport "http" host port = let uriStr = "http://" ++ host ++ ":" ++ show port in
-                                case parseURI uriStr of
-                                  Nothing -> do return (NoTransport $ "Failed to parse URI: " ++ uriStr)
-                                  Just(uri) -> do
-                                    t <- openHttpClient uri
-                                    return $ Http t
-getTransport t host port = do return (NoTransport $ "Unsupported transport: " ++ t)
-
-data ProtocolType = Binary
-                  | Compact
-                  | JSON
-                  | Header
-                  deriving (Show, Eq)
-
-getProtocol :: String -> ProtocolType
-getProtocol "binary"  = Binary
-getProtocol "compact" = Compact
-getProtocol "json"    = JSON
-getProtocol "header" = Header
-getProtocol p = error $ "Unsupported Protocol: " ++ p
-
-defaultOptions :: Options
-defaultOptions = Options
-  { port         = 9090
-  , domainSocket = ""
-  , host         = "localhost"
-  , transport    = "buffered"
-  , protocol     = Binary
-  , ssl          = False
-  , testLoops    = 1
-  }
-
-runClient :: Protocol p => p -> IO ()
-runClient p = do
-  let prot = (p,p)
-  putStrLn "Starting Tests"
-
-  -- VOID Test
-  putStrLn "testVoid"
-  Client.testVoid prot
-
-  -- String Test
-  putStrLn "testString"
-  s <- Client.testString prot "Test"
-  when (s /= "Test") exitFailure
-
-  -- Bool Test
-  putStrLn "testBool"
-  bool <- Client.testBool prot True
-  when (not bool) exitFailure
-  putStrLn "testBool"
-  bool <- Client.testBool prot False
-  when (bool) exitFailure
-
-  -- Byte Test
-  putStrLn "testByte"
-  byte <- Client.testByte prot 1
-  when (byte /= 1) exitFailure
-
-  -- I32 Test
-  putStrLn "testI32"
-  i32 <- Client.testI32 prot (-1)
-  when (i32 /= -1) exitFailure
-
-  -- I64 Test
-  putStrLn "testI64"
-  i64 <- Client.testI64 prot (-34359738368)
-  when (i64 /= -34359738368) exitFailure
-
-  -- Double Test
-  putStrLn "testDouble"
-  dub <- Client.testDouble prot (-5.2098523)
-  when (abs (dub + 5.2098523) > 0.001) exitFailure
-
-  -- Binary Test
-  putStrLn "testBinary"
-  bin <- Client.testBinary prot (LBS.pack . reverse $ [-128..127])
-  when ((reverse [-128..127]) /= LBS.unpack bin) exitFailure
-  
-  -- Struct Test
-  let structIn = Xtruct{ xtruct_string_thing = "Zero"
-                       , xtruct_byte_thing   = 1
-                       , xtruct_i32_thing    = -3
-                       , xtruct_i64_thing    = -5
-                       }
-  putStrLn "testStruct"
-  structOut <- Client.testStruct prot structIn
-  when (structIn /= structOut) exitFailure
-
-  -- Nested Struct Test
-  let nestIn = Xtruct2{ xtruct2_byte_thing   = 1
-                      , xtruct2_struct_thing = structIn
-                      , xtruct2_i32_thing    = 5
-                      }
-  putStrLn "testNest"
-  nestOut <- Client.testNest prot nestIn
-  when (nestIn /= nestOut) exitFailure
-
-  -- Map Test
-  let mapIn = Map.fromList $ map (\i -> (i, i-10)) [1..5]
-  putStrLn "testMap"
-  mapOut <- Client.testMap prot mapIn
-  when (mapIn /= mapOut) exitFailure
-
-  -- Set Test
-  let setIn = Set.fromList [-2..3]
-  putStrLn "testSet"
-  setOut <- Client.testSet prot setIn
-  when (setIn /= setOut) exitFailure
-
-  -- List Test
-  let listIn = Vector.fromList [-2..3]
-  putStrLn "testList"
-  listOut <- Client.testList prot listIn
-  when (listIn /= listOut) exitFailure
-
-  -- Enum Test
-  putStrLn "testEnum"
-  numz1 <- Client.testEnum prot Numberz_ONE
-  when (numz1 /= Numberz_ONE) exitFailure
-
-  putStrLn "testEnum"
-  numz2 <- Client.testEnum prot Numberz_TWO
-  when (numz2 /= Numberz_TWO) exitFailure
-
-  putStrLn "testEnum"
-  numz5 <- Client.testEnum prot Numberz_FIVE
-  when (numz5 /= Numberz_FIVE) exitFailure
-
-  -- Typedef Test
-  putStrLn "testTypedef"
-  uid <- Client.testTypedef prot 309858235082523
-  when (uid /= 309858235082523) exitFailure
-
-  -- Nested Map Test
-  putStrLn "testMapMap"
-  _ <- Client.testMapMap prot 1
-
-  -- Exception Test
-  putStrLn "testException"
-  exn1 <- try $ Client.testException prot "Xception"
-  case exn1 of
-    Left (Xception _ _) -> return ()
-    _ -> putStrLn (show exn1) >> exitFailure
-
-  putStrLn "testException"
-  exn2 <- try $ Client.testException prot "TException"
-  case exn2 of
-    Left (_ :: SomeException) -> return ()
-    Right _ -> exitFailure
-
-  putStrLn "testException"
-  exn3 <- try $ Client.testException prot "success"
-  case exn3 of
-    Left (_ :: SomeException) -> exitFailure
-    Right _ -> return ()
-
-  -- Multi Exception Test
-  putStrLn "testMultiException"
-  multi1 <- try $ Client.testMultiException prot "Xception" "test 1"
-  case multi1 of
-    Left (Xception _ _) -> return ()
-    _ -> exitFailure
-
-  putStrLn "testMultiException"
-  multi2 <- try $ Client.testMultiException prot "Xception2" "test 2"
-  case multi2 of
-    Left (Xception2 _ _) -> return ()
-    _ -> exitFailure
-
-  putStrLn "testMultiException"
-  multi3 <- try $ Client.testMultiException prot "success" "test 3"
-  case multi3 of
-    Left (_ :: SomeException) -> exitFailure
-    Right _ -> return ()
-
-
-main :: IO ()
-main = do
-  options <- flip parseFlags defaultOptions <$> getArgs
-  case options of
-    Nothing -> showHelp
-    Just Options{..} -> do
-      trans <- Main.getTransport transport host port
-      case trans of
-        Buffered t -> runTest testLoops protocol t
-        Framed t   -> runTest testLoops protocol t
-        Http t     -> runTest testLoops protocol t
-        NoTransport err -> putStrLn err
-  where
-    makeClient p t = case p of
-                       Binary  -> runClient $ BinaryProtocol t
-                       Compact -> runClient $ CompactProtocol t
-                       JSON    -> runClient $ JSONProtocol t
-                       Header  -> createHeaderProtocol t t >>= runClient
-    runTest loops p t = do
-      let client = makeClient p t
-      replicateM_ loops client
-      putStrLn "COMPLETED SUCCESSFULLY"
-
-parseFlags :: [String] -> Options -> Maybe Options
-parseFlags (flag : flags) opts = do
-  let pieces = splitOn "=" flag
-  case pieces of
-    "--port" : arg : _ -> parseFlags flags opts{ port = read arg }
-    "--domain-socket" : arg : _ -> parseFlags flags opts{ domainSocket = read arg }
-    "--host" : arg : _ -> parseFlags flags opts{ host = arg }
-    "--transport" : arg : _ -> parseFlags flags opts{ transport = arg }
-    "--protocol" : arg : _ -> parseFlags flags opts{ protocol = getProtocol arg }
-    "-n" : arg : _ -> parseFlags flags opts{ testLoops = read arg }
-    "--h" : _ -> Nothing
-    "--help" : _ -> Nothing
-    "--ssl" : _ -> parseFlags flags opts{ ssl = True }
-    "--processor-events" : _ -> parseFlags flags opts
-    _ -> Nothing
-parseFlags [] opts = Just opts
-
-showHelp :: IO ()
-showHelp = putStrLn
-  "Allowed options:\n\
-  \  -h [ --help ]               produce help message\n\
-  \  --host arg (=localhost)     Host to connect\n\
-  \  --port arg (=9090)          Port number to connect\n\
-  \  --domain-socket arg         Domain Socket (e.g. /tmp/ThriftTest.thrift),\n\
-  \                              instead of host and port\n\
-  \  --transport arg (=buffered) Transport: buffered, framed, http\n\
-  \  --protocol arg (=binary)    Protocol: binary, compact, json\n\
-  \  --ssl                       Encrypted Transport using SSL\n\
-  \  -n [ --testloops ] arg (=1) Number of Tests"
diff --git a/test/hs/TestServer.hs b/test/hs/TestServer.hs
deleted file mode 100644
index c37dda3..0000000
--- a/test/hs/TestServer.hs
+++ /dev/null
@@ -1,312 +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.
---
-
-{-# LANGUAGE OverloadedStrings,RecordWildCards #-}
-module Main where
-
-import Control.Exception
-import Control.Monad
-import Data.Functor
-import Data.HashMap.Strict (HashMap)
-import Data.List
-import Data.List.Split
-import Data.String
-import Network
-import System.Environment
-import System.Exit
-import System.IO
-import Control.Concurrent (threadDelay)
-import qualified System.IO as IO
-import qualified Data.HashMap.Strict as Map
-import qualified Data.HashSet as Set
-import qualified Data.Text.Lazy as Text
-import qualified Data.Vector as Vector
-
-import ThriftTest
-import ThriftTest_Iface
-import ThriftTest_Types
-
-import Thrift
-import Thrift.Server
-import Thrift.Transport.Framed
-import Thrift.Transport.Handle
-import Thrift.Protocol.Binary
-import Thrift.Protocol.Compact
-import Thrift.Protocol.Header
-import Thrift.Protocol.JSON
-
-data Options = Options
-  { port         :: Int
-  , domainSocket :: String
-  , serverType   :: ServerType
-  , transport    :: String
-  , protocol     :: ProtocolType
-  , ssl          :: Bool
-  , workers      :: Int
-  }
-
-data ServerType = Simple
-                | ThreadPool
-                | Threaded
-                | NonBlocking
-                deriving (Show, Eq)
-
-instance IsString ServerType where
-  fromString "simple"      = Simple
-  fromString "thread-pool" = ThreadPool
-  fromString "threaded"    = Threaded
-  fromString "nonblocking" = NonBlocking
-  fromString _ = error "not a valid server type"
-
-data TransportType = Buffered (Socket -> (IO IO.Handle))
-                   | Framed (Socket -> (IO (FramedTransport IO.Handle)))
-                   | NoTransport String
-
-getTransport :: String -> TransportType
-getTransport "buffered" = Buffered $ \s -> do
-  (h, _, _) <- (accept s)
-  IO.hSetBuffering h $ IO.BlockBuffering Nothing
-  return h
-getTransport "framed" = Framed $ \s -> do
-  (h, _, _) <- (accept s)
-  openFramedTransport h
-getTransport t = NoTransport $ "Unsupported transport: " ++ t
-
-data ProtocolType = Binary
-                  | Compact
-                  | JSON
-                  | Header
-
-getProtocol :: String -> ProtocolType
-getProtocol "binary"  = Binary
-getProtocol "compact" = Compact
-getProtocol "json"    = JSON
-getProtocol "header"  = Header
-getProtocol p = error $"Unsupported Protocol: " ++ p
-
-defaultOptions :: Options
-defaultOptions = Options
-  { port         = 9090
-  , domainSocket = ""
-  , serverType   = Threaded
-  , transport    = "buffered"
-  , protocol     = Binary
-  -- TODO: Haskell lib does not have SSL support
-  , ssl          = False
-  , workers      = 4
-  }
-
-stringifyMap :: (Show a, Show b) => Map.HashMap a b -> String
-stringifyMap = Data.List.intercalate ", " . Data.List.map joinKV . Map.toList
-  where joinKV (k, v) = show k ++ " => " ++ show v
-
-stringifySet :: Show a => Set.HashSet a -> String
-stringifySet = Data.List.intercalate ", " . Data.List.map show . Set.toList
-
-stringifyList :: Show a => Vector.Vector a -> String
-stringifyList = Data.List.intercalate ", " . Data.List.map show . Vector.toList
-
-data TestHandler = TestHandler
-instance ThriftTest_Iface TestHandler where
-  testVoid _ = System.IO.putStrLn "testVoid()"
-
-  testString _ s = do
-    System.IO.putStrLn $ "testString(" ++ show s ++ ")"
-    return s
-
-  testBool _ x = do
-    System.IO.putStrLn $ "testBool(" ++ show x ++ ")"
-    return x
-
-  testByte _ x = do
-    System.IO.putStrLn $ "testByte(" ++ show x ++ ")"
-    return x
-
-  testI32 _ x = do
-    System.IO.putStrLn $ "testI32(" ++ show x ++ ")"
-    return x
-
-  testI64 _ x = do
-    System.IO.putStrLn $ "testI64(" ++ show x ++ ")"
-    return x
-
-  testDouble _ x = do
-    System.IO.putStrLn $ "testDouble(" ++ show x ++ ")"
-    return x
-
-  testBinary _ x = do
-    System.IO.putStrLn $ "testBinary(" ++ show x ++ ")"
-    return x
-
-  testStruct _ struct@Xtruct{..} = do
-    System.IO.putStrLn $ "testStruct({" ++ show xtruct_string_thing
-                      ++ ", " ++ show xtruct_byte_thing
-                      ++ ", " ++ show xtruct_i32_thing
-                      ++ ", " ++ show xtruct_i64_thing
-                      ++ "})"
-    return struct
-
-  testNest _ nest@Xtruct2{..} = do
-    let Xtruct{..} = xtruct2_struct_thing
-    System.IO.putStrLn $ "testNest({" ++ show xtruct2_byte_thing
-                   ++ "{, " ++ show xtruct_string_thing
-                   ++  ", " ++ show xtruct_byte_thing
-                   ++  ", " ++ show xtruct_i32_thing
-                   ++  ", " ++ show xtruct_i64_thing
-                   ++ "}, " ++ show xtruct2_i32_thing
-    return nest
-
-  testMap _ m = do
-    System.IO.putStrLn $ "testMap({" ++ stringifyMap m ++ "})"
-    return m
-
-  testStringMap _ m = do
-    System.IO.putStrLn $ "testStringMap(" ++ stringifyMap m ++ "})"
-    return m
-
-  testSet _ x = do
-    System.IO.putStrLn $ "testSet({" ++ stringifySet x ++ "})"
-    return x
-
-  testList _ x = do
-    System.IO.putStrLn $ "testList(" ++ stringifyList x ++ "})"
-    return x
-
-  testEnum _ x = do
-    System.IO.putStrLn $ "testEnum(" ++ show x ++ ")"
-    return x
-
-  testTypedef _ x = do
-    System.IO.putStrLn $ "testTypedef(" ++ show x ++ ")"
-    return x
-
-  testMapMap _ x = do
-    System.IO.putStrLn $ "testMapMap(" ++ show x ++ ")"
-    return $ Map.fromList [ (-4, Map.fromList [ (-4, -4)
-                                              , (-3, -3)
-                                              , (-2, -2)
-                                              , (-1, -1)
-                                              ])
-                          , (4,  Map.fromList [ (1, 1)
-                                              , (2, 2)
-                                              , (3, 3)
-                                              , (4, 4)
-                                              ])
-                          ]
-
-  testInsanity _ x = do
-    System.IO.putStrLn "testInsanity()"
-    return $ Map.fromList [ (1, Map.fromList [ (Numberz_TWO  , x)
-                                             , (Numberz_THREE, x)
-                                             ])
-                          , (2, Map.fromList [ (Numberz_SIX, default_Insanity)
-                                             ])
-                          ]
-
-  testMulti _ byte i32 i64 _ _ _ = do
-    System.IO.putStrLn "testMulti()"
-    return Xtruct{ xtruct_string_thing = Text.pack "Hello2"
-                 , xtruct_byte_thing   = byte
-                 , xtruct_i32_thing    = i32
-                 , xtruct_i64_thing    = i64
-                 }
-
-  testException _ s = do
-    System.IO.putStrLn $ "testException(" ++ show s ++ ")"
-    case s of
-      "Xception"   -> throw $ Xception 1001 s
-      "TException" -> throw ThriftException
-      _ -> return ()
-
-  testMultiException _ s1 s2 = do
-    System.IO.putStrLn $ "testMultiException(" ++ show s1 ++ ", " ++ show s2 ++  ")"
-    case s1 of
-      "Xception"   -> throw $ Xception 1001 "This is an Xception"
-      "Xception2"  -> throw $ Xception2 2002 $ Xtruct "This is an Xception2" 0 0 0
-      "TException" -> throw ThriftException
-      _ -> return default_Xtruct{ xtruct_string_thing = s2 }
-
-  testOneway _ i = do
-    System.IO.putStrLn $ "testOneway(" ++ show i ++ "): Sleeping..."
-    threadDelay $ (fromIntegral i) * 1000000
-    System.IO.putStrLn $ "testOneway(" ++ show i ++ "): done sleeping!"
-
-main :: IO ()
-main = do
-  options <- flip parseFlags defaultOptions <$> getArgs
-  case options of
-    Nothing -> showHelp
-    Just Options{..} -> do
-      case Main.getTransport transport of
-        Buffered f -> runServer protocol f port
-        Framed   f -> runServer protocol f port
-        NoTransport err -> putStrLn err
-      System.IO.putStrLn $ "Starting \"" ++ show serverType ++ "\" server (" ++
-        show transport ++ ") listen on: " ++ domainSocket ++ show port
-      where
-        acceptor p f socket = do
-          t <- f socket
-          return (p t, p t)
-
-        headerAcceptor f socket = do
-          t <- f socket
-          p <- createHeaderProtocol1 t
-          return (p, p)
-
-        doRunServer p f = do
-          runThreadedServer (acceptor p f) TestHandler ThriftTest.process . PortNumber . fromIntegral
-
-        runServer p f port = case p of
-          Binary  -> doRunServer BinaryProtocol f port
-          Compact -> doRunServer CompactProtocol f port
-          JSON    -> doRunServer JSONProtocol f port
-          Header  -> runThreadedServer (headerAcceptor f) TestHandler ThriftTest.process (PortNumber $ fromIntegral port)
-
-parseFlags :: [String] -> Options -> Maybe Options
-parseFlags (flag : flags) opts = do
-  let pieces = splitOn "=" flag
-  case pieces of
-    "--port" : arg : _ -> parseFlags flags opts{ port = read arg }
-    "--domain-socket" : arg : _ -> parseFlags flags opts{ domainSocket = read arg }
-    "--server-type" : arg : _ -> parseFlags flags opts{ serverType = fromString arg }
-    "--transport" : arg : _ -> parseFlags flags opts{ transport = arg }
-    "--protocol" : arg : _ -> parseFlags flags opts{ protocol = getProtocol arg }
-    "--workers" : arg : _ -> parseFlags flags opts{ workers = read arg }
-    "-n" : arg : _ -> parseFlags flags opts{ workers = read arg }
-    "--h" : _ -> Nothing
-    "--help" : _ -> Nothing
-    "--ssl" : _ -> parseFlags flags opts{ ssl = True }
-    "--processor-events" : _ -> parseFlags flags opts
-    _ -> Nothing
-parseFlags [] opts = Just opts
-
-showHelp :: IO ()
-showHelp = System.IO.putStrLn
-  "Allowed options:\n\
-  \  -h [ --help ]               produce help message\n\
-  \  --port arg (=9090)          Port number to listen\n\
-  \  --domain-socket arg         Unix Domain Socket (e.g. /tmp/ThriftTest.thrift)\n\
-  \  --server-type arg (=simple) type of server, \"simple\", \"thread-pool\",\n\
-  \                              \"threaded\", or \"nonblocking\"\n\
-  \  --transport arg (=buffered) transport: buffered, framed\n\
-  \  --protocol arg (=binary)    protocol: binary, compact, json\n\
-  \  --ssl                       Encrypted Transport using SSL\n\
-  \  --processor-events          processor-events\n\
-  \  -n [ --workers ] arg (=4)   Number of thread pools workers. Only valid for\n\
-  \                              thread-pool server type"
diff --git a/test/hs/ThriftTestUtils.hs b/test/hs/ThriftTestUtils.hs
deleted file mode 100644
index 9c19b56..0000000
--- a/test/hs/ThriftTestUtils.hs
+++ /dev/null
@@ -1,65 +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.
---
-
-module ThriftTestUtils (ClientFunc, ServerFunc, clientLog, serverLog, testLog, runTest) where
-
-
-import qualified Control.Concurrent
-import qualified Network
-import qualified System.IO
-
-
-serverPort :: Network.PortNumber
-serverPort = 9090
-
-serverAddress :: (String, Network.PortID)
-serverAddress = ("localhost", Network.PortNumber serverPort)
-
-
-testLog :: String -> IO ()
-testLog str = do
-    System.IO.hPutStr System.IO.stdout $ str ++ "\n"
-    System.IO.hFlush System.IO.stdout
-
-
-clientLog :: String -> IO ()
-clientLog str = testLog $ "CLIENT: " ++ str
-
-serverLog :: String -> IO ()
-serverLog str = testLog $ "SERVER: " ++ str
-
-
-type ServerFunc = Network.PortNumber -> IO ()
-type ClientFunc = (String, Network.PortID) -> IO ()
-
-runTest :: ServerFunc -> ClientFunc -> IO ()
-runTest server client = do
-    _ <- Control.Concurrent.forkIO (server serverPort)
-
-    -- Fairly horrible; this does not 100% guarantees that the other thread
-    -- has actually opened the socket we need... but not much else we can do
-    -- without this, the client races the server to the socket, and wins every
-    -- time
-    Control.Concurrent.yield
-    Control.Concurrent.threadDelay $ 500 * 1000 -- unit is in _micro_seconds
-    Control.Concurrent.yield
-
-    client serverAddress
-
-    testLog "SUCCESS"
diff --git a/test/hs/ThriftTest_Main.hs b/test/hs/ThriftTest_Main.hs
deleted file mode 100644
index 6421c6a..0000000
--- a/test/hs/ThriftTest_Main.hs
+++ /dev/null
@@ -1,214 +0,0 @@
-{-# LANGUAGE ScopedTypeVariables #-}
---
--- 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.
---
-
-{-# LANGUAGE OverloadedStrings #-}
-
-module Main where
-
-
-import qualified Control.Exception
-import qualified Data.HashMap.Strict as Map
-import qualified Data.HashSet as Set
-import qualified Data.Vector as Vector
-
-import qualified Network
-
-import Thrift
-import Thrift.Protocol.Binary
-import Thrift.Server
-import Thrift.Transport.Handle
-
-import qualified ThriftTestUtils
-
-import qualified ThriftTest
-import qualified ThriftTest_Client as Client
-import qualified ThriftTest_Iface as Iface
-import qualified ThriftTest_Types as Types
-
-
-data TestHandler = TestHandler
-instance Iface.ThriftTest_Iface TestHandler where
-    testVoid _ = return ()
-
-    testString _ s = do
-        ThriftTestUtils.serverLog $ show s
-        return s
-
-    testByte _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testI32 _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testI64 _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testDouble _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testBinary _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testStruct _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testNest _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testMap _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testStringMap _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testSet _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testList _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testEnum _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testTypedef _ x = do
-        ThriftTestUtils.serverLog $ show x
-        return x
-
-    testMapMap _ _ = do
-        return (Map.fromList [(1, Map.fromList [(2, 2)])])
-
-    testInsanity _ x = do
-        return (Map.fromList [(1, Map.fromList [(Types.Numberz_ONE, x)])])
-
-    testMulti _ _ _ _ _ _ _ = do
-        return (Types.Xtruct "" 0 0 0)
-
-    testException _ _ = do
-        Control.Exception.throw (Types.Xception 1 "bya")
-
-    testMultiException _ _ _ = do
-        Control.Exception.throw (Types.Xception 1 "xyz")
-
-    testOneway _ i = do
-        ThriftTestUtils.serverLog $ show i
-
-
-client :: (String, Network.PortID) -> IO ()
-client addr = do
-    to <- hOpen addr
-    let ps = (BinaryProtocol to, BinaryProtocol to)
-
-    v1 <- Client.testString ps "bya"
-    ThriftTestUtils.clientLog $ show v1
-
-    v2 <- Client.testByte ps 8
-    ThriftTestUtils.clientLog $ show v2
-
-    v3 <- Client.testByte ps (-8)
-    ThriftTestUtils.clientLog $ show v3
-
-    v4 <- Client.testI32 ps 32
-    ThriftTestUtils.clientLog $ show v4
-
-    v5 <- Client.testI32 ps (-32)
-    ThriftTestUtils.clientLog $ show v5
-
-    v6 <- Client.testI64 ps 64
-    ThriftTestUtils.clientLog $ show v6
-
-    v7 <- Client.testI64 ps (-64)
-    ThriftTestUtils.clientLog $ show v7
-
-    v8 <- Client.testDouble ps 3.14
-    ThriftTestUtils.clientLog $ show v8
-
-    v9 <- Client.testDouble ps (-3.14)
-    ThriftTestUtils.clientLog $ show v9
-
-    -- TODO: Client.testBinary ...
-	
-    v10 <- Client.testMap ps (Map.fromList [(1,1),(2,2),(3,3)])
-    ThriftTestUtils.clientLog $ show v10
-
-    v11 <- Client.testStringMap ps (Map.fromList [("a","123"),("a b","with spaces "),("same","same"),("0","numeric key")])
-    ThriftTestUtils.clientLog $ show v11
-
-    v12 <- Client.testList ps (Vector.fromList [1,2,3,4,5])
-    ThriftTestUtils.clientLog $ show v12
-
-    v13 <- Client.testSet ps (Set.fromList [1,2,3,4,5])
-    ThriftTestUtils.clientLog $ show v13
-
-    v14 <- Client.testStruct ps (Types.Xtruct "hi" 4 5 0)
-    ThriftTestUtils.clientLog $ show v14
-
-    (testException ps "bad") `Control.Exception.catch` testExceptionHandler
-
-    (testMultiException ps "ok") `Control.Exception.catch` testMultiExceptionHandler1
-    (testMultiException ps "bad") `Control.Exception.catch` testMultiExceptionHandler2 `Control.Exception.catch` testMultiExceptionHandler3
-
-    -- (  (Client.testMultiException ps "e" "e2">> ThriftTestUtils.clientLog "bad") `Control.Exception.catch` 
-
-    tClose to
-  where testException ps msg = do
-            _ <- Client.testException ps "e"
-            ThriftTestUtils.clientLog msg
-            return ()
-
-        testExceptionHandler (e :: Types.Xception) = do
-            ThriftTestUtils.clientLog $ show e
-
-        testMultiException ps msg = do
-            _ <- Client.testMultiException ps "e" "e2"
-            ThriftTestUtils.clientLog msg
-            return ()
-
-        testMultiExceptionHandler1 (e :: Types.Xception) = do
-            ThriftTestUtils.clientLog $ show e
-
-        testMultiExceptionHandler2 (e :: Types.Xception2) = do
-            ThriftTestUtils.clientLog $ show e
-
-        testMultiExceptionHandler3 (_ :: Control.Exception.SomeException) = do
-            ThriftTestUtils.clientLog "ok"
-
-
-server :: Network.PortNumber -> IO ()
-server port = do
-    ThriftTestUtils.serverLog "Ready..."
-    (runBasicServer TestHandler ThriftTest.process port)
-    `Control.Exception.catch`
-    (\(TransportExn s _) -> error $ "FAILURE: " ++ s)
-
-
-main :: IO ()
-main = ThriftTestUtils.runTest server client
diff --git a/test/hs/run-test.sh b/test/hs/run-test.sh
deleted file mode 100755
index ecafc18..0000000
--- a/test/hs/run-test.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/bin/sh
-
-#
-# 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.
-#
-
-if [ "x" = "x$1" ]; then
-  printf "run-test.sh needs an argument, the name of the test to run. Try 'ThriftTest' or 'ProtoDebugTest'\n"
-  exit 2
-fi
-
-# Check some basics
-if [ -z $BASE ]; then
-    BASE=../..
-fi
-
-# Figure out what file to run has a server
-if [ -z $TEST_SOURCE_FILE ]; then
-    TEST_SOURCE_FILE=$BASE/test/hs/$1_Main.hs
-fi
-
-if [ ! -e $TEST_SOURCE_FILE ]; then
-    printf "Missing server code file $TEST_SOURCE_FILE \n"
-    exit 3
-fi
-
-printf "Running test... \n"
-runhaskell -Wall -XScopedTypeVariables -i$BASE/lib/hs/src -igen-hs $TEST_SOURCE_FILE
diff --git a/test/known_failures_Linux.json b/test/known_failures_Linux.json
index 3ee1703..53a5139 100644
--- a/test/known_failures_Linux.json
+++ b/test/known_failures_Linux.json
@@ -271,10 +271,6 @@
   "cpp-py_multi_http-domain",
   "cpp-py_multi_http-ip",
   "cpp-py_multi_http-ip-ssl",
-  "cpp-rs_multic_buffered-ip",
-  "cpp-rs_multic_framed-ip",
-  "cpp-rs_multi_buffered-ip",
-  "cpp-rs_multi_framed-ip",
   "c_glib-netstd_binary_buffered-ip",
   "c_glib-netstd_binary_framed-ip",
   "c_glib-netstd_compact_buffered-ip",
@@ -283,10 +279,6 @@
   "c_glib-netstd_multi-binary_framed-ip",
   "c_glib-netstd_multic-compact_buffered-ip",
   "c_glib-netstd_multic-compact_framed-ip",
-  "c_glib-rs_multic_buffered-ip",
-  "c_glib-rs_multic_framed-ip",
-  "c_glib-rs_multi_buffered-ip",
-  "c_glib-rs_multi_framed-ip",
   "d-cl_binary_buffered-ip",
   "d-cl_binary_framed-ip",
   "d-cpp_binary_buffered-ip",
@@ -886,8 +878,6 @@
   "perl-netstd_multi-binary_buffered-ip-ssl",
   "perl-netstd_multi-binary_framed-ip",
   "perl-netstd_multi-binary_framed-ip-ssl",
-  "perl-rs_multi_buffered-ip",
-  "perl-rs_multi_framed-ip",
   "py-cpp_accel-binary_http-domain",
   "py-cpp_accel-binary_http-ip",
   "py-cpp_accel-binary_http-ip-ssl",
@@ -1186,14 +1176,6 @@
   "py3-php_binary-accel_framed-ip",
   "py3-php_json_buffered-ip",
   "py3-php_json_framed-ip",
-  "py3-rs_multia-multi_buffered-ip",
-  "py3-rs_multia-multi_framed-ip",
-  "py3-rs_multiac-multic_buffered-ip",
-  "py3-rs_multiac-multic_framed-ip",
-  "py3-rs_multic_buffered-ip",
-  "py3-rs_multic_framed-ip",
-  "py3-rs_multi_buffered-ip",
-  "py3-rs_multi_framed-ip",
   "rb-cpp_json_buffered-domain",
   "rb-cpp_json_buffered-ip",
   "rb-cpp_json_buffered-ip-ssl",
diff --git a/test/netstd/Client/Client.csproj b/test/netstd/Client/Client.csproj
index 4ed57cb..d3504d4 100644
--- a/test/netstd/Client/Client.csproj
+++ b/test/netstd/Client/Client.csproj
@@ -19,10 +19,12 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
+    <LangVersion>9.0</LangVersion>
     <AssemblyName>Client</AssemblyName>
     <PackageId>Client</PackageId>
     <OutputType>Exe</OutputType>
+    <Version>0.15.0.0</Version>
     <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
     <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
@@ -31,9 +33,9 @@
     <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
   </PropertyGroup>
   <ItemGroup>
-    <PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.7.0" />
+    <PackageReference Include="System.Net.Http.WinHttpHandler" Version="5.0.0" />
     <PackageReference Include="System.Runtime.Serialization.Primitives" Version="[4.3,)" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="4.8.1" />
     <PackageReference Include="System.Threading" Version="[4.3,)" />
   </ItemGroup>
   <ItemGroup>
diff --git a/test/netstd/Client/Program.cs b/test/netstd/Client/Program.cs
index 0fe2cce..bcc02a2 100644
--- a/test/netstd/Client/Program.cs
+++ b/test/netstd/Client/Program.cs
@@ -18,6 +18,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Runtime.InteropServices;
 using ThriftTest;
 
 namespace Client
@@ -26,13 +27,16 @@
     {
         public static int Main(string[] args)
         {
-            try
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
             {
-                Console.SetBufferSize(Console.BufferWidth, 4096);
-            }
-            catch (Exception)
-            {
-                Console.WriteLine("Failed to grow scroll-back buffer");
+                try
+                {
+                    Console.SetBufferSize(Console.BufferWidth, 4096);
+                }
+                catch (Exception)
+                {
+                    Console.WriteLine("Failed to grow scroll-back buffer");
+                }
             }
 
             // run whatever mode is choosen, default to test impl
@@ -66,5 +70,3 @@
         }
     }
 }
-
-
diff --git a/test/netstd/Client/TestClient.cs b/test/netstd/Client/TestClient.cs
index ec90250..70a21e1 100644
--- a/test/netstd/Client/TestClient.cs
+++ b/test/netstd/Client/TestClient.cs
@@ -353,7 +353,7 @@
 
                     try
                     {
-                        ReturnCode |= ExecuteClientTestAsync(client).GetAwaiter().GetResult(); ;
+                        ReturnCode |= ExecuteClientTest(client).GetAwaiter().GetResult(); ;
                     }
                     catch (Exception ex)
                     {
@@ -469,7 +469,7 @@
                     amount = 15 * 1024 * 1024;
                     break;
                 default:
-                    throw new ArgumentException(nameof(testcase));
+                    throw new ArgumentException("invalid argument",nameof(testcase));
             }
 
             var retval = new byte[amount];
@@ -499,16 +499,16 @@
             return token.Token;
         }
 
-        public static async Task<int> ExecuteClientTestAsync(ThriftTest.Client client)
+        public static async Task<int> ExecuteClientTest(ThriftTest.Client client)
         {
             var returnCode = 0;
 
             Console.Write("testVoid()");
-            await client.testVoidAsync(MakeTimeoutToken());
+            await client.testVoid(MakeTimeoutToken());
             Console.WriteLine(" = void");
 
             Console.Write("testString(\"Test\")");
-            var s = await client.testStringAsync("Test", MakeTimeoutToken());
+            var s = await client.testString("Test", MakeTimeoutToken());
             Console.WriteLine(" = \"" + s + "\"");
             if ("Test" != s)
             {
@@ -517,7 +517,7 @@
             }
 
             Console.Write("testBool(true)");
-            var t = await client.testBoolAsync((bool)true, MakeTimeoutToken());
+            var t = await client.testBool((bool)true, MakeTimeoutToken());
             Console.WriteLine(" = " + t);
             if (!t)
             {
@@ -525,7 +525,7 @@
                 returnCode |= ErrorBaseTypes;
             }
             Console.Write("testBool(false)");
-            var f = await client.testBoolAsync((bool)false, MakeTimeoutToken());
+            var f = await client.testBool((bool)false, MakeTimeoutToken());
             Console.WriteLine(" = " + f);
             if (f)
             {
@@ -534,7 +534,7 @@
             }
 
             Console.Write("testByte(1)");
-            var i8 = await client.testByteAsync((sbyte)1, MakeTimeoutToken());
+            var i8 = await client.testByte((sbyte)1, MakeTimeoutToken());
             Console.WriteLine(" = " + i8);
             if (1 != i8)
             {
@@ -543,7 +543,7 @@
             }
 
             Console.Write("testI32(-1)");
-            var i32 = await client.testI32Async(-1, MakeTimeoutToken());
+            var i32 = await client.testI32(-1, MakeTimeoutToken());
             Console.WriteLine(" = " + i32);
             if (-1 != i32)
             {
@@ -552,7 +552,7 @@
             }
 
             Console.Write("testI64(-34359738368)");
-            var i64 = await client.testI64Async(-34359738368, MakeTimeoutToken());
+            var i64 = await client.testI64(-34359738368, MakeTimeoutToken());
             Console.WriteLine(" = " + i64);
             if (-34359738368 != i64)
             {
@@ -562,7 +562,7 @@
 
             // TODO: Validate received message
             Console.Write("testDouble(5.325098235)");
-            var dub = await client.testDoubleAsync(5.325098235, MakeTimeoutToken());
+            var dub = await client.testDouble(5.325098235, MakeTimeoutToken());
             Console.WriteLine(" = " + dub);
             if (5.325098235 != dub)
             {
@@ -570,7 +570,7 @@
                 returnCode |= ErrorBaseTypes;
             }
             Console.Write("testDouble(-0.000341012439638598279)");
-            dub = await client.testDoubleAsync(-0.000341012439638598279, MakeTimeoutToken());
+            dub = await client.testDouble(-0.000341012439638598279, MakeTimeoutToken());
             Console.WriteLine(" = " + dub);
             if (-0.000341012439638598279 != dub)
             {
@@ -586,7 +586,7 @@
                 Console.Write("testBinary({0} bytes)", binOut.Length);
                 try
                 {
-                    var binIn = await client.testBinaryAsync(binOut, MakeTimeoutToken());
+                    var binIn = await client.testBinary(binOut, MakeTimeoutToken());
                     Console.WriteLine(" = {0} bytes", binIn.Length);
                     if (binIn.Length != binOut.Length)
                     {
@@ -636,7 +636,7 @@
                 I32_thing = -3,
                 I64_thing = -5
             };
-            var i = await client.testStructAsync(o, MakeTimeoutToken());
+            var i = await client.testStruct(o, MakeTimeoutToken());
             Console.WriteLine(" = {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}");
 
             // TODO: Validate received message
@@ -647,7 +647,7 @@
                 Struct_thing = o,
                 I32_thing = 5
             };
-            var i2 = await client.testNestAsync(o2, MakeTimeoutToken());
+            var i2 = await client.testNest(o2, MakeTimeoutToken());
             i = i2.Struct_thing;
             Console.WriteLine(" = {" + i2.Byte_thing + ", {\"" + i.String_thing + "\", " + i.Byte_thing + ", " + i.I32_thing + ", " + i.I64_thing + "}, " + i2.I32_thing + "}");
 
@@ -672,7 +672,7 @@
             }
             Console.Write("})");
 
-            var mapin = await client.testMapAsync(mapout, MakeTimeoutToken());
+            var mapin = await client.testMap(mapout, MakeTimeoutToken());
 
             Console.Write(" = {");
             first = true;
@@ -712,7 +712,7 @@
             }
             Console.Write("})");
 
-            var listin = await client.testListAsync(listout, MakeTimeoutToken());
+            var listin = await client.testList(listout, MakeTimeoutToken());
 
             Console.Write(" = {");
             first = true;
@@ -753,7 +753,7 @@
             }
             Console.Write("})");
 
-            var setin = await client.testSetAsync(setout, MakeTimeoutToken());
+            var setin = await client.testSet(setout, MakeTimeoutToken());
 
             Console.Write(" = {");
             first = true;
@@ -773,7 +773,7 @@
 
 
             Console.Write("testEnum(ONE)");
-            var ret = await client.testEnumAsync(Numberz.ONE, MakeTimeoutToken());
+            var ret = await client.testEnum(Numberz.ONE, MakeTimeoutToken());
             Console.WriteLine(" = " + ret);
             if (Numberz.ONE != ret)
             {
@@ -782,7 +782,7 @@
             }
 
             Console.Write("testEnum(TWO)");
-            ret = await client.testEnumAsync(Numberz.TWO, MakeTimeoutToken());
+            ret = await client.testEnum(Numberz.TWO, MakeTimeoutToken());
             Console.WriteLine(" = " + ret);
             if (Numberz.TWO != ret)
             {
@@ -791,7 +791,7 @@
             }
 
             Console.Write("testEnum(THREE)");
-            ret = await client.testEnumAsync(Numberz.THREE, MakeTimeoutToken());
+            ret = await client.testEnum(Numberz.THREE, MakeTimeoutToken());
             Console.WriteLine(" = " + ret);
             if (Numberz.THREE != ret)
             {
@@ -800,7 +800,7 @@
             }
 
             Console.Write("testEnum(FIVE)");
-            ret = await client.testEnumAsync(Numberz.FIVE, MakeTimeoutToken());
+            ret = await client.testEnum(Numberz.FIVE, MakeTimeoutToken());
             Console.WriteLine(" = " + ret);
             if (Numberz.FIVE != ret)
             {
@@ -809,7 +809,7 @@
             }
 
             Console.Write("testEnum(EIGHT)");
-            ret = await client.testEnumAsync(Numberz.EIGHT, MakeTimeoutToken());
+            ret = await client.testEnum(Numberz.EIGHT, MakeTimeoutToken());
             Console.WriteLine(" = " + ret);
             if (Numberz.EIGHT != ret)
             {
@@ -818,7 +818,7 @@
             }
 
             Console.Write("testTypedef(309858235082523)");
-            var uid = await client.testTypedefAsync(309858235082523L, MakeTimeoutToken());
+            var uid = await client.testTypedef(309858235082523L, MakeTimeoutToken());
             Console.WriteLine(" = " + uid);
             if (309858235082523L != uid)
             {
@@ -828,7 +828,7 @@
 
             // TODO: Validate received message
             Console.Write("testMapMap(1)");
-            var mm = await client.testMapMapAsync(1, MakeTimeoutToken());
+            var mm = await client.testMapMap(1, MakeTimeoutToken());
             Console.Write(" = {");
             foreach (var key in mm.Keys)
             {
@@ -862,7 +862,7 @@
                 truck
             };
             Console.Write("testInsanity()");
-            var whoa = await client.testInsanityAsync(insane, MakeTimeoutToken());
+            var whoa = await client.testInsanity(insane, MakeTimeoutToken());
             Console.Write(" = {");
             foreach (var key in whoa.Keys)
             {
@@ -927,14 +927,14 @@
             var arg4 = Numberz.FIVE;
             long arg5 = 5000000;
             Console.Write("Test Multi(" + arg0 + "," + arg1 + "," + arg2 + ",{" + string.Join(",", tmpMultiDict) + "}," + arg4 + "," + arg5 + ")");
-            var multiResponse = await client.testMultiAsync(arg0, arg1, arg2, multiDict, arg4, arg5, MakeTimeoutToken());
+            var multiResponse = await client.testMulti(arg0, arg1, arg2, multiDict, arg4, arg5, MakeTimeoutToken());
             Console.Write(" = Xtruct(byte_thing:" + multiResponse.Byte_thing + ",String_thing:" + multiResponse.String_thing
                           + ",i32_thing:" + multiResponse.I32_thing + ",i64_thing:" + multiResponse.I64_thing + ")\n");
 
             try
             {
                 Console.WriteLine("testException(\"Xception\")");
-                await client.testExceptionAsync("Xception", MakeTimeoutToken());
+                await client.testException("Xception", MakeTimeoutToken());
                 Console.WriteLine("*** FAILED ***");
                 returnCode |= ErrorExceptions;
             }
@@ -955,7 +955,7 @@
             try
             {
                 Console.WriteLine("testException(\"TException\")");
-                await client.testExceptionAsync("TException", MakeTimeoutToken());
+                await client.testException("TException", MakeTimeoutToken());
                 Console.WriteLine("*** FAILED ***");
                 returnCode |= ErrorExceptions;
             }
@@ -972,7 +972,7 @@
             try
             {
                 Console.WriteLine("testException(\"ok\")");
-                await client.testExceptionAsync("ok", MakeTimeoutToken());
+                await client.testException("ok", MakeTimeoutToken());
                 // OK
             }
             catch (Exception ex)
@@ -985,7 +985,7 @@
             try
             {
                 Console.WriteLine("testMultiException(\"Xception\", ...)");
-                await client.testMultiExceptionAsync("Xception", "ignore", MakeTimeoutToken());
+                await client.testMultiException("Xception", "ignore", MakeTimeoutToken());
                 Console.WriteLine("*** FAILED ***");
                 returnCode |= ErrorExceptions;
             }
@@ -1006,7 +1006,7 @@
             try
             {
                 Console.WriteLine("testMultiException(\"Xception2\", ...)");
-                await client.testMultiExceptionAsync("Xception2", "ignore", MakeTimeoutToken());
+                await client.testMultiException("Xception2", "ignore", MakeTimeoutToken());
                 Console.WriteLine("*** FAILED ***");
                 returnCode |= ErrorExceptions;
             }
@@ -1027,7 +1027,7 @@
             try
             {
                 Console.WriteLine("testMultiException(\"success\", \"OK\")");
-                if ("OK" != (await client.testMultiExceptionAsync("success", "OK", MakeTimeoutToken())).String_thing)
+                if ("OK" != (await client.testMultiException("success", "OK", MakeTimeoutToken())).String_thing)
                 {
                     Console.WriteLine("*** FAILED ***");
                     returnCode |= ErrorExceptions;
@@ -1043,7 +1043,7 @@
             Console.WriteLine("Test Oneway(1)");
             var sw = new Stopwatch();
             sw.Start();
-            await client.testOnewayAsync(1, MakeTimeoutToken());
+            await client.testOneway(1, MakeTimeoutToken());
             sw.Stop();
             if (sw.ElapsedMilliseconds > 1000)
             {
@@ -1057,7 +1057,7 @@
             sw.Start();
             var token = MakeTimeoutToken(20000);
             for (var k = 0; k < times; ++k)
-                await client.testVoidAsync(token);
+                await client.testVoid(token);
             sw.Stop();
             Console.WriteLine(" = {0} ms a testVoid() call", sw.ElapsedMilliseconds / times);
             return returnCode;
diff --git a/test/netstd/Server/Program.cs b/test/netstd/Server/Program.cs
index 8414b48..8f1f36d 100644
--- a/test/netstd/Server/Program.cs
+++ b/test/netstd/Server/Program.cs
@@ -18,6 +18,7 @@
 using System;
 using System.Linq;
 using System.Collections.Generic;
+using System.Runtime.InteropServices;
 using ThriftTest;
 
 namespace Server
@@ -26,13 +27,16 @@
     {
         public static int Main(string[] args)
         {
-            try
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
             {
-                Console.SetBufferSize(Console.BufferWidth, 4096);
-            }
-            catch (Exception)
-            {
-                Console.WriteLine("Failed to grow scroll-back buffer");
+                try
+                {
+                    Console.SetBufferSize(Console.BufferWidth, 4096);
+                }
+                catch (Exception)
+                {
+                    Console.WriteLine("Failed to grow scroll-back buffer");
+                }
             }
 
             // run whatever mode is choosen, default to test impl
@@ -62,5 +66,3 @@
         }
     }
 }
-
-
diff --git a/test/netstd/Server/Server.csproj b/test/netstd/Server/Server.csproj
index fa5ce46..e2ec93c 100644
--- a/test/netstd/Server/Server.csproj
+++ b/test/netstd/Server/Server.csproj
@@ -19,10 +19,12 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
+    <LangVersion>9.0</LangVersion>
     <AssemblyName>Server</AssemblyName>
     <PackageId>Server</PackageId>
     <OutputType>Exe</OutputType>
+    <Version>0.15.0.0</Version>
     <GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
     <GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
@@ -32,10 +34,10 @@
   </PropertyGroup>
   <ItemGroup>
     <PackageReference Include="System.IO.Pipes" Version="4.3.0" />
-    <PackageReference Include="System.IO.Pipes.AccessControl" Version="4.5.1" />
-    <PackageReference Include="System.Net.Http.WinHttpHandler" Version="4.7.0" />
+    <PackageReference Include="System.IO.Pipes.AccessControl" Version="5.0.0" />
+    <PackageReference Include="System.Net.Http.WinHttpHandler" Version="5.0.0" />
     <PackageReference Include="System.Runtime.Serialization.Primitives" Version="[4.3,)" />
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="4.8.1" />
     <PackageReference Include="System.Threading" Version="[4.3,)" />
   </ItemGroup>
   <ItemGroup>
diff --git a/test/netstd/Server/TestServer.cs b/test/netstd/Server/TestServer.cs
index 5c99099..471d6c8 100644
--- a/test/netstd/Server/TestServer.cs
+++ b/test/netstd/Server/TestServer.cs
@@ -35,6 +35,7 @@
 using Thrift.Transport.Server;
 
 #pragma warning disable IDE0063  // using can be simplified, we don't
+#pragma warning disable IDE0057  // substr can be simplified, we don't
 
 namespace ThriftTest
 {
@@ -59,11 +60,19 @@
         Framed
     }
 
+    internal enum ServerChoice
+    {
+        Simple,
+        ThreadPool
+    }
+
+
     internal class ServerParam
     {
         internal BufferChoice buffering = BufferChoice.None;
         internal ProtocolChoice protocol = ProtocolChoice.Binary;
         internal TransportChoice transport = TransportChoice.Socket;
+        internal ServerChoice server = ServerChoice.Simple;
         internal int port = 9090;
         internal string pipe = null;
 
@@ -102,13 +111,17 @@
                 {
                     protocol = ProtocolChoice.Json;
                 }
+                else if (args[i] == "--server-type=simple")
+                {
+                    server = ServerChoice.Simple;
+                }
                 else if (args[i] == "--threaded" || args[i] == "--server-type=threaded")
                 {
                     throw new NotImplementedException(args[i]);
                 }
                 else if (args[i] == "--threadpool" || args[i] == "--server-type=threadpool")
                 {
-                    throw new NotImplementedException(args[i]);
+                    server = ServerChoice.ThreadPool;
                 }
                 else if (args[i] == "--prototype" || args[i] == "--processor=prototype")
                 {
@@ -149,7 +162,10 @@
 
     public class TestServer
     {
-        public static int _clientID = -1;
+        #pragma warning disable CA2211
+        public static int _clientID = -1;  // use with Interlocked only!
+        #pragma warning restore CA2211
+
         private static readonly TConfiguration Configuration = null;  // or new TConfiguration() if needed
 
         public delegate void TestLogDelegate(string msg, params object[] values);
@@ -187,7 +203,7 @@
         {
             public TServer Server { get; set; }
             private readonly int handlerID;
-            private readonly StringBuilder sb = new StringBuilder();
+            private readonly StringBuilder sb = new();
             private readonly TestLogDelegate logger;
 
             public TestHandlerAsync()
@@ -206,61 +222,61 @@
                 Console.Write(sb.ToString());
             }
 
-            public Task testVoidAsync(CancellationToken cancellationToken)
+            public Task testVoid(CancellationToken cancellationToken)
             {
                 logger.Invoke("testVoid()");
                 return Task.CompletedTask;
             }
 
-            public Task<string> testStringAsync(string thing, CancellationToken cancellationToken)
+            public Task<string> testString(string thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testString({0})", thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<bool> testBoolAsync(bool thing, CancellationToken cancellationToken)
+            public Task<bool> testBool(bool thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testBool({0})", thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<sbyte> testByteAsync(sbyte thing, CancellationToken cancellationToken)
+            public Task<sbyte> testByte(sbyte thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testByte({0})", thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<int> testI32Async(int thing, CancellationToken cancellationToken)
+            public Task<int> testI32(int thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testI32({0})", thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<long> testI64Async(long thing, CancellationToken cancellationToken)
+            public Task<long> testI64(long thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testI64({0})", thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<double> testDoubleAsync(double thing, CancellationToken cancellationToken)
+            public Task<double> testDouble(double thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testDouble({0})", thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<byte[]> testBinaryAsync(byte[] thing, CancellationToken cancellationToken)
+            public Task<byte[]> testBinary(byte[] thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testBinary({0} bytes)", thing.Length);
                 return Task.FromResult(thing);
             }
 
-            public Task<Xtruct> testStructAsync(Xtruct thing, CancellationToken cancellationToken)
+            public Task<Xtruct> testStruct(Xtruct thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing.String_thing, thing.Byte_thing, thing.I32_thing, thing.I64_thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<Xtruct2> testNestAsync(Xtruct2 nest, CancellationToken cancellationToken)
+            public Task<Xtruct2> testNest(Xtruct2 nest, CancellationToken cancellationToken)
             {
                 var thing = nest.Struct_thing;
                 logger.Invoke("testNest({{{0}, {{\"{1}\", {2}, {3}, {4}, {5}}}}})",
@@ -273,7 +289,7 @@
                 return Task.FromResult(nest);
             }
 
-            public Task<Dictionary<int, int>> testMapAsync(Dictionary<int, int> thing, CancellationToken cancellationToken)
+            public Task<Dictionary<int, int>> testMap(Dictionary<int, int> thing, CancellationToken cancellationToken)
             {
                 sb.Clear();
                 sb.Append("testMap({{");
@@ -295,7 +311,7 @@
                 return Task.FromResult(thing);
             }
 
-            public Task<Dictionary<string, string>> testStringMapAsync(Dictionary<string, string> thing, CancellationToken cancellationToken)
+            public Task<Dictionary<string, string>> testStringMap(Dictionary<string, string> thing, CancellationToken cancellationToken)
             {
                 sb.Clear();
                 sb.Append("testStringMap({{");
@@ -317,7 +333,7 @@
                 return Task.FromResult(thing);
             }
 
-            public Task<THashSet<int>> testSetAsync(THashSet<int> thing, CancellationToken cancellationToken)
+            public Task<THashSet<int>> testSet(THashSet<int> thing, CancellationToken cancellationToken)
             {
                 sb.Clear();
                 sb.Append("testSet({{");
@@ -339,7 +355,7 @@
                 return Task.FromResult(thing);
             }
 
-            public Task<List<int>> testListAsync(List<int> thing, CancellationToken cancellationToken)
+            public Task<List<int>> testList(List<int> thing, CancellationToken cancellationToken)
             {
                 sb.Clear();
                 sb.Append("testList({{");
@@ -361,19 +377,19 @@
                 return Task.FromResult(thing);
             }
 
-            public Task<Numberz> testEnumAsync(Numberz thing, CancellationToken cancellationToken)
+            public Task<Numberz> testEnum(Numberz thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testEnum({0})", thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<long> testTypedefAsync(long thing, CancellationToken cancellationToken)
+            public Task<long> testTypedef(long thing, CancellationToken cancellationToken)
             {
                 logger.Invoke("testTypedef({0})", thing);
                 return Task.FromResult(thing);
             }
 
-            public Task<Dictionary<int, Dictionary<int, int>>> testMapMapAsync(int hello, CancellationToken cancellationToken)
+            public Task<Dictionary<int, Dictionary<int, int>>> testMapMap(int hello, CancellationToken cancellationToken)
             {
                 logger.Invoke("testMapMap({0})", hello);
                 var mapmap = new Dictionary<int, Dictionary<int, int>>();
@@ -392,7 +408,7 @@
                 return Task.FromResult(mapmap);
             }
 
-            public Task<Dictionary<long, Dictionary<Numberz, Insanity>>> testInsanityAsync(Insanity argument, CancellationToken cancellationToken)
+            public Task<Dictionary<long, Dictionary<Numberz, Insanity>>> testInsanity(Insanity argument, CancellationToken cancellationToken)
             {
                 logger.Invoke("testInsanity()");
 
@@ -425,7 +441,7 @@
                 return Task.FromResult(insane);
             }
 
-            public Task<Xtruct> testMultiAsync(sbyte arg0, int arg1, long arg2, Dictionary<short, string> arg3, Numberz arg4, long arg5,
+            public Task<Xtruct> testMulti(sbyte arg0, int arg1, long arg2, Dictionary<short, string> arg3, Numberz arg4, long arg5,
                 CancellationToken cancellationToken)
             {
                 logger.Invoke("testMulti()");
@@ -438,7 +454,7 @@
                 return Task.FromResult(hello);
             }
 
-            public Task testExceptionAsync(string arg, CancellationToken cancellationToken)
+            public Task testException(string arg, CancellationToken cancellationToken)
             {
                 logger.Invoke("testException({0})", arg);
                 if (arg == "Xception")
@@ -457,7 +473,7 @@
                 return Task.CompletedTask;
             }
 
-            public Task<Xtruct> testMultiExceptionAsync(string arg0, string arg1, CancellationToken cancellationToken)
+            public Task<Xtruct> testMultiException(string arg0, string arg1, CancellationToken cancellationToken)
             {
                 logger.Invoke("testMultiException({0}, {1})", arg0, arg1);
                 if (arg0 == "Xception")
@@ -484,7 +500,7 @@
                 return Task.FromResult(result);
             }
 
-            public Task testOnewayAsync(int secondsToSleep, CancellationToken cancellationToken)
+            public Task testOneway(int secondsToSleep, CancellationToken cancellationToken)
             {
                 logger.Invoke("testOneway({0}), sleeping...", secondsToSleep);
                 Task.Delay(secondsToSleep * 1000, cancellationToken).GetAwaiter().GetResult();
@@ -556,7 +572,7 @@
                     {
                         case TransportChoice.NamedPipe:
                             Debug.Assert(param.pipe != null);
-                            trans = new TNamedPipeServerTransport(param.pipe, Configuration);
+                            trans = new TNamedPipeServerTransport(param.pipe, Configuration, NamedPipeClientFlags.OnlyLocalClients);
                             break;
 
 
@@ -609,16 +625,23 @@
                     var testProcessor = new ThriftTest.AsyncProcessor(testHandler);
                     var processorFactory = new TSingletonProcessorFactory(testProcessor);
 
-                    TServer serverEngine = new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger);
+                    var poolconfig = new TThreadPoolAsyncServer.Configuration();  // use platform defaults
+                    TServer serverEngine = param.server switch
+                    {
+                        ServerChoice.Simple => new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger),
+                        ServerChoice.ThreadPool => new TThreadPoolAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, poolconfig, logger),
+                        _ => new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger)
+                    };
 
                     //Server event handler
                     var serverEvents = new MyServerEventHandler();
                     serverEngine.SetEventHandler(serverEvents);
 
                     // Run it
-                    var where = (!string.IsNullOrEmpty(param.pipe)) ? "on pipe " + param.pipe : "on port " + param.port;
-                    Console.WriteLine("Starting the AsyncBaseServer " + where +
-                                      " with processor TPrototypeProcessorFactory prototype factory " +
+                    var where = (!string.IsNullOrEmpty(param.pipe)) ? "pipe " + param.pipe : "port " + param.port;
+                    Console.WriteLine("Running "+ serverEngine.GetType().Name +
+                                      " at "+ where +
+                                      " using "+ processorFactory.GetType().Name + " processor prototype factory " +
                                       (param.buffering == BufferChoice.Buffered ? " with buffered transport" : "") +
                                       (param.buffering == BufferChoice.Framed ? " with framed transport" : "") +
                                       (param.transport == TransportChoice.TlsSocket ? " with encryption" : "") +
diff --git a/test/netstd/ThriftTest.sln b/test/netstd/ThriftTest.sln
index 352576e..7e101d9 100644
--- a/test/netstd/ThriftTest.sln
+++ b/test/netstd/ThriftTest.sln
@@ -1,6 +1,7 @@
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.26730.12
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30104.148
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "..\..\lib\netstd\Thrift\Thrift.csproj", "{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}"
 EndProject
@@ -8,6 +9,14 @@
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{0C6E8685-F191-4479-9842-882A38961127}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.IntegrationTests", "..\..\lib\netstd\Tests\Thrift.IntegrationTests\Thrift.IntegrationTests.csproj", "{C8148BFF-B943-4474-8D33-A641C6FD3DAB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.PublicInterfaces.Compile.Tests", "..\..\lib\netstd\Tests\Thrift.PublicInterfaces.Compile.Tests\Thrift.PublicInterfaces.Compile.Tests.csproj", "{5D86C1B6-0CDA-4D1D-80A5-240583B21148}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Tests", "..\..\lib\netstd\Tests\Thrift.Tests\Thrift.Tests.csproj", "{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift.Benchmarks", "..\..\lib\netstd\Benchmarks\Thrift.Benchmarks\Thrift.Benchmarks.csproj", "{66946544-8DE7-45E9-8D0E-93EADA028D44}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -54,6 +63,54 @@
 		{0C6E8685-F191-4479-9842-882A38961127}.Release|x64.Build.0 = Release|Any CPU
 		{0C6E8685-F191-4479-9842-882A38961127}.Release|x86.ActiveCfg = Release|Any CPU
 		{0C6E8685-F191-4479-9842-882A38961127}.Release|x86.Build.0 = Release|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|x64.Build.0 = Debug|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Debug|x86.Build.0 = Debug|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|x64.ActiveCfg = Release|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|x64.Build.0 = Release|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|x86.ActiveCfg = Release|Any CPU
+		{C8148BFF-B943-4474-8D33-A641C6FD3DAB}.Release|x86.Build.0 = Release|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|x64.Build.0 = Debug|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Debug|x86.Build.0 = Debug|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|x64.ActiveCfg = Release|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|x64.Build.0 = Release|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|x86.ActiveCfg = Release|Any CPU
+		{5D86C1B6-0CDA-4D1D-80A5-240583B21148}.Release|x86.Build.0 = Release|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|x64.Build.0 = Debug|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Debug|x86.Build.0 = Debug|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|Any CPU.Build.0 = Release|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|x64.ActiveCfg = Release|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|x64.Build.0 = Release|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|x86.ActiveCfg = Release|Any CPU
+		{37FDED71-F8FB-434B-B2A8-1C53CCD9FD38}.Release|x86.Build.0 = Release|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|x64.Build.0 = Debug|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Debug|x86.Build.0 = Debug|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|Any CPU.Build.0 = Release|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|x64.ActiveCfg = Release|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|x64.Build.0 = Release|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|x86.ActiveCfg = Release|Any CPU
+		{66946544-8DE7-45E9-8D0E-93EADA028D44}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/test/rs/Makefile.am b/test/rs/Makefile.am
index 4b061ea..78db5ee 100644
--- a/test/rs/Makefile.am
+++ b/test/rs/Makefile.am
@@ -22,6 +22,8 @@
 
 precross: stubs
 	$(CARGO) build
+	$(CARGO) fmt --all -- --check
+	$(CARGO) clippy --all -- -D warnings
 	[ -d bin ] || mkdir bin
 	cp target/debug/test_server bin/test_server
 	cp target/debug/test_client bin/test_client
diff --git a/test/rs/src/bin/test_client.rs b/test/rs/src/bin/test_client.rs
index 6cbc238..8623915 100644
--- a/test/rs/src/bin/test_client.rs
+++ b/test/rs/src/bin/test_client.rs
@@ -15,21 +15,24 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use clap::{clap_app, value_t};
 use env_logger;
 use log::*;
-use clap::{clap_app, value_t};
 
 use std::collections::{BTreeMap, BTreeSet};
 use std::fmt::Debug;
+use std::net::TcpStream;
 
 use thrift;
+use thrift::protocol::{
+    TBinaryInputProtocol, TBinaryOutputProtocol, TCompactInputProtocol, TCompactOutputProtocol,
+    TInputProtocol, TMultiplexedOutputProtocol, TOutputProtocol,
+};
+use thrift::transport::{
+    TBufferedReadTransport, TBufferedWriteTransport, TFramedReadTransport, TFramedWriteTransport,
+    TIoChannel, TReadTransport, TTcpChannel, TWriteTransport,
+};
 use thrift::OrderedFloat;
-use thrift::protocol::{TBinaryInputProtocol, TBinaryOutputProtocol, TCompactInputProtocol,
-                       TCompactOutputProtocol, TInputProtocol, TMultiplexedOutputProtocol,
-                       TOutputProtocol};
-use thrift::transport::{ReadHalf, TBufferedReadTransport, TBufferedWriteTransport,
-                        TFramedReadTransport, TFramedWriteTransport, TIoChannel, TReadTransport,
-                        TTcpChannel, TWriteTransport, WriteHalf};
 use thrift_test::*;
 
 fn main() {
@@ -71,25 +74,27 @@
     let transport = matches.value_of("transport").unwrap_or("buffered");
     let protocol = matches.value_of("protocol").unwrap_or("binary");
 
-
-    let mut thrift_test_client = {
-        let (i_prot, o_prot) = build_protocols(host, port, transport, protocol, "ThriftTest")?;
-        ThriftTestSyncClient::new(i_prot, o_prot)
-    };
+    // create a TCPStream that will be shared by all Thrift clients
+    // service calls from multiple Thrift clients will be interleaved over the same connection
+    // this isn't a problem for us because we're single-threaded and all calls block to completion
+    let shared_stream = TcpStream::connect(format!("{}:{}", host, port))?;
 
     let mut second_service_client = if protocol.starts_with("multi") {
-        let (i_prot, o_prot) = build_protocols(host, port, transport, protocol, "SecondService")?;
+        let shared_stream_clone = shared_stream.try_clone()?;
+        let (i_prot, o_prot) = build(shared_stream_clone, transport, protocol, "SecondService")?;
         Some(SecondServiceSyncClient::new(i_prot, o_prot))
     } else {
         None
     };
 
+    let mut thrift_test_client = {
+        let (i_prot, o_prot) = build(shared_stream, transport, protocol, "ThriftTest")?;
+        ThriftTestSyncClient::new(i_prot, o_prot)
+    };
+
     info!(
         "connecting to {}:{} with {}+{} stack",
-        host,
-        port,
-        protocol,
-        transport
+        host, port, protocol, transport
     );
 
     for _ in 0..testloops {
@@ -99,68 +104,60 @@
     Ok(())
 }
 
-fn build_protocols(
-    host: &str,
-    port: u16,
+fn build(
+    stream: TcpStream,
     transport: &str,
     protocol: &str,
     service_name: &str,
 ) -> thrift::Result<(Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>)> {
-    let (i_chan, o_chan) = tcp_channel(host, port)?;
+    let c = TTcpChannel::with_stream(stream);
+    let (i_chan, o_chan) = c.split()?;
 
     let (i_tran, o_tran): (Box<dyn TReadTransport>, Box<dyn TWriteTransport>) = match transport {
-        "buffered" => {
-            (Box::new(TBufferedReadTransport::new(i_chan)),
-             Box::new(TBufferedWriteTransport::new(o_chan)))
-        }
-        "framed" => {
-            (Box::new(TFramedReadTransport::new(i_chan)),
-             Box::new(TFramedWriteTransport::new(o_chan)))
-        }
+        "buffered" => (
+            Box::new(TBufferedReadTransport::new(i_chan)),
+            Box::new(TBufferedWriteTransport::new(o_chan)),
+        ),
+        "framed" => (
+            Box::new(TFramedReadTransport::new(i_chan)),
+            Box::new(TFramedWriteTransport::new(o_chan)),
+        ),
         unmatched => return Err(format!("unsupported transport {}", unmatched).into()),
     };
 
     let (i_prot, o_prot): (Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>) = match protocol {
-        "binary" => {
-            (Box::new(TBinaryInputProtocol::new(i_tran, true)),
-             Box::new(TBinaryOutputProtocol::new(o_tran, true)))
-        }
-        "multi" => {
-            (Box::new(TBinaryInputProtocol::new(i_tran, true)),
-             Box::new(
-                TMultiplexedOutputProtocol::new(
-                    service_name,
-                    TBinaryOutputProtocol::new(o_tran, true),
-                ),
-            ))
-        }
-        "compact" => {
-            (Box::new(TCompactInputProtocol::new(i_tran)),
-             Box::new(TCompactOutputProtocol::new(o_tran)))
-        }
-        "multic" => {
-            (Box::new(TCompactInputProtocol::new(i_tran)),
-             Box::new(TMultiplexedOutputProtocol::new(service_name, TCompactOutputProtocol::new(o_tran)),))
-        }
+        "binary" => (
+            Box::new(TBinaryInputProtocol::new(i_tran, true)),
+            Box::new(TBinaryOutputProtocol::new(o_tran, true)),
+        ),
+        "multi" => (
+            Box::new(TBinaryInputProtocol::new(i_tran, true)),
+            Box::new(TMultiplexedOutputProtocol::new(
+                service_name,
+                TBinaryOutputProtocol::new(o_tran, true),
+            )),
+        ),
+        "compact" => (
+            Box::new(TCompactInputProtocol::new(i_tran)),
+            Box::new(TCompactOutputProtocol::new(o_tran)),
+        ),
+        "multic" => (
+            Box::new(TCompactInputProtocol::new(i_tran)),
+            Box::new(TMultiplexedOutputProtocol::new(
+                service_name,
+                TCompactOutputProtocol::new(o_tran),
+            )),
+        ),
         unmatched => return Err(format!("unsupported protocol {}", unmatched).into()),
     };
 
     Ok((i_prot, o_prot))
 }
 
-// FIXME: expose "open" through the client interface so I don't have to early
-// open
-fn tcp_channel(
-    host: &str,
-    port: u16,
-) -> thrift::Result<(ReadHalf<TTcpChannel>, WriteHalf<TTcpChannel>)> {
-    let mut c = TTcpChannel::new();
-    c.open(&format!("{}:{}", host, port))?;
-    c.split()
-}
-
-type BuildThriftTestClient = ThriftTestSyncClient<Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>>;
-type BuiltSecondServiceClient = SecondServiceSyncClient<Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>>;
+type BuildThriftTestClient =
+    ThriftTestSyncClient<Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>>;
+type BuiltSecondServiceClient =
+    SecondServiceSyncClient<Box<dyn TInputProtocol>, Box<dyn TOutputProtocol>>;
 
 #[allow(clippy::cognitive_complexity)]
 fn make_thrift_calls(
@@ -211,7 +208,7 @@
 
     info!("testEnum");
     {
-        verify_expected_result(thrift_test_client.test_enum(Numberz::Two), Numberz::Two)?;
+        verify_expected_result(thrift_test_client.test_enum(Numberz::TWO), Numberz::TWO)?;
     }
 
     info!("testBinary");
@@ -255,26 +252,22 @@
     {
         let x_snd = Xtruct2 {
             byte_thing: Some(32),
-            struct_thing: Some(
-                Xtruct {
-                    string_thing: Some("foo".to_owned()),
-                    byte_thing: Some(1),
-                    i32_thing: Some(324_382_098),
-                    i64_thing: Some(12_938_492_818),
-                },
-            ),
+            struct_thing: Some(Xtruct {
+                string_thing: Some("foo".to_owned()),
+                byte_thing: Some(1),
+                i32_thing: Some(324_382_098),
+                i64_thing: Some(12_938_492_818),
+            }),
             i32_thing: Some(293_481_098),
         };
         let x_cmp = Xtruct2 {
             byte_thing: Some(32),
-            struct_thing: Some(
-                Xtruct {
-                    string_thing: Some("foo".to_owned()),
-                    byte_thing: Some(1),
-                    i32_thing: Some(324_382_098),
-                    i64_thing: Some(12_938_492_818),
-                },
-            ),
+            struct_thing: Some(Xtruct {
+                string_thing: Some("foo".to_owned()),
+                byte_thing: Some(1),
+                i32_thing: Some(324_382_098),
+                i64_thing: Some(12_938_492_818),
+            }),
             i32_thing: Some(293_481_098),
         };
         verify_expected_result(thrift_test_client.test_nest(x_snd), x_cmp)?;
@@ -386,7 +379,7 @@
         };
 
         verify_expected_result(
-            thrift_test_client.test_multi(1, -123_948, -19_234_123_981, m_snd, Numberz::Eight, 81),
+            thrift_test_client.test_multi(1, -123_948, -19_234_123_981, m_snd, Numberz::EIGHT, 81),
             s_cmp,
         )?;
     }
@@ -400,49 +393,43 @@
     // }
     {
         let mut arg_map_usermap: BTreeMap<Numberz, i64> = BTreeMap::new();
-        arg_map_usermap.insert(Numberz::One, 4289);
-        arg_map_usermap.insert(Numberz::Eight, 19);
+        arg_map_usermap.insert(Numberz::ONE, 4289);
+        arg_map_usermap.insert(Numberz::EIGHT, 19);
 
         let mut arg_vec_xtructs: Vec<Xtruct> = Vec::new();
-        arg_vec_xtructs.push(
-            Xtruct {
-                string_thing: Some("foo".to_owned()),
-                byte_thing: Some(8),
-                i32_thing: Some(29),
-                i64_thing: Some(92384),
-            },
-        );
-        arg_vec_xtructs.push(
-            Xtruct {
-                string_thing: Some("bar".to_owned()),
-                byte_thing: Some(28),
-                i32_thing: Some(2),
-                i64_thing: Some(-1281),
-            },
-        );
-        arg_vec_xtructs.push(
-            Xtruct {
-                string_thing: Some("baz".to_owned()),
-                byte_thing: Some(0),
-                i32_thing: Some(3_948_539),
-                i64_thing: Some(-12_938_492),
-            },
-        );
+        arg_vec_xtructs.push(Xtruct {
+            string_thing: Some("foo".to_owned()),
+            byte_thing: Some(8),
+            i32_thing: Some(29),
+            i64_thing: Some(92384),
+        });
+        arg_vec_xtructs.push(Xtruct {
+            string_thing: Some("bar".to_owned()),
+            byte_thing: Some(28),
+            i32_thing: Some(2),
+            i64_thing: Some(-1281),
+        });
+        arg_vec_xtructs.push(Xtruct {
+            string_thing: Some("baz".to_owned()),
+            byte_thing: Some(0),
+            i32_thing: Some(3_948_539),
+            i64_thing: Some(-12_938_492),
+        });
 
         let mut s_cmp_nested_1: BTreeMap<Numberz, Insanity> = BTreeMap::new();
         let insanity = Insanity {
             user_map: Some(arg_map_usermap),
             xtructs: Some(arg_vec_xtructs),
         };
-        s_cmp_nested_1.insert(Numberz::Two, insanity.clone());
-        s_cmp_nested_1.insert(Numberz::Three, insanity.clone());
+        s_cmp_nested_1.insert(Numberz::TWO, insanity.clone());
+        s_cmp_nested_1.insert(Numberz::THREE, insanity.clone());
 
         let mut s_cmp_nested_2: BTreeMap<Numberz, Insanity> = BTreeMap::new();
         let empty_insanity = Insanity {
             user_map: Some(BTreeMap::new()),
             xtructs: Some(Vec::new()),
         };
-        s_cmp_nested_2.insert(Numberz::Six, empty_insanity);
+        s_cmp_nested_2.insert(Numberz::SIX, empty_insanity);
 
         let mut s_cmp: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
         s_cmp.insert(1 as UserId, s_cmp_nested_1);
@@ -455,12 +442,12 @@
     {
         let r = thrift_test_client.test_exception("Xception".to_owned());
         let x = match r {
-            Err(thrift::Error::User(ref e)) => {
-                match e.downcast_ref::<Xception>() {
-                    Some(x) => Ok(x),
-                    None => Err(thrift::Error::User("did not get expected Xception struct".into()),),
-                }
-            }
+            Err(thrift::Error::User(ref e)) => match e.downcast_ref::<Xception>() {
+                Some(x) => Ok(x),
+                None => Err(thrift::Error::User(
+                    "did not get expected Xception struct".into(),
+                )),
+            },
             _ => Err(thrift::Error::User("did not get exception".into())),
         }?;
 
@@ -498,12 +485,12 @@
         let r =
             thrift_test_client.test_multi_exception("Xception".to_owned(), "ignored".to_owned());
         let x = match r {
-            Err(thrift::Error::User(ref e)) => {
-                match e.downcast_ref::<Xception>() {
-                    Some(x) => Ok(x),
-                    None => Err(thrift::Error::User("did not get expected Xception struct".into()),),
-                }
-            }
+            Err(thrift::Error::User(ref e)) => match e.downcast_ref::<Xception>() {
+                Some(x) => Ok(x),
+                None => Err(thrift::Error::User(
+                    "did not get expected Xception struct".into(),
+                )),
+            },
             _ => Err(thrift::Error::User("did not get exception".into())),
         }?;
 
@@ -520,28 +507,26 @@
         let r =
             thrift_test_client.test_multi_exception("Xception2".to_owned(), "ignored".to_owned());
         let x = match r {
-            Err(thrift::Error::User(ref e)) => {
-                match e.downcast_ref::<Xception2>() {
-                    Some(x) => Ok(x),
-                    None => Err(thrift::Error::User("did not get expected Xception struct".into()),),
-                }
-            }
+            Err(thrift::Error::User(ref e)) => match e.downcast_ref::<Xception2>() {
+                Some(x) => Ok(x),
+                None => Err(thrift::Error::User(
+                    "did not get expected Xception struct".into(),
+                )),
+            },
             _ => Err(thrift::Error::User("did not get exception".into())),
         }?;
 
         let x_cmp = Xception2 {
             error_code: Some(2002),
-            struct_thing: Some(
-                Xtruct {
-                    string_thing: Some("This is an Xception2".to_owned()),
-                    // since this is an OPT_IN_REQ_OUT field the sender sets a default
-                    byte_thing: Some(0),
-                    // since this is an OPT_IN_REQ_OUT field the sender sets a default
-                    i32_thing: Some(0),
-                    // since this is an OPT_IN_REQ_OUT field the sender sets a default
-                    i64_thing: Some(0),
-                },
-            ),
+            struct_thing: Some(Xtruct {
+                string_thing: Some("This is an Xception2".to_owned()),
+                // since this is an OPT_IN_REQ_OUT field the sender sets a default
+                byte_thing: Some(0),
+                // since this is an OPT_IN_REQ_OUT field the sender sets a default
+                i32_thing: Some(0),
+                // since this is an OPT_IN_REQ_OUT field the sender sets a default
+                i64_thing: Some(0),
+            }),
         };
 
         verify_expected_result(Ok(x), &x_cmp)?;
@@ -551,7 +536,9 @@
     {
         let r = thrift_test_client.test_multi_exception("haha".to_owned(), "RETURNED".to_owned());
         let x = match r {
-            Err(e) => Err(thrift::Error::User(format!("received an unexpected exception {:?}", e).into(),),),
+            Err(e) => Err(thrift::Error::User(
+                format!("received an unexpected exception {:?}", e).into(),
+            )),
             _ => r,
         }?;
 
@@ -591,7 +578,9 @@
                 Ok(())
             } else {
                 info!("*** FAILED ***");
-                Err(thrift::Error::User(format!("expected {:?} but got {:?}", &expected, &v).into()),)
+                Err(thrift::Error::User(
+                    format!("expected {:?} but got {:?}", &expected, &v).into(),
+                ))
             }
         }
         Err(e) => Err(e),
diff --git a/test/rs/src/bin/test_server.rs b/test/rs/src/bin/test_server.rs
index 74be12d..6a05e79 100644
--- a/test/rs/src/bin/test_server.rs
+++ b/test/rs/src/bin/test_server.rs
@@ -15,23 +15,25 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use clap::{clap_app, value_t};
 use env_logger;
 use log::*;
-use clap::{clap_app, value_t};
 
 use std::collections::{BTreeMap, BTreeSet};
 use std::thread;
 use std::time::Duration;
 
 use thrift;
-use thrift::OrderedFloat;
-use thrift::protocol::{TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory,
-                       TCompactInputProtocolFactory, TCompactOutputProtocolFactory,
-                       TInputProtocolFactory, TOutputProtocolFactory};
+use thrift::protocol::{
+    TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory, TCompactInputProtocolFactory,
+    TCompactOutputProtocolFactory, TInputProtocolFactory, TOutputProtocolFactory,
+};
 use thrift::server::{TMultiplexedProcessor, TServer};
-use thrift::transport::{TBufferedReadTransportFactory, TBufferedWriteTransportFactory,
-                        TFramedReadTransportFactory, TFramedWriteTransportFactory,
-                        TReadTransportFactory, TWriteTransportFactory};
+use thrift::transport::{
+    TBufferedReadTransportFactory, TBufferedWriteTransportFactory, TFramedReadTransportFactory,
+    TFramedWriteTransportFactory, TReadTransportFactory, TWriteTransportFactory,
+};
+use thrift::OrderedFloat;
 use thrift_test::*;
 
 fn main() {
@@ -49,7 +51,6 @@
 }
 
 fn run() -> thrift::Result<()> {
-
     // unsupported options:
     // --domain-socket
     // --pipe
@@ -75,50 +76,55 @@
 
     info!("binding to {}", listen_address);
 
-    let (i_transport_factory, o_transport_factory): (Box<dyn TReadTransportFactory>,
-                                                     Box<dyn TWriteTransportFactory>) =
-        match &*transport {
-            "buffered" => {
-                (Box::new(TBufferedReadTransportFactory::new()),
-                 Box::new(TBufferedWriteTransportFactory::new()))
-            }
-            "framed" => {
-                (Box::new(TFramedReadTransportFactory::new()),
-                 Box::new(TFramedWriteTransportFactory::new()))
-            }
-            unknown => {
-                return Err(format!("unsupported transport type {}", unknown).into());
-            }
-        };
+    let (i_transport_factory, o_transport_factory): (
+        Box<dyn TReadTransportFactory>,
+        Box<dyn TWriteTransportFactory>,
+    ) = match &*transport {
+        "buffered" => (
+            Box::new(TBufferedReadTransportFactory::new()),
+            Box::new(TBufferedWriteTransportFactory::new()),
+        ),
+        "framed" => (
+            Box::new(TFramedReadTransportFactory::new()),
+            Box::new(TFramedWriteTransportFactory::new()),
+        ),
+        unknown => {
+            return Err(format!("unsupported transport type {}", unknown).into());
+        }
+    };
 
-    let (i_protocol_factory, o_protocol_factory): (Box<dyn TInputProtocolFactory>,
-                                                   Box<dyn TOutputProtocolFactory>) =
-        match &*protocol {
-            "binary" | "multi" | "multi:binary" => {
-                (Box::new(TBinaryInputProtocolFactory::new()),
-                 Box::new(TBinaryOutputProtocolFactory::new()))
-            }
-            "compact" | "multic" | "multi:compact" => {
-                (Box::new(TCompactInputProtocolFactory::new()),
-                 Box::new(TCompactOutputProtocolFactory::new()))
-            }
-            unknown => {
-                return Err(format!("unsupported transport type {}", unknown).into());
-            }
-        };
+    let (i_protocol_factory, o_protocol_factory): (
+        Box<dyn TInputProtocolFactory>,
+        Box<dyn TOutputProtocolFactory>,
+    ) = match &*protocol {
+        "binary" | "multi" | "multi:binary" => (
+            Box::new(TBinaryInputProtocolFactory::new()),
+            Box::new(TBinaryOutputProtocolFactory::new()),
+        ),
+        "compact" | "multic" | "multi:compact" => (
+            Box::new(TCompactInputProtocolFactory::new()),
+            Box::new(TCompactOutputProtocolFactory::new()),
+        ),
+        unknown => {
+            return Err(format!("unsupported transport type {}", unknown).into());
+        }
+    };
 
     let test_processor = ThriftTestSyncProcessor::new(ThriftTestSyncHandlerImpl {});
 
     match &*server_type {
         "simple" | "thread-pool" => {
             if protocol == "multi" || protocol == "multic" {
-                let second_service_processor = SecondServiceSyncProcessor::new(SecondServiceSyncHandlerImpl {},);
+                let second_service_processor =
+                    SecondServiceSyncProcessor::new(SecondServiceSyncHandlerImpl {});
 
                 let mut multiplexed_processor = TMultiplexedProcessor::new();
-                multiplexed_processor
-                    .register("ThriftTest", Box::new(test_processor), true)?;
-                multiplexed_processor
-                    .register("SecondService", Box::new(second_service_processor), false)?;
+                multiplexed_processor.register("ThriftTest", Box::new(test_processor), true)?;
+                multiplexed_processor.register(
+                    "SecondService",
+                    Box::new(second_service_processor),
+                    false,
+                )?;
 
                 let mut server = TServer::new(
                     i_transport_factory,
@@ -268,15 +274,15 @@
     ) -> thrift::Result<BTreeMap<UserId, BTreeMap<Numberz, Insanity>>> {
         info!("testInsanity({:?})", argument);
         let mut map_0: BTreeMap<Numberz, Insanity> = BTreeMap::new();
-        map_0.insert(Numberz::Two, argument.clone());
-        map_0.insert(Numberz::Three, argument);
+        map_0.insert(Numberz::TWO, argument.clone());
+        map_0.insert(Numberz::THREE, argument);
 
         let mut map_1: BTreeMap<Numberz, Insanity> = BTreeMap::new();
         let insanity = Insanity {
             user_map: None,
             xtructs: None,
         };
-        map_1.insert(Numberz::Six, insanity);
+        map_1.insert(Numberz::SIX, insanity);
 
         let mut ret: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
         ret.insert(1, map_0);
@@ -315,15 +321,11 @@
         info!("testException({})", arg);
 
         match &*arg {
-            "Xception" => {
-                Err(
-                    (Xception {
-                             error_code: Some(1001),
-                             message: Some(arg),
-                         })
-                        .into(),
-                )
-            }
+            "Xception" => Err((Xception {
+                error_code: Some(1001),
+                message: Some(arg),
+            })
+            .into()),
             "TException" => Err("this is a random error".into()),
             _ => Ok(()),
         }
@@ -339,41 +341,27 @@
     //   do not throw anything and return Xtruct with string_thing = arg1
     fn handle_test_multi_exception(&self, arg0: String, arg1: String) -> thrift::Result<Xtruct> {
         match &*arg0 {
-            "Xception" => {
-                Err(
-                    (Xception {
-                             error_code: Some(1001),
-                             message: Some("This is an Xception".to_owned()),
-                         })
-                        .into(),
-                )
-            }
-            "Xception2" => {
-                Err(
-                    (Xception2 {
-                             error_code: Some(2002),
-                             struct_thing: Some(
-                            Xtruct {
-                                string_thing: Some("This is an Xception2".to_owned()),
-                                byte_thing: None,
-                                i32_thing: None,
-                                i64_thing: None,
-                            },
-                        ),
-                         })
-                        .into(),
-                )
-            }
-            _ => {
-                Ok(
-                    Xtruct {
-                        string_thing: Some(arg1),
-                        byte_thing: None,
-                        i32_thing: None,
-                        i64_thing: None,
-                    },
-                )
-            }
+            "Xception" => Err((Xception {
+                error_code: Some(1001),
+                message: Some("This is an Xception".to_owned()),
+            })
+            .into()),
+            "Xception2" => Err((Xception2 {
+                error_code: Some(2002),
+                struct_thing: Some(Xtruct {
+                    string_thing: Some("This is an Xception2".to_owned()),
+                    byte_thing: None,
+                    i32_thing: None,
+                    i64_thing: None,
+                }),
+            })
+            .into()),
+            _ => Ok(Xtruct {
+                string_thing: Some(arg1),
+                byte_thing: None,
+                i32_thing: None,
+                i64_thing: None,
+            }),
         }
     }
 
diff --git a/tutorial/Makefile.am b/tutorial/Makefile.am
index 484b485..ba445e0 100755
--- a/tutorial/Makefile.am
+++ b/tutorial/Makefile.am
@@ -50,10 +50,6 @@
 SUBDIRS += rb
 endif
 
-if WITH_HASKELL
-SUBDIRS += hs
-endif
-
 if WITH_HAXE
 SUBDIRS += haxe
 endif
@@ -104,11 +100,9 @@
 # Any folders or files not listed above being added to SUBDIR need to be placed here in
 # EXTRA_DIST to be included in the release
 EXTRA_DIST = \
-	as3 \
 	d \
 	delphi \
 	erl \
-	hs \
 	ocaml \
 	shared.thrift \
 	tutorial.thrift \
diff --git a/tutorial/as3/build.xml b/tutorial/as3/build.xml
deleted file mode 100644
index f7ed32d..0000000
--- a/tutorial/as3/build.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<project name="tutorial" default="dist" basedir=".">
-
-  <description>Thrift actionscript 3.0 tutorial.</description>
-
-  <property name="gen" location="gen-as3" />
-  <property name="src" location="src" />
-  <property name="thrift.src" location="../../lib/as3/src/" />
-  <property name="dist" location="dist" />
-
-  <property name="final.name" value="as3-tutorial" />
-  <property name="swf.name" value="${dist}/${final.name}.swf" />
-
-  <target name="flex.check" unless="FLEX_HOME">
-    <fail message='You must set the FLEX_HOME property pointing to your flex SDK, eg. ant -DFLEX_HOME="/Applications/Adobe Flex Builder 3/sdks/3.2.0"'/>
-  </target>
-
-  <target name="flex.init" depends="flex.check" unless="flex.finished">
-    <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
-    <property name="flex.finished" value="true"/>
-  </target>
-
-  <target name="init">
-    <tstamp />
-    <mkdir dir="${dist}"/>
-  </target>
-
-  <target name="dist" depends="generate, flex.init, init">
-    <mxmlc output="${swf.name}" file="${src}/CalculatorUI.as">
-      <source-path path-element="${gen}" />
-      <source-path path-element="${src}" />
-      <source-path path-element="${thrift.src}" />
-    </mxmlc>
-  </target>
-
-  <target name="generate">
-    <!-- Generate the thrift gen-java source -->
-    <exec executable="../../compiler/cpp/thrift" failonerror="true">
-      <arg line="--gen as3 ../shared.thrift"/>
-    </exec>
-    <exec executable="../../compiler/cpp/thrift" failonerror="true">
-      <arg line="--gen as3 ../tutorial.thrift"/>
-    </exec>
-  </target>
-
-  <target name="clean">
-    <delete dir="${gen}"/>
-    <delete dir="${dist}" />
-  </target>
-
-</project>
diff --git a/tutorial/as3/src/CalculatorUI.as b/tutorial/as3/src/CalculatorUI.as
deleted file mode 100644
index d996df5..0000000
--- a/tutorial/as3/src/CalculatorUI.as
+++ /dev/null
@@ -1,142 +0,0 @@
-package {
-  import flash.display.Sprite;
-  import flash.text.TextField;
-  import flash.text.TextFieldType;
-  import flash.events.MouseEvent;
-  import flash.system.Security;
-
-  import org.apache.thrift.transport.TSocket;
-  import org.apache.thrift.transport.TTransport;
-  import org.apache.thrift.protocol.TProtocol;
-  import org.apache.thrift.protocol.TBinaryProtocol;
-
-  /**
-   * Simple interface and connection logic implementation for tutorial.
-   */
-  public class CalculatorUI extends Sprite {
-    public static const BUTTON_PADDING:uint = 5;
-
-    private var mCalculatorClient:Calculator; // we use calculator through interface
-    private var mTransport:TTransport; // Transport, used to comunicate with server
-
-    private var mAddButton:Sprite;
-    private var mLeft:TextField;
-    private var mRight:TextField;
-    private var mResult:TextField;
-
-    private var pingButton:Sprite;
-
-    public function CalculatorUI() {
-      buildInterface();
-      initSecurity();
-      initConnection();
-    }
-
-    private function initSecurity():void {
-      Security.loadPolicyFile("xmlsocket://127.0.0.1:9092");
-    }
-
-    /**
-     * Example of initializing connection.
-     */
-    private function initConnection():void {
-      mTransport = new TSocket("127.0.0.1", 9090); // we connect to server
-      mTransport.open();
-      // initialize protocol:
-      var protocol:TProtocol = new TBinaryProtocol(mTransport, false, false);
-      mCalculatorClient = new CalculatorImpl(protocol); // finally, we create calculator client instance
-    }
-
-    private function onPingClick(me:MouseEvent):void {
-      if(!mTransport.isOpen()) return;
-      mCalculatorClient.ping(onPingError, onPingSuccess);
-    }
-
-    private function onPingError(error:Error):void {
-      trace("Error, while requesting ping.");
-      throw error;
-    }
-
-    private function onPingSuccess():void {
-      trace("Ping returned successfully");
-    }
-
-    private function onAddClick(me:MouseEvent):void {
-      if(!mTransport.isOpen()) return;
-      var num1:Number = Number(mLeft.text);
-      var num2:Number = Number(mRight.text);
-      mResult.text = "Processing...";
-      mCalculatorClient.add(num1, num2, onAddError, onAddSuccess);
-    }
-
-    private function onAddError(error:Error):void {
-      trace("Error, while requesting add.");
-      throw error;
-    }
-
-    private function onAddSuccess(res:Number):void {
-      mResult.text = String(res);
-    }
-
-    private function buildInterface():void {
-      addChild(pingButton = buildButton("PING"));
-      pingButton.x = (stage.stageWidth - pingButton.width) / 2;
-      pingButton.y = 10;
-      pingButton.addEventListener(MouseEvent.CLICK, onPingClick);
-
-      var top:Number = pingButton.y + pingButton.height + 20;
-      addChild(mLeft = buildDigitInput());
-      mLeft.x = 15;
-      mLeft.y = top + BUTTON_PADDING;
-      addChild(mRight = buildDigitInput());
-      mRight.x = mLeft.x + mLeft.width + 15;
-      mRight.y = top + BUTTON_PADDING;
-      addChild(mAddButton = buildButton("ADD"));
-      mAddButton.x = mRight.x + mRight.width + 15;
-      mAddButton.y = top;
-      mAddButton.addEventListener(MouseEvent.CLICK, onAddClick);
-      addChild(mResult = buildDigitInput());
-      mResult.x = mAddButton.x + mAddButton.width + 15;
-      mResult.y = top + BUTTON_PADDING;
-    }
-
-    /**
-     * Simple digit-only input field.
-     */
-    private function buildDigitInput():TextField {
-      var textField:TextField = new TextField;
-      textField.width = 75;
-      textField.height = 20;
-      textField.restrict = "0987654321.";
-      textField.type = TextFieldType.INPUT;
-      textField.background = true;
-      textField.backgroundColor = 0xaaaaff;
-      textField.textColor = 0xffff00;
-      return textField;
-    }
-
-    /**
-     * Simple button drawing.
-     */
-    private function buildButton(text:String):Sprite {
-      var button:Sprite = new Sprite;
-      var textField:TextField = new TextField;
-      textField.width = 4000;
-      textField.text = text;
-      textField.textColor = 0xffff00;
-      textField.width = textField.textWidth + 4;
-      textField.height = textField.textHeight + 4;
-      textField.mouseEnabled = false;
-      button.graphics.beginFill(0x0000ff);
-      button.graphics.lineStyle(0, 0x000000);
-      button.graphics.drawRoundRect(0, 0, textField.width + BUTTON_PADDING * 2,
-                                    textField.height + BUTTON_PADDING * 2, BUTTON_PADDING);
-      button.graphics.endFill();
-      button.addChild(textField);
-      textField.x = BUTTON_PADDING;
-      textField.y = BUTTON_PADDING;
-      button.useHandCursor = button.buttonMode = true;
-      return button;
-    }
-  }
-}
diff --git a/tutorial/dart/Makefile.am b/tutorial/dart/Makefile.am
index 0b93ac8..860f292 100644
--- a/tutorial/dart/Makefile.am
+++ b/tutorial/dart/Makefile.am
@@ -75,7 +75,4 @@
 	console_client/pubspec.yaml \
 	server/bin/main.dart \
 	server/pubspec.yaml \
-	console_client/.analysis_options \
-	client/.analysis_options \
-	server/.analysis_options \
 	build.sh
diff --git a/tutorial/dart/client/.analysis_options b/tutorial/dart/client/.analysis_options
deleted file mode 100644
index a10d4c5..0000000
--- a/tutorial/dart/client/.analysis_options
+++ /dev/null
@@ -1,2 +0,0 @@
-analyzer:
-  strong-mode: true
diff --git a/tutorial/dart/client/pubspec.yaml b/tutorial/dart/client/pubspec.yaml
index d047457..bf36aed 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.14.2
+version: 0.15.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/.analysis_options b/tutorial/dart/console_client/.analysis_options
deleted file mode 100644
index a10d4c5..0000000
--- a/tutorial/dart/console_client/.analysis_options
+++ /dev/null
@@ -1,2 +0,0 @@
-analyzer:
-  strong-mode: true
diff --git a/tutorial/dart/console_client/pubspec.yaml b/tutorial/dart/console_client/pubspec.yaml
index 41dcb30..c662e89 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.14.2
+version: 0.15.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/.analysis_options b/tutorial/dart/server/.analysis_options
deleted file mode 100644
index a10d4c5..0000000
--- a/tutorial/dart/server/.analysis_options
+++ /dev/null
@@ -1,2 +0,0 @@
-analyzer:
-  strong-mode: true
diff --git a/tutorial/dart/server/pubspec.yaml b/tutorial/dart/server/pubspec.yaml
index f1dd1a1..81c482c 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.14.2
+version: 0.15.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.dpr b/tutorial/delphi/DelphiClient/DelphiClient.dpr
index 64d7d68..e44ae3b 100644
--- a/tutorial/delphi/DelphiClient/DelphiClient.dpr
+++ b/tutorial/delphi/DelphiClient/DelphiClient.dpr
@@ -36,8 +36,8 @@
   Thrift.Transport.WinHTTP in '..\..\..\lib\delphi\src\Thrift.Transport.WinHTTP.pas',
   Thrift.Transport.MsxmlHTTP in '..\..\..\lib\delphi\src\Thrift.Transport.MsxmlHTTP.pas',
   Thrift.WinHTTP in '..\..\..\lib\delphi\src\Thrift.WinHTTP.pas',
-  Shared in '..\..\gen-delphi\Shared.pas',
-  Tutorial in '..\..\gen-delphi\Tutorial.pas';
+  Shared in '..\gen-delphi\Shared.pas',
+  Tutorial in '..\gen-delphi\Tutorial.pas';
 
 
 type
diff --git a/tutorial/delphi/DelphiClient/DelphiClient.dproj b/tutorial/delphi/DelphiClient/DelphiClient.dproj
index 8b94142..1e2ab3d 100644
--- a/tutorial/delphi/DelphiClient/DelphiClient.dproj
+++ b/tutorial/delphi/DelphiClient/DelphiClient.dproj
@@ -1,4 +1,22 @@
-	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 		<PropertyGroup>
 			<ProjectGuid>{2B8FB3A1-2F9E-4883-8C53-0F56220B34F6}</ProjectGuid>
 			<MainSource>DelphiClient.dpr</MainSource>
@@ -62,8 +80,8 @@
 			<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.WinHTTP.pas"/>
 			<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.MsxmlHTTP.pas"/>
 			<DCCReference Include="..\..\..\lib\delphi\src\Thrift.WinHTTP.pas"/>
-			<DCCReference Include="..\..\gen-delphi\Shared.pas"/>
-			<DCCReference Include="..\..\gen-delphi\Tutorial.pas"/>
+			<DCCReference Include="..\gen-delphi\Shared.pas"/>
+			<DCCReference Include="..\gen-delphi\Tutorial.pas"/>
 			<BuildConfiguration Include="Release">
 				<Key>Cfg_2</Key>
 				<CfgParent>Base</CfgParent>
@@ -78,6 +96,11 @@
 		</ItemGroup>
 		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
 		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[pushd ..
+thrift.exe -r -gen delphi ..\tutorial.thrift
+popd]]></PreBuildEvent>
+		</PropertyGroup>
 		<ProjectExtensions>
 			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
 			<Borland.ProjectType/>
@@ -101,18 +124,21 @@
 					<VersionInfoKeys>
 						<VersionInfoKeys Name="CompanyName"/>
 						<VersionInfoKeys Name="FileDescription">Thrift Tutorial</VersionInfoKeys>
-						<VersionInfoKeys Name="FileVersion">0.14.2.0</VersionInfoKeys>
+						<VersionInfoKeys Name="FileVersion">0.15.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.14.2.0</VersionInfoKeys>
+						<VersionInfoKeys Name="ProductVersion">0.15.0.0</VersionInfoKeys>
 						<VersionInfoKeys Name="Comments"/>
 					</VersionInfoKeys>
 					<Source>
 						<Source Name="MainSource">DelphiClient.dpr</Source>
 					</Source>
+					<Parameters>
+						<Parameters Name="RunParams">--transport framed --http http://example.org</Parameters>
+					</Parameters>
 				</Delphi.Personality>
 				<Platforms>
 					<Platform value="Win32">True</Platform>
diff --git a/tutorial/delphi/DelphiServer/DelphiServer.dpr b/tutorial/delphi/DelphiServer/DelphiServer.dpr
index 41a3514..5f2dc45 100644
--- a/tutorial/delphi/DelphiServer/DelphiServer.dpr
+++ b/tutorial/delphi/DelphiServer/DelphiServer.dpr
@@ -36,8 +36,8 @@
   Thrift.Server in '..\..\..\lib\delphi\src\Thrift.Server.pas',
   Thrift.Transport in '..\..\..\lib\delphi\src\Thrift.Transport.pas',
   Thrift.WinHTTP in '..\..\..\lib\delphi\src\Thrift.WinHTTP.pas',
-  Shared in '..\..\gen-delphi\Shared.pas',
-  Tutorial in '..\..\gen-delphi\Tutorial.pas';
+  Shared in '..\gen-delphi\Shared.pas',
+  Tutorial in '..\gen-delphi\Tutorial.pas';
 
 
 type
diff --git a/tutorial/delphi/DelphiServer/DelphiServer.dproj b/tutorial/delphi/DelphiServer/DelphiServer.dproj
index b043d9a..b1b7f48 100644
--- a/tutorial/delphi/DelphiServer/DelphiServer.dproj
+++ b/tutorial/delphi/DelphiServer/DelphiServer.dproj
@@ -1,4 +1,22 @@
-	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<!--
+ 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.
+-->
+	<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 		<PropertyGroup>
 			<ProjectGuid>{2B8FB3A1-2F9E-4883-8C53-0F56220B34F6}</ProjectGuid>
 			<MainSource>DelphiServer.dpr</MainSource>
@@ -59,8 +77,8 @@
 			<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Server.pas"/>
 			<DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.pas"/>
 			<DCCReference Include="..\..\..\lib\delphi\src\Thrift.WinHTTP.pas"/>
-			<DCCReference Include="..\..\gen-delphi\Shared.pas"/>
-			<DCCReference Include="..\..\gen-delphi\Tutorial.pas"/>
+			<DCCReference Include="..\gen-delphi\Shared.pas"/>
+			<DCCReference Include="..\gen-delphi\Tutorial.pas"/>
 			<BuildConfiguration Include="Release">
 				<Key>Cfg_2</Key>
 				<CfgParent>Base</CfgParent>
@@ -75,6 +93,11 @@
 		</ItemGroup>
 		<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
 		<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+		<PropertyGroup>
+			<PreBuildEvent><![CDATA[pushd ..
+thrift.exe -r -gen delphi ..\tutorial.thrift
+popd]]></PreBuildEvent>
+		</PropertyGroup>
 		<ProjectExtensions>
 			<Borland.Personality>Delphi.Personality.12</Borland.Personality>
 			<Borland.ProjectType/>
@@ -98,13 +121,13 @@
 					<VersionInfoKeys>
 						<VersionInfoKeys Name="CompanyName"/>
 						<VersionInfoKeys Name="FileDescription">Thrift Tutorial</VersionInfoKeys>
-						<VersionInfoKeys Name="FileVersion">0.14.2.0</VersionInfoKeys>
+						<VersionInfoKeys Name="FileVersion">0.15.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.14.2.0</VersionInfoKeys>
+						<VersionInfoKeys Name="ProductVersion">0.15.0.0</VersionInfoKeys>
 						<VersionInfoKeys Name="Comments"/>
 					</VersionInfoKeys>
 					<Source>
diff --git a/tutorial/go/Makefile.am b/tutorial/go/Makefile.am
index bd57d65..ed108fd 100644
--- a/tutorial/go/Makefile.am
+++ b/tutorial/go/Makefile.am
@@ -18,36 +18,30 @@
 #
 
 gen-go/tutorial/calculator.go gen-go/shared/shared_service.go: $(top_srcdir)/tutorial/tutorial.thrift
-	$(THRIFT) --gen go$(COMPILER_EXTRAFLAG) -r $<
+	$(THRIFT) --gen go:thrift_import=github.com/apache/thrift/lib/go/thrift,package_prefix=github.com/apache/thrift/tutorial/go/gen-go/$(COMPILER_EXTRAFLAG) -r $<
 
 all-local: gen-go/tutorial/calculator.go
 
-check: src/github.com/apache/thrift/lib/go/thrift thirdparty-dep
-	$(THRIFT) -r --gen go$(COMPILER_EXTRAFLAG) $(top_srcdir)/tutorial/tutorial.thrift
-	cp -r gen-go/* src/
-	GOPATH=`pwd` $(GO) build -o go-tutorial ./src
-	GOPATH=`pwd` $(GO) build -o calculator-remote src/tutorial/calculator-remote/calculator-remote.go
-
-src/github.com/apache/thrift/lib/go/thrift:
-	mkdir -p src/github.com/apache/thrift/lib/go
-	ln -sf $(realpath $(top_srcdir)/lib/go/thrift) src/github.com/apache/thrift/lib/go/thrift
+check: thirdparty-dep all
+	$(GO) build -mod=mod -o go-tutorial ./src
+	$(GO) build -mod=mod -o calculator-remote ./gen-go/tutorial/calculator-remote/calculator-remote.go
 
 thirdparty-dep:
 
 tutorialserver: all
-	GOPATH=`pwd` $(GO) run src/*.go -server=true
+	$(GO) run -mod=mod src/*.go -server=true
 
 tutorialclient: all
-	GOPATH=`pwd` $(GO) run src/*.go
+	$(GO) run -mod=mod src/*.go
 
 tutorialsecureserver: all
-	GOPATH=`pwd` $(GO) run src/*.go -server=true -secure=true
+	$(GO) run -mod=mod src/*.go -server=true -secure=true
 
 tutorialsecureclient: all
-	GOPATH=`pwd` $(GO) run src/*.go -secure=true
+	$(GO) run -mod=mod src/*.go -secure=true
 
 clean-local:
-	$(RM) -r gen-* src/shared src/tutorial src/git.apache.org go-tutorial calculator-remote
+	$(RM) -r gen-* go-tutorial calculator-remote
 
 EXTRA_DIST = \
 	src/client.go \
diff --git a/tutorial/go/src/client.go b/tutorial/go/src/client.go
index 319ca3e..8776f9c 100644
--- a/tutorial/go/src/client.go
+++ b/tutorial/go/src/client.go
@@ -23,9 +23,9 @@
 	"context"
 	"crypto/tls"
 	"fmt"
-	"tutorial"
 
 	"github.com/apache/thrift/lib/go/thrift"
+	"github.com/apache/thrift/tutorial/go/gen-go/tutorial"
 )
 
 var defaultCtx = context.Background()
diff --git a/tutorial/go/src/handler.go b/tutorial/go/src/handler.go
index 5c0eed0..7645fc2 100644
--- a/tutorial/go/src/handler.go
+++ b/tutorial/go/src/handler.go
@@ -22,9 +22,10 @@
 import (
 	"context"
 	"fmt"
-	"shared"
 	"strconv"
-	"tutorial"
+
+	"github.com/apache/thrift/tutorial/go/gen-go/shared"
+	"github.com/apache/thrift/tutorial/go/gen-go/tutorial"
 )
 
 type CalculatorHandler struct {
diff --git a/tutorial/go/src/main.go b/tutorial/go/src/main.go
index 7730d7b..afac6bb 100644
--- a/tutorial/go/src/main.go
+++ b/tutorial/go/src/main.go
@@ -22,8 +22,9 @@
 import (
 	"flag"
 	"fmt"
-	"github.com/apache/thrift/lib/go/thrift"
 	"os"
+
+	"github.com/apache/thrift/lib/go/thrift"
 )
 
 func Usage() {
diff --git a/tutorial/go/src/server.go b/tutorial/go/src/server.go
index 95708eb..1171ca6 100644
--- a/tutorial/go/src/server.go
+++ b/tutorial/go/src/server.go
@@ -22,8 +22,9 @@
 import (
 	"crypto/tls"
 	"fmt"
+
 	"github.com/apache/thrift/lib/go/thrift"
-	"tutorial"
+	"github.com/apache/thrift/tutorial/go/gen-go/tutorial"
 )
 
 func runServer(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory, addr string, secure bool) error {
@@ -40,7 +41,7 @@
 	} else {
 		transport, err = thrift.NewTServerSocket(addr)
 	}
-	
+
 	if err != nil {
 		return err
 	}
diff --git a/tutorial/haxe/Tutorial.hxproj b/tutorial/haxe/Tutorial.hxproj
index 796f648..44e0efd 100644
--- a/tutorial/haxe/Tutorial.hxproj
+++ b/tutorial/haxe/Tutorial.hxproj
@@ -4,7 +4,7 @@
   <output>
     <movie outputType="Application" />
     <movie input="" />
-    <movie path="bin/HaxeTutorial" />
+    <movie path="bin\HaxeTutorial" />
     <movie fps="30" />
     <movie width="800" />
     <movie height="600" />
@@ -17,7 +17,7 @@
   <classpaths>
     <class path="src" />
     <class path="gen-haxe" />
-    <class path="../../lib/haxe/src" />
+    <class path="..\..\lib\haxe\src" />
   </classpaths>
   <!-- Build options -->
   <build>
diff --git a/tutorial/haxe/php-web-server.hxml b/tutorial/haxe/php-web-server.hxml
index 395a852..88007c1 100644
--- a/tutorial/haxe/php-web-server.hxml
+++ b/tutorial/haxe/php-web-server.hxml
@@ -27,7 +27,7 @@
 
 #PHP target
 -php bin/php-web-server/
---php-front Main-debug.php
+-D php-front=Main-debug.php
 
 #defines
 -D phpwebserver
diff --git a/tutorial/haxe/php.hxml b/tutorial/haxe/php.hxml
index c2f6887..42bbf74 100644
--- a/tutorial/haxe/php.hxml
+++ b/tutorial/haxe/php.hxml
@@ -27,7 +27,7 @@
 
 #PHP target
 -php bin/php/
---php-front Main-debug.php
+-D php-front=Main-debug.php
 
 #Add debug information
 -debug
diff --git a/tutorial/haxe/src/CalculatorHandler.hx b/tutorial/haxe/src/CalculatorHandler.hx
index e9752db..fcb06d1 100644
--- a/tutorial/haxe/src/CalculatorHandler.hx
+++ b/tutorial/haxe/src/CalculatorHandler.hx
@@ -31,7 +31,7 @@
 import shared.*;
 
 
-class CalculatorHandler implements Calculator {
+class CalculatorHandler implements Calculator_service {
 
     private var log = new IntMap<SharedStruct>();
 
diff --git a/tutorial/haxe/src/Main.hx b/tutorial/haxe/src/Main.hx
index 6bebe71..a56549f 100644
--- a/tutorial/haxe/src/Main.hx
+++ b/tutorial/haxe/src/Main.hx
@@ -32,6 +32,7 @@
 enum Prot {
     binary;
     json;
+	compact;
 }
 
 enum Trns {
@@ -112,12 +113,12 @@
     #if ! (flash || js)
 
     private static function GetHelp() : String {
-        return Sys.executablePath()+"  modus  trnsOption  transport  protocol\n"
+        return Sys.programPath+"  modus  layered  transport  protocol\n"
         +"Options:\n"
-        +"  modus:       client, server   (default: client)\n"
-        +"  trnsOption:  framed, buffered (default: none)\n"
-        +"  transport:   socket, http     (default: socket)\n"
-        +"  protocol:    binary, json     (default: binary)\n"
+        +"  modus:       client, server          (default: client)\n"
+        +"  layered:     framed, buffered        (default: none)\n"
+        +"  transport:   socket, http            (default: socket)\n"
+        +"  protocol:    binary, json, compact   (default: binary)\n"
         +"\n"
         +"All arguments are optional.\n";
     }
@@ -160,6 +161,9 @@
                 } else if ( arg == "json") {
                     prot = json;
                     ++step;
+                } else if ( arg == "compact") {
+                    prot = compact;
+                    ++step;
                 } else {
                     throw "Unknown protocol "+arg;
                 }
@@ -217,6 +221,9 @@
         case json:
              trace("- JSON protocol");
              protocol = new TJSONProtocol( transport);
+        case compact:
+             trace("- compact protocol");
+             protocol = new TCompactProtocol( transport);
         default:
             throw "Unhandled protocol";
         }
@@ -232,7 +239,7 @@
         var client = ClientSetup();
 
         try {
-              client.ping();
+            client.ping();
             trace("ping() successful");
         } catch(error : TException) {
             trace('ping() failed: $error');
@@ -310,11 +317,12 @@
             #else
               trace("- http transport");
               transport = new TWrappingServerTransport(
-                      new TStreamTransport(
-                        new TFileStream("php://input", Read),
-                        new TFileStream("php://output", Append)
-                        )
-                      );
+                new TStreamTransport(
+                  new TFileStream("php://input", Read),
+                  new TFileStream("php://output", Append),
+                  null
+                )
+              );
 
             #end
         default:
@@ -341,11 +349,14 @@
         case json:
             trace("- JSON protocol");
              protfactory = new TJSONProtocolFactory();
+        case compact:
+            trace("- compact protocol");
+             protfactory = new TCompactProtocolFactory();
         default:
             throw "Unhandled protocol";
         }
 
-        var handler = new CalculatorHandler();
+        var handler : Calculator_service = new CalculatorHandler();
         var processor = new CalculatorProcessor(handler);
         var server = new TSimpleServer( processor, transport, transfactory, protfactory);
         #if phpwebserver
diff --git a/tutorial/hs/HaskellClient.hs b/tutorial/hs/HaskellClient.hs
deleted file mode 100644
index 76a8824..0000000
--- a/tutorial/hs/HaskellClient.hs
+++ /dev/null
@@ -1,76 +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.
---
-
-import qualified Calculator
-import qualified Calculator_Client as Client
-import qualified SharedService_Client as SClient
-import Tutorial_Types
-import SharedService_Iface
-import Shared_Types
-
-import Thrift
-import Thrift.Protocol.Binary
-import Thrift.Transport
-import Thrift.Transport.Handle
-import Thrift.Server
-
-import Control.Exception
-import Data.Maybe
-import Data.Text.Lazy
-import Text.Printf
-import Network
-
-main = do
-  transport  <- hOpen ("localhost", PortNumber 9090)
-  let binProto = BinaryProtocol transport
-  let client = (binProto, binProto)
-
-  Client.ping client
-  print "ping()"
-
-  sum <- Client.add client 1 1
-  printf "1+1=%d\n" sum
-
-
-  let work = Work { work_op = Operation_DIVIDE,
-                    work_num1 = 1,
-                    work_num2 = 0,
-                    work_comment = Nothing
-                  }
-
-  Control.Exception.catch (printf "1/0=%d\n" =<< Client.calculate client 1 work)
-        (\e -> printf "InvalidOperation %s\n" (show (e :: InvalidOperation)))
-
-
-  let work = Work { work_op = Operation_SUBTRACT,
-                    work_num1 = 15,
-                    work_num2 = 10,
-                    work_comment = Nothing
-                  }
-
-  diff <- Client.calculate client 1 work
-  printf "15-10=%d\n" diff
-
-  log <- SClient.getStruct client 1
-  printf "Check log: %s\n" $ unpack $ sharedStruct_value log
-
-  -- Close!
-  tClose transport
-
-
diff --git a/tutorial/hs/HaskellServer.hs b/tutorial/hs/HaskellServer.hs
deleted file mode 100644
index 1594ee3..0000000
--- a/tutorial/hs/HaskellServer.hs
+++ /dev/null
@@ -1,103 +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.
---
-
-{-# LANGUAGE OverloadedStrings #-}
-
-import qualified Calculator
-import Calculator_Iface
-import Tutorial_Types
-import SharedService_Iface
-import Shared_Types
-
-import Thrift
-import Thrift.Protocol.Binary
-import Thrift.Transport
-import Thrift.Server
-
-import Data.Int
-import Data.String
-import Data.Maybe
-import Text.Printf
-import Control.Exception (throw)
-import Control.Concurrent.MVar
-import qualified Data.Map as M
-import Data.Map ((!))
-import Data.Monoid
-
-data CalculatorHandler = CalculatorHandler {mathLog :: MVar (M.Map Int32 SharedStruct)}
-
-newCalculatorHandler = do
-  log <- newMVar mempty
-  return $ CalculatorHandler log
-
-instance SharedService_Iface CalculatorHandler where
-  getStruct self k = do
-    myLog <- readMVar (mathLog self)
-    return $ (myLog ! k)
-
-
-instance Calculator_Iface CalculatorHandler where
-  ping _ =
-    print "ping()"
-
-  add _ n1 n2 = do
-    printf "add(%d,%d)\n" n1 n2
-    return (n1 + n2)
-
-  calculate self mlogid mwork = do
-    printf "calculate(%d, %s)\n" logid (show work)
-
-    let val = case op work of
-                Operation_ADD ->
-                    num1 work + num2 work
-                Operation_SUBTRACT ->
-                    num1 work - num2 work
-                Operation_MULTIPLY ->
-                    num1 work * num2 work
-                Operation_DIVIDE ->
-                    if num2 work == 0 then
-                        throw $
-                              InvalidOperation {
-                                 invalidOperation_whatOp = fromIntegral $ fromEnum $ op work,
-                                 invalidOperation_why = "Cannot divide by 0"
-                                            }
-                    else
-                        num1 work `div` num2 work
-
-    let logEntry = SharedStruct logid (fromString $ show $ val)
-    modifyMVar_ (mathLog self) $ return .(M.insert logid logEntry)
-
-    return $! val
-
-   where
-     -- stupid dynamic languages f'ing it up
-     num1 = work_num1
-     num2 = work_num2
-     op = work_op
-     logid = mlogid
-     work = mwork
-
-  zip _ =
-    print "zip()"
-
-main =  do
-  handler <- newCalculatorHandler
-  print "Starting the server..."
-  runBasicServer handler Calculator.process 9090
-  print "done."
diff --git a/tutorial/hs/LICENSE b/tutorial/hs/LICENSE
deleted file mode 100644
index 3b6d7d7..0000000
--- a/tutorial/hs/LICENSE
+++ /dev/null
@@ -1,239 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed 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.
-
---------------------------------------------------
-SOFTWARE DISTRIBUTED WITH THRIFT:
-
-The Apache Thrift software includes a number of subcomponents with
-separate copyright notices and license terms. Your use of the source
-code for the these subcomponents is subject to the terms and
-conditions of the following licenses.
-
---------------------------------------------------
-Portions of the following files are licensed under the MIT License:
-
-  lib/erl/src/Makefile.am
-
-Please see doc/otp-base-license.txt for the full terms of this license.
-
---------------------------------------------------
-For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components:
-
-#   Copyright (c) 2007 Thomas Porschberg <thomas@randspringer.de>
-#
-#   Copying and distribution of this file, with or without
-#   modification, are permitted in any medium without royalty provided
-#   the copyright notice and this notice are preserved.
-
---------------------------------------------------
-For the lib/nodejs/lib/thrift/json_parse.js:
-
-/*
-    json_parse.js
-    2015-05-02
-    Public Domain.
-    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
-*/
-(By Douglas Crockford <douglas@crockford.com>)
---------------------------------------------------
diff --git a/tutorial/hs/Makefile.am b/tutorial/hs/Makefile.am
deleted file mode 100755
index 9c6fd83..0000000
--- a/tutorial/hs/Makefile.am
+++ /dev/null
@@ -1,47 +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.
-#
-
-all-local:
-	$(top_builddir)/compiler/cpp/thrift --gen hs -r $(top_srcdir)/tutorial/tutorial.thrift
-	$(CABAL) install
-
-install-exec-hook:
-	$(CABAL) install
-
-# Make sure this doesn't fail if Haskell is not configured.
-clean-local:
-	$(CABAL) clean
-	$(RM) -r dist/
-	$(RM) -r gen-*/
-
-dist-hook:
-	$(RM) -r $(distdir)/dist/
-	$(RM) -r $(distdir)/gen-*/
-
-check-local:
-	$(CABAL) check
-
-tutorialserver: all
-	dist/build/HaskellServer/HaskellServer
-
-tutorialclient: all
-	dist/build/HaskellClient/HaskellClient
-
-EXTRA_DIST = \
-	LICENSE
diff --git a/tutorial/hs/Setup.lhs b/tutorial/hs/Setup.lhs
deleted file mode 100644
index c7df182..0000000
--- a/tutorial/hs/Setup.lhs
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/usr/bin/env runhaskell
-
-> -- 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.
-
-> import Distribution.Simple
-> main = defaultMain
diff --git a/tutorial/hs/ThriftTutorial.cabal b/tutorial/hs/ThriftTutorial.cabal
deleted file mode 100755
index d66f39e..0000000
--- a/tutorial/hs/ThriftTutorial.cabal
+++ /dev/null
@@ -1,73 +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.
---
-
-Name:           ThriftTutorial
-Version:        0.14.2
-Cabal-Version:  >= 1.4
-License:        OtherLicense
-Category:       Foreign
-Build-Type:     Simple
-Synopsis:       Thrift Tutorial library package
-Homepage:       http://thrift.apache.org
-Bug-Reports:    https://issues.apache.org/jira/browse/THRIFT
-Maintainer:     dev@thrift.apache.org
-License-File:   LICENSE
-
-Description:
-  Haskell tutorial for the Apache Thrift RPC system. Requires the use of the thrift code generator.
-
-flag network-uri
-   description: Get Network.URI from the network-uri package
-   default: True
-
-Executable HaskellServer
-  Main-is: HaskellServer.hs
-  Hs-Source-Dirs:
-    ., gen-hs/
-  Build-Depends:
-    base >= 4, base < 5, ghc-prim, containers, thrift, vector, unordered-containers, text, hashable, bytestring, QuickCheck
-  Extensions:
-    DeriveDataTypeable,
-    ExistentialQuantification,
-    FlexibleInstances,
-    KindSignatures,
-    MagicHash,
-    RankNTypes,
-    ScopedTypeVariables,
-    TypeSynonymInstances
-
-Executable HaskellClient
-  Main-is: HaskellClient.hs
-  Hs-Source-Dirs:
-    ., gen-hs/
-  Build-Depends:
-    base >= 4, base < 5, ghc-prim, containers, thrift, vector, QuickCheck
-  if flag(network-uri)
-     build-depends: network-uri >= 2.6, network >= 2.6
-  else
-     build-depends: network < 2.6
-  Extensions:
-    DeriveDataTypeable,
-    ExistentialQuantification,
-    FlexibleInstances,
-    KindSignatures,
-    MagicHash,
-    RankNTypes,
-    ScopedTypeVariables,
-    TypeSynonymInstances
diff --git a/tutorial/netstd/Client/Client.csproj b/tutorial/netstd/Client/Client.csproj
index 10d5040..e91b7a9 100644
--- a/tutorial/netstd/Client/Client.csproj
+++ b/tutorial/netstd/Client/Client.csproj
@@ -19,10 +19,12 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
+    <LangVersion>9.0</LangVersion>
     <AssemblyName>Client</AssemblyName>
     <PackageId>Client</PackageId>
     <OutputType>Exe</OutputType>
+    <Version>0.15.0.0</Version>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
     <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
     <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
@@ -30,7 +32,7 @@
   </PropertyGroup>
 
   <ItemGroup>
-    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.0" />
+    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="5.0.1" />
   </ItemGroup>
 
   <ItemGroup>
diff --git a/tutorial/netstd/Client/Program.cs b/tutorial/netstd/Client/Program.cs
index abbba70..9c47450 100644
--- a/tutorial/netstd/Client/Program.cs
+++ b/tutorial/netstd/Client/Program.cs
@@ -34,11 +34,14 @@
 using tutorial;
 using shared;
 
+#pragma warning disable IDE0063  // using
+#pragma warning disable IDE0057  // substr
+
 namespace Client
 {
     public class Program
     {
-        private static ServiceCollection ServiceCollection = new ServiceCollection();
+        private static readonly ServiceCollection ServiceCollection = new();
         private static ILogger Logger;
         private static readonly TConfiguration Configuration = null;  // new TConfiguration() if  needed
 
@@ -49,26 +52,27 @@
     Client -help
         will diplay help information 
 
-    Client -tr:<transport> -bf:<buffering> -pr:<protocol> -mc:<numClients>
+    Client -tr:<transport> -bf:<buffering> -pr:<protocol> [-mc:<numClients>]  [-multiplex]
         will run client with specified arguments (tcp transport and binary protocol by default) and with 1 client
 
 Options:
     -tr (transport): 
-        tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
-        namedpipe - namedpipe transport will be used (pipe address - "".test"")
-        http - http transport will be used (address - ""http://localhost:9090"")        
-        tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
+        tcp - (default) tcp transport  (localhost:9090)
+        tcptls - tcp tls transport  (localhost:9090)
+        namedpipe - namedpipe transport  (pipe "".test"")
+        http - http transport  (http://localhost:9090)
 
     -bf (buffering): 
-        none - (default) no buffering will be used
-        buffered - buffered transport will be used
-        framed - framed transport will be used
+        none - (default) no buffering 
+        buffered - buffered transport 
+        framed - framed transport 
 
     -pr (protocol): 
-        binary - (default) binary protocol will be used
-        compact - compact protocol will be used
-        json - json protocol will be used
-        multiplexed - multiplexed protocol will be used
+        binary - (default) binary protocol 
+        compact - compact protocol 
+        json - json protocol 
+
+    -multiplex - adds multiplexed protocol
 
     -mc (multiple clients):
         <numClients> - number of multiple clients to connect to server (max 100, default 1)
@@ -80,7 +84,7 @@
 
         public static void Main(string[] args)
         {
-            args = args ?? new string[0];
+            args ??= Array.Empty<string>();
 
             ServiceCollection.AddLogging(logging => ConfigureLogging(logging));
             using (var serviceProvider = ServiceCollection.BuildServiceProvider())
@@ -115,43 +119,77 @@
 
             Logger.LogInformation($"Selected # of clients: {numClients}");
 
-            var transports = new TTransport[numClients];
-            for (int i = 0; i < numClients; i++)
-            {
-                var t = GetTransport(args);
-                transports[i] = t;
-            }
-            
-            Logger.LogInformation($"Selected client transport: {transports[0]}");
+            var transport = GetTransport(args);
+            Logger.LogInformation($"Selected client transport: {transport}");
 
-            var protocols = new Tuple<Protocol, TProtocol>[numClients];
-            for (int i = 0; i < numClients; i++)
-            {
-                var p = GetProtocol(args, transports[i]);
-                protocols[i] = p;
-            }
+            var protocol = MakeProtocol( args, MakeTransport(args));
+            Logger.LogInformation($"Selected client protocol: {GetProtocol(args)}");
 
-            Logger.LogInformation($"Selected client protocol: {protocols[0].Item1}");
+            var mplex = GetMultiplex(args);
+            Logger.LogInformation("Multiplex " + (mplex ? "yes" : "no"));
 
             var tasks = new Task[numClients];
             for (int i = 0; i < numClients; i++)
             {
-                var task = RunClientAsync(protocols[i], cancellationToken);
+                var task = RunClientAsync(protocol, mplex, cancellationToken);
                 tasks[i] = task;
             }
 
-            Task.WaitAll(tasks);
-
+            Task.WaitAll(tasks,cancellationToken);
             await Task.CompletedTask;
         }
 
-        private static TTransport GetTransport(string[] args)
+        private static bool GetMultiplex(string[] args)
         {
-            TTransport transport = new TSocketTransport(IPAddress.Loopback, 9090, Configuration);
+            var mplex = args.FirstOrDefault(x => x.StartsWith("-multiplex"));
+            return !string.IsNullOrEmpty(mplex);
+        }
 
+        private static Protocol GetProtocol(string[] args)
+        {
+            var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+            if (string.IsNullOrEmpty(protocol))
+                return Protocol.Binary;
+
+            protocol = protocol.Substring(0, 1).ToUpperInvariant() + protocol.Substring(1).ToLowerInvariant();
+            if (Enum.TryParse(protocol, true, out Protocol selectedProtocol))
+                return selectedProtocol;
+            else
+                return Protocol.Binary;
+        }
+
+        private static Buffering GetBuffering(string[] args)
+        {
+            var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(":")?[1];
+            if (string.IsNullOrEmpty(buffering))
+                return Buffering.None;
+
+            buffering = buffering.Substring(0, 1).ToUpperInvariant() + buffering.Substring(1).ToLowerInvariant();
+            if (Enum.TryParse<Buffering>(buffering, out var selectedBuffering))
+                return selectedBuffering;
+            else
+                return Buffering.None;
+        }
+
+        private static Transport GetTransport(string[] args)
+        {
+            var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+            if (string.IsNullOrEmpty(transport))
+                return Transport.Tcp;
+
+            transport = transport.Substring(0, 1).ToUpperInvariant() + transport.Substring(1).ToLowerInvariant();
+            if (Enum.TryParse(transport, true, out Transport selectedTransport))
+                return selectedTransport;
+            else
+                return Transport.Tcp;
+        }
+
+
+        private static TTransport MakeTransport(string[] args)
+        {
             // construct endpoint transport
-            var transportArg = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
-            if (Enum.TryParse(transportArg, true, out Transport selectedTransport))
+            TTransport transport = null;
+            Transport selectedTransport = GetTransport(args);
             {
                 switch (selectedTransport)
                 {
@@ -179,23 +217,20 @@
             }
 
             // optionally add layered transport(s)
-            var bufferingArg = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(':')?[1];
-            if (Enum.TryParse<Buffering>(bufferingArg, out var selectedBuffering))
+            Buffering selectedBuffering = GetBuffering(args);
+            switch (selectedBuffering)
             {
-                switch (selectedBuffering)
-                {
-                    case Buffering.Buffered:
-                        transport = new TBufferedTransport(transport);
-                        break;
+                case Buffering.Buffered:
+                    transport = new TBufferedTransport(transport);
+                    break;
 
-                    case Buffering.Framed:
-                        transport = new TFramedTransport(transport);
-                        break;
+                case Buffering.Framed:
+                    transport = new TFramedTransport(transport);
+                    break;
 
-                    default: // layered transport(s) are optional
-                        Debug.Assert(selectedBuffering == Buffering.None, "unhandled case");
-                        break;
-                }
+                default: // layered transport(s) are optional
+                    Debug.Assert(selectedBuffering == Buffering.None, "unhandled case");
+                    break;
             }
 
             return transport;
@@ -207,11 +242,10 @@
 
             Logger.LogInformation($"Selected # of clients: {numClients}");
 
-            int c;
-            if( int.TryParse(numClients, out c) && (0 < c) && (c <= 100))
-				return c;
-			else
-				return 1;
+            if (int.TryParse(numClients, out int c) && (0 < c) && (c <= 100))
+                return c;
+            else
+                return 1;
         }
 
         private static X509Certificate2 GetCertificate()
@@ -250,65 +284,33 @@
             return true;
         }
 
-        private static Tuple<Protocol, TProtocol> GetProtocol(string[] args, TTransport transport)
+        private static TProtocol MakeProtocol(string[] args, TTransport transport)
         {
-            var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
-
-            Protocol selectedProtocol;
-            if (Enum.TryParse(protocol, true, out selectedProtocol))
+            Protocol selectedProtocol = GetProtocol(args);
+            return selectedProtocol switch
             {
-                switch (selectedProtocol)
-                {
-                    case Protocol.Binary:
-                        return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
-                    case Protocol.Compact:
-                        return new Tuple<Protocol, TProtocol>(selectedProtocol, new TCompactProtocol(transport));
-                    case Protocol.Json:
-                        return new Tuple<Protocol, TProtocol>(selectedProtocol, new TJsonProtocol(transport));
-                    case Protocol.Multiplexed:
-                        // it returns BinaryProtocol to avoid making wrapped protocol as public in TProtocolDecorator (in RunClientAsync it will be wrapped into Multiplexed protocol)
-                        return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
-                    default:
-                        Debug.Assert(false, "unhandled case");
-                        break;
-                }
-            }
-
-            return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+                Protocol.Binary => new TBinaryProtocol(transport),
+                Protocol.Compact => new TCompactProtocol(transport),
+                Protocol.Json => new TJsonProtocol(transport),
+                _ => throw new Exception("unhandled protocol"),
+            };
         }
 
-        private static async Task RunClientAsync(Tuple<Protocol, TProtocol> protocolTuple, CancellationToken cancellationToken)
+        private static async Task RunClientAsync(TProtocol protocol, bool multiplex, CancellationToken cancellationToken)
         {
             try
             {
-                var protocol = protocolTuple.Item2;
-                var protocolType = protocolTuple.Item1;
-
-                TBaseClient client = null;
-
                 try
                 {
-                    if (protocolType != Protocol.Multiplexed)
-                    {
+                    if( multiplex)
+                        protocol = new TMultiplexedProtocol(protocol, nameof(Calculator));
 
-                        client = new Calculator.Client(protocol);
-                        await ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
-                    }
-                    else
-                    {
-                        // it uses binary protocol there  to create Multiplexed protocols
-                        var multiplex = new TMultiplexedProtocol(protocol, nameof(Calculator));
-                        client = new Calculator.Client(multiplex);
-                        await ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
-
-                        multiplex = new TMultiplexedProtocol(protocol, nameof(SharedService));
-                        client = new SharedService.Client(multiplex);
-                        await ExecuteSharedServiceClientOperations(cancellationToken, (SharedService.Client)client);
-                    }
+                    var client = new Calculator.Client(protocol);
+                    await ExecuteCalculatorClientOperations(client, cancellationToken);
                 }
                 catch (Exception ex)
                 {
-                    Logger.LogError($"{client?.ClientId} " + ex);
+                    Logger.LogError(ex.ToString());
                 }
                 finally
                 {
@@ -321,18 +323,18 @@
             }
         }
 
-        private static async Task ExecuteCalculatorClientOperations(CancellationToken cancellationToken, Calculator.Client client)
+        private static async Task ExecuteCalculatorClientOperations( Calculator.Client client, CancellationToken cancellationToken)
         {
             await client.OpenTransportAsync(cancellationToken);
 
             // Async version
 
-            Logger.LogInformation($"{client.ClientId} PingAsync()");
-            await client.pingAsync(cancellationToken);
+            Logger.LogInformation($"{client.ClientId} Ping()");
+            await client.ping(cancellationToken);
 
-            Logger.LogInformation($"{client.ClientId} AddAsync(1,1)");
-            var sum = await client.addAsync(1, 1, cancellationToken);
-            Logger.LogInformation($"{client.ClientId} AddAsync(1,1)={sum}");
+            Logger.LogInformation($"{client.ClientId} Add(1,1)");
+            var sum = await client.add(1, 1, cancellationToken);
+            Logger.LogInformation($"{client.ClientId} Add(1,1)={sum}");
 
             var work = new Work
             {
@@ -343,8 +345,8 @@
 
             try
             {
-                Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
-                await client.calculateAsync(1, work, cancellationToken);
+                Logger.LogInformation($"{client.ClientId} Calculate(1)");
+                await client.calculate(1, work, cancellationToken);
                 Logger.LogInformation($"{client.ClientId} Whoa we can divide by 0");
             }
             catch (InvalidOperation io)
@@ -358,8 +360,8 @@
 
             try
             {
-                Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
-                var diff = await client.calculateAsync(1, work, cancellationToken);
+                Logger.LogInformation($"{client.ClientId} Calculate(1)");
+                var diff = await client.calculate(1, work, cancellationToken);
                 Logger.LogInformation($"{client.ClientId} 15-10={diff}");
             }
             catch (InvalidOperation io)
@@ -367,22 +369,12 @@
                 Logger.LogInformation($"{client.ClientId} Invalid operation: " + io);
             }
 
-            Logger.LogInformation($"{client.ClientId} GetStructAsync(1)");
-            var log = await client.getStructAsync(1, cancellationToken);
+            Logger.LogInformation($"{client.ClientId} GetStruct(1)");
+            var log = await client.getStruct(1, cancellationToken);
             Logger.LogInformation($"{client.ClientId} Check log: {log.Value}");
 
-            Logger.LogInformation($"{client.ClientId} ZipAsync() with delay 100mc on server side");
-            await client.zipAsync(cancellationToken);
-        }
-        private static async Task ExecuteSharedServiceClientOperations(CancellationToken cancellationToken, SharedService.Client client)
-        {
-            await client.OpenTransportAsync(cancellationToken);
-
-            // Async version
-
-            Logger.LogInformation($"{client.ClientId} SharedService GetStructAsync(1)");
-            var log = await client.getStructAsync(1, cancellationToken);
-            Logger.LogInformation($"{client.ClientId} SharedService Value: {log.Value}");
+            Logger.LogInformation($"{client.ClientId} Zip() with delay 100mc on server side");
+            await client.zip(cancellationToken);
         }
 
 
@@ -401,7 +393,6 @@
             Binary,
             Compact,
             Json,
-            Multiplexed
         }
 
         private enum Buffering
diff --git a/tutorial/netstd/Client/Properties/launchSettings.json b/tutorial/netstd/Client/Properties/launchSettings.json
deleted file mode 100644
index 6b7b60d..0000000
--- a/tutorial/netstd/Client/Properties/launchSettings.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "profiles": {
-    "Client": {
-      "commandName": "Project",
-      "commandLineArgs": "-p:multiplexed"
-    }
-  }
-}
\ No newline at end of file
diff --git a/tutorial/netstd/Interfaces/GlobalSuppressions.cs b/tutorial/netstd/Interfaces/GlobalSuppressions.cs
new file mode 100644
index 0000000..34fdc79
--- /dev/null
+++ b/tutorial/netstd/Interfaces/GlobalSuppressions.cs
@@ -0,0 +1,26 @@
+// 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.
+
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project.
+// Project-level suppressions either have no target or are given
+// a specific target and scoped to a namespace, type, member, etc.
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Performance", "CA1822", Justification = "<Ausstehend>", Scope = "module")]
+[assembly: SuppressMessage("Style", "IDE0083", Justification = "<Ausstehend>", Scope = "module")]
diff --git a/tutorial/netstd/Interfaces/Interfaces.csproj b/tutorial/netstd/Interfaces/Interfaces.csproj
index c8b2bd8..c2adc9e 100644
--- a/tutorial/netstd/Interfaces/Interfaces.csproj
+++ b/tutorial/netstd/Interfaces/Interfaces.csproj
@@ -19,9 +19,10 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netstandard2.0</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
     <AssemblyName>Interfaces</AssemblyName>
     <PackageId>Interfaces</PackageId>
+    <Version>0.15.0.0</Version>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
     <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
     <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
@@ -33,7 +34,7 @@
   </ItemGroup>
 
   <ItemGroup>
-    <PackageReference Include="System.ServiceModel.Primitives" Version="4.7.0" />
+    <PackageReference Include="System.ServiceModel.Primitives" Version="4.8.1" />
   </ItemGroup>
 
   <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
diff --git a/tutorial/netstd/Server/Program.cs b/tutorial/netstd/Server/Program.cs
index 3181e8e..80205d5 100644
--- a/tutorial/netstd/Server/Program.cs
+++ b/tutorial/netstd/Server/Program.cs
@@ -38,17 +38,20 @@
 using Thrift.Processor;
 using System.Diagnostics;
 
+#pragma warning disable IDE0063  // using
+#pragma warning disable IDE0057  // substr
+
 namespace Server
 {
     public class Program
     {
-        private static ServiceCollection ServiceCollection = new ServiceCollection();
+        private static readonly ServiceCollection ServiceCollection = new();
         private static ILogger Logger;
         private static readonly TConfiguration Configuration = null;  // new TConfiguration() if  needed
 
         public static void Main(string[] args)
         {
-            args = args ?? new string[0];
+            args ??= Array.Empty<string>();
 
             ServiceCollection.AddLogging(logging => ConfigureLogging(logging));
             using (var serviceProvider = ServiceCollection.BuildServiceProvider())
@@ -89,26 +92,27 @@
     Server -help
         will diplay help information 
 
-    Server -tr:<transport> -bf:<buffering> -pr:<protocol>
+    Server -tr:<transport> -bf:<buffering> -pr:<protocol>  [-multiplex]
         will run server with specified arguments (tcp transport, no buffering, and binary protocol by default)
 
 Options:
     -tr (transport): 
-        tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
-        namedpipe - namedpipe transport will be used (pipe address - "".test"")
-        http - http transport will be used (http address - ""localhost:9090"")
-        tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090)
+        tcp - (default) tcp transport (localhost:9090)
+        tcptls - tcp transport with tls (localhost:9090)
+        namedpipe - namedpipe transport (pipe "".test"")
+        http - http transport (localhost:9090)
 
     -bf (buffering): 
-        none - (default) no buffering will be used
-        buffered - buffered transport will be used
-        framed - framed transport will be used
+        none - (default) no buffering
+        buffered - buffered transport
+        framed - framed transport
 
     -pr (protocol): 
-        binary - (default) binary protocol will be used
-        compact - compact protocol will be used
-        json - json protocol will be used
-        multiplexed - multiplexed protocol will be used
+        binary - (default) binary protocol
+        compact - compact protocol
+        json - json protocol
+
+    -multiplex - adds multiplexed protocol
 
 Sample:
     Server -tr:tcp
@@ -120,141 +124,125 @@
             var selectedTransport = GetTransport(args);
             var selectedBuffering = GetBuffering(args);
             var selectedProtocol = GetProtocol(args);
+            var multiplex = GetMultiplex(args);
 
             if (selectedTransport == Transport.Http)
             {
+                if (multiplex)
+                    throw new Exception("This tutorial semple code does not yet allow multiplex over http (although Thrift itself of course does)");
                 new HttpServerSample().Run(cancellationToken);
             }
             else
             {
-                await RunSelectedConfigurationAsync(selectedTransport, selectedBuffering, selectedProtocol, cancellationToken);
+                await RunSelectedConfigurationAsync(selectedTransport, selectedBuffering, selectedProtocol, multiplex, cancellationToken);
             }
         }
 
+
+        private static bool GetMultiplex(string[] args)
+        {
+            var mplex = args.FirstOrDefault(x => x.StartsWith("-multiplex"));
+            return !string.IsNullOrEmpty(mplex);
+        }
+
         private static Protocol GetProtocol(string[] args)
         {
-            var transport = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+            var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+            if (string.IsNullOrEmpty(protocol))
+                return Protocol.Binary;
 
-            Enum.TryParse(transport, true, out Protocol selectedProtocol);
-
-            return selectedProtocol;
+            protocol = protocol.Substring(0, 1).ToUpperInvariant() + protocol.Substring(1).ToLowerInvariant();
+            if (Enum.TryParse(protocol, true, out Protocol selectedProtocol))
+                return selectedProtocol;
+            else
+                return Protocol.Binary;
         }
 
         private static Buffering GetBuffering(string[] args)
         {
             var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(":")?[1];
+            if (string.IsNullOrEmpty(buffering))
+                return Buffering.None;
 
-            Enum.TryParse<Buffering>(buffering, out var selectedBuffering);
-
-            return selectedBuffering;
+            buffering = buffering.Substring(0, 1).ToUpperInvariant() + buffering.Substring(1).ToLowerInvariant();
+            if( Enum.TryParse<Buffering>(buffering, out var selectedBuffering))
+                return selectedBuffering;
+            else
+                return Buffering.None;
         }
 
         private static Transport GetTransport(string[] args)
         {
             var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+            if (string.IsNullOrEmpty(transport))
+                return Transport.Tcp;
 
-            Enum.TryParse(transport, true, out Transport selectedTransport);
-
-            return selectedTransport;
+            transport = transport.Substring(0, 1).ToUpperInvariant() + transport.Substring(1).ToLowerInvariant();
+            if( Enum.TryParse(transport, true, out Transport selectedTransport))
+                return selectedTransport;
+            else
+                return Transport.Tcp;
         }
 
-        private static async Task RunSelectedConfigurationAsync(Transport transport, Buffering buffering, Protocol protocol, CancellationToken cancellationToken)
+        private static async Task RunSelectedConfigurationAsync(Transport transport, Buffering buffering, Protocol protocol, bool multiplex, CancellationToken cancellationToken)
         {
+            TServerTransport serverTransport = transport switch
+            {
+                Transport.Tcp => new TServerSocketTransport(9090, Configuration),
+                Transport.NamedPipe => new TNamedPipeServerTransport(".test", Configuration, NamedPipeClientFlags.None),
+                Transport.TcpTls => new TTlsServerSocketTransport(9090, Configuration, GetCertificate(), ClientCertValidator, LocalCertificateSelectionCallback),
+                _ => throw new ArgumentException("unsupported value $transport", nameof(transport)),
+            };
+
+            TTransportFactory transportFactory = buffering switch
+            {
+                Buffering.Buffered => new TBufferedTransport.Factory(),
+                Buffering.Framed => new TFramedTransport.Factory(),
+                // layered transport(s) are optional
+                Buffering.None => null,
+                _ => throw new ArgumentException("unsupported value $buffering", nameof(buffering)),
+            };
+
+            TProtocolFactory protocolFactory = protocol switch
+            {
+                Protocol.Binary => new TBinaryProtocol.Factory(),
+                Protocol.Compact => new TCompactProtocol.Factory(),
+                Protocol.Json => new TJsonProtocol.Factory(),
+                _ => throw new ArgumentException("unsupported value $protocol", nameof(protocol)),
+            };
+
             var handler = new CalculatorAsyncHandler();
+            ITAsyncProcessor processor = new Calculator.AsyncProcessor(handler);
 
-            TServerTransport serverTransport = null;
-            switch (transport)
+            if (multiplex)
             {
-                case Transport.Tcp:
-                    serverTransport = new TServerSocketTransport(9090, Configuration);
-                    break;
-                case Transport.NamedPipe:
-                    serverTransport = new TNamedPipeServerTransport(".test", Configuration);
-                    break;
-                case Transport.TcpTls:
-                    serverTransport = new TTlsServerSocketTransport(9090, Configuration,
-                        GetCertificate(), ClientCertValidator, LocalCertificateSelectionCallback);
-                    break;
-            }
+                var multiplexedProcessor = new TMultiplexedProcessor();
+                multiplexedProcessor.RegisterProcessor(nameof(Calculator), processor);
 
-            TTransportFactory inputTransportFactory = null;
-            TTransportFactory outputTransportFactory = null;
-            switch (buffering)
-            {
-                case Buffering.Buffered:
-                    inputTransportFactory = new TBufferedTransport.Factory();
-                    outputTransportFactory = new TBufferedTransport.Factory();
-                    break;
-
-                case Buffering.Framed:
-                    inputTransportFactory = new TFramedTransport.Factory();
-                    outputTransportFactory = new TFramedTransport.Factory();
-                    break;
-
-                default: // layered transport(s) are optional
-                    Debug.Assert(buffering == Buffering.None, "unhandled case");
-                    break;
-            }
-
-            TProtocolFactory inputProtocolFactory = null;
-            TProtocolFactory outputProtocolFactory = null;
-            ITAsyncProcessor processor = null;
-            switch (protocol)
-            {
-                case Protocol.Binary:
-                    inputProtocolFactory = new TBinaryProtocol.Factory();
-                    outputProtocolFactory = new TBinaryProtocol.Factory();
-                    processor = new Calculator.AsyncProcessor(handler);
-                    break;
-
-                case Protocol.Compact:
-                    inputProtocolFactory = new TCompactProtocol.Factory();
-                    outputProtocolFactory = new TCompactProtocol.Factory();
-                    processor = new Calculator.AsyncProcessor(handler);
-                    break;
-
-                case Protocol.Json:
-                    inputProtocolFactory = new TJsonProtocol.Factory();
-                    outputProtocolFactory = new TJsonProtocol.Factory();
-                    processor = new Calculator.AsyncProcessor(handler);
-                    break;
-
-                case Protocol.Multiplexed:
-                    inputProtocolFactory = new TBinaryProtocol.Factory();
-                    outputProtocolFactory = new TBinaryProtocol.Factory();
-
-                    var calcHandler = new CalculatorAsyncHandler();
-                    var calcProcessor = new Calculator.AsyncProcessor(calcHandler);
-
-                    var sharedServiceHandler = new SharedServiceAsyncHandler();
-                    var sharedServiceProcessor = new SharedService.AsyncProcessor(sharedServiceHandler);
-
-                    var multiplexedProcessor = new TMultiplexedProcessor();
-                    multiplexedProcessor.RegisterProcessor(nameof(Calculator), calcProcessor);
-                    multiplexedProcessor.RegisterProcessor(nameof(SharedService), sharedServiceProcessor);
-
-                    processor = multiplexedProcessor;
-                    break;
-
-                default:
-                    throw new ArgumentOutOfRangeException(nameof(protocol), protocol, null);
+                processor = multiplexedProcessor;
             }
 
 
             try
             {
                 Logger.LogInformation(
-                    $"Selected TAsyncServer with {serverTransport} transport, {processor} processor and {inputProtocolFactory} protocol factories");
+                    string.Format(
+                        "TSimpleAsyncServer with \n{0} transport\n{1} buffering\nmultiplex = {2}\n{3} protocol",
+                        transport,
+                        buffering,
+                        multiplex ? "yes" : "no",
+                        protocol
+                        ));
 
                 var loggerFactory = ServiceCollection.BuildServiceProvider().GetService<ILoggerFactory>();
 
                 var server = new TSimpleAsyncServer(
                     itProcessorFactory: new TSingletonProcessorFactory(processor),
                     serverTransport: serverTransport,
-                    inputTransportFactory: inputTransportFactory,
-                    outputTransportFactory: outputTransportFactory,
-                    inputProtocolFactory: inputProtocolFactory,
-                    outputProtocolFactory: outputProtocolFactory,
+                    inputTransportFactory: transportFactory,
+                    outputTransportFactory: transportFactory,
+                    inputProtocolFactory: protocolFactory,
+                    outputProtocolFactory: protocolFactory,
                     logger: loggerFactory.CreateLogger<TSimpleAsyncServer>());
 
                 Logger.LogInformation("Starting the server...");
@@ -323,7 +311,6 @@
             Binary,
             Compact,
             Json,
-            Multiplexed
         }
 
         public class HttpServerSample
@@ -364,6 +351,8 @@
                 // This method gets called by the runtime. Use this method to add services to the container.
                 public void ConfigureServices(IServiceCollection services)
                 {
+                    // NOTE: this is not really the recommended way to do it
+                    // because the HTTP server cannot be configured properly to e.g. accept framed or multiplex
                     services.AddTransient<Calculator.IAsync, CalculatorAsyncHandler>();
                     services.AddTransient<ITAsyncProcessor, Calculator.AsyncProcessor>();
                     services.AddTransient<THttpServerTransport, THttpServerTransport>();
@@ -372,6 +361,8 @@
                 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
                 public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
                 {
+                    _ = env;
+                    _ = loggerFactory;
                     app.UseMiddleware<THttpServerTransport>();
                 }
             }
@@ -379,36 +370,36 @@
 
         public class CalculatorAsyncHandler : Calculator.IAsync
         {
-            private readonly Dictionary<int, SharedStruct> _log = new Dictionary<int, SharedStruct>();
+            private readonly Dictionary<int, SharedStruct> _log = new();
 
             public CalculatorAsyncHandler()
             {
             }
 
-            public async Task<SharedStruct> getStructAsync(int key,
+            public async Task<SharedStruct> getStruct(int key,
                 CancellationToken cancellationToken)
             {
-                Logger.LogInformation("GetStructAsync({0})", key);
+                Logger.LogInformation("GetStruct({0})", key);
                 return await Task.FromResult(_log[key]);
             }
 
-            public async Task pingAsync(CancellationToken cancellationToken)
+            public async Task ping(CancellationToken cancellationToken)
             {
-                Logger.LogInformation("PingAsync()");
+                Logger.LogInformation("Ping()");
                 await Task.CompletedTask;
             }
 
-            public async Task<int> addAsync(int num1, int num2, CancellationToken cancellationToken)
+            public async Task<int> add(int num1, int num2, CancellationToken cancellationToken)
             {
-                Logger.LogInformation($"AddAsync({num1},{num2})");
+                Logger.LogInformation($"Add({num1},{num2})");
                 return await Task.FromResult(num1 + num2);
             }
 
-            public async Task<int> calculateAsync(int logid, Work w, CancellationToken cancellationToken)
+            public async Task<int> calculate(int logid, Work w, CancellationToken cancellationToken)
             {
-                Logger.LogInformation($"CalculateAsync({logid}, [{w.Op},{w.Num1},{w.Num2}])");
+                Logger.LogInformation($"Calculate({logid}, [{w.Op},{w.Num1},{w.Num2}])");
 
-                var val = 0;
+                int val;
                 switch (w.Op)
                 {
                     case Operation.ADD:
@@ -460,22 +451,22 @@
                 return await Task.FromResult(val);
             }
 
-            public async Task zipAsync(CancellationToken cancellationToken)
+            public async Task zip(CancellationToken cancellationToken)
             {
-                Logger.LogInformation("ZipAsync() with delay 100mc");
+                Logger.LogInformation("Zip() with delay 100mc");
                 await Task.Delay(100, CancellationToken.None);
             }
         }
 
         public class SharedServiceAsyncHandler : SharedService.IAsync
         {
-            public async Task<SharedStruct> getStructAsync(int key, CancellationToken cancellationToken)
+            public async Task<SharedStruct> getStruct(int key, CancellationToken cancellationToken)
             {
-                Logger.LogInformation("GetStructAsync({0})", key);
+                Logger.LogInformation("GetStruct({0})", key);
                 return await Task.FromResult(new SharedStruct()
                 {
                     Key = key,
-                    Value = "GetStructAsync"
+                    Value = "GetStruct"
                 });
             }
         }
diff --git a/tutorial/netstd/Server/Properties/launchSettings.json b/tutorial/netstd/Server/Properties/launchSettings.json
deleted file mode 100644
index 78076ff..0000000
--- a/tutorial/netstd/Server/Properties/launchSettings.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "profiles": {
-    "Server": {
-      "commandName": "Project",
-      "commandLineArgs": "-p:multiplexed"
-    }
-  }
-}
\ No newline at end of file
diff --git a/tutorial/netstd/Server/Server.csproj b/tutorial/netstd/Server/Server.csproj
index b3ff516..b63967b 100644
--- a/tutorial/netstd/Server/Server.csproj
+++ b/tutorial/netstd/Server/Server.csproj
@@ -19,10 +19,12 @@
   -->
 
   <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
+    <TargetFramework>net5.0</TargetFramework>
+    <LangVersion>9.0</LangVersion>
     <AssemblyName>Server</AssemblyName>
     <PackageId>Server</PackageId>
     <OutputType>Exe</OutputType>
+    <Version>0.15.0.0</Version>
     <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
     <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
     <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
@@ -38,7 +40,7 @@
     <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="3.1.0" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="5.0.0" />
   </ItemGroup>
 
 </Project>
diff --git a/tutorial/ocaml/_oasis b/tutorial/ocaml/_oasis
index deebd5e..2e1773e 100644
--- a/tutorial/ocaml/_oasis
+++ b/tutorial/ocaml/_oasis
@@ -1,5 +1,5 @@
 Name: tutorial
-Version: 0.14.2
+Version: 0.15.0
 OASISFormat: 0.3
 Synopsis: OCaml Tutorial example
 Authors: Apache Thrift Developers <dev@thrift.apache.org>
diff --git a/tutorial/rs/Makefile.am b/tutorial/rs/Makefile.am
index 666331e..13f6707 100644
--- a/tutorial/rs/Makefile.am
+++ b/tutorial/rs/Makefile.am
@@ -24,6 +24,8 @@
 
 all-local: gen-rs/tutorial.rs
 	$(CARGO) build
+	$(CARGO) fmt --all -- --check
+	$(CARGO) clippy --all -- -D warnings
 	[ -d bin ] || mkdir bin
 	cp target/debug/tutorial_server bin/tutorial_server
 	cp target/debug/tutorial_client bin/tutorial_client
diff --git a/tutorial/rs/src/bin/tutorial_client.rs b/tutorial/rs/src/bin/tutorial_client.rs
index f7de23f..4bf2ec0 100644
--- a/tutorial/rs/src/bin/tutorial_client.rs
+++ b/tutorial/rs/src/bin/tutorial_client.rs
@@ -67,7 +67,7 @@
     let logid = 32;
 
     // let's do...a multiply!
-    let res = client.calculate(logid, Work::new(7, 8, Operation::Multiply, None))?;
+    let res = client.calculate(logid, Work::new(7, 8, Operation::MULTIPLY, None))?;
     println!("multiplied 7 and 8 and got {}", res);
 
     // let's get the log for it
@@ -77,7 +77,7 @@
     // ok - let's be bad :(
     // do a divide by 0
     // logid doesn't matter; won't be recorded
-    let res = client.calculate(77, Work::new(2, 0, Operation::Divide, "we bad".to_owned()));
+    let res = client.calculate(77, Work::new(2, 0, Operation::DIVIDE, "we bad".to_owned()));
 
     // we should have gotten an exception back
     match res {
diff --git a/tutorial/rs/src/bin/tutorial_server.rs b/tutorial/rs/src/bin/tutorial_server.rs
index fbccb69..ab6df57 100644
--- a/tutorial/rs/src/bin/tutorial_server.rs
+++ b/tutorial/rs/src/bin/tutorial_server.rs
@@ -123,7 +123,7 @@
         let res = if let Some(ref op) = w.op {
             if w.num1.is_none() || w.num2.is_none() {
                 Err(InvalidOperation {
-                    what_op: Some(*op as i32),
+                    what_op: Some(op.into()),
                     why: Some("no operands specified".to_owned()),
                 })
             } else {
@@ -132,19 +132,26 @@
                 let num2 = w.num2.as_ref().expect("operands checked");
 
                 match *op {
-                    Operation::Add => Ok(num1 + num2),
-                    Operation::Subtract => Ok(num1 - num2),
-                    Operation::Multiply => Ok(num1 * num2),
-                    Operation::Divide => {
+                    Operation::ADD => Ok(num1 + num2),
+                    Operation::SUBTRACT => Ok(num1 - num2),
+                    Operation::MULTIPLY => Ok(num1 * num2),
+                    Operation::DIVIDE => {
                         if *num2 == 0 {
                             Err(InvalidOperation {
-                                what_op: Some(*op as i32),
+                                what_op: Some(op.into()),
                                 why: Some("divide by 0".to_owned()),
                             })
                         } else {
                             Ok(num1 / num2)
                         }
                     }
+                    _ => {
+                        let op_val: i32 = op.into();
+                        Err(InvalidOperation {
+                            what_op: Some(op_val),
+                            why: Some(format!("unsupported operation type '{}'", op_val)),
+                        })
+                    }
                 }
             }
         } else {