Merge pull request #2383 from BioDataAnalysis/bda_minor_cmake_cleanup

Minor cleanup of two CMake files, and removed (unused) boost deps
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/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 766d2b6..464ca6a 100644
--- a/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.cc
@@ -1349,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);
 
@@ -1399,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)
         {
@@ -1430,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);
 
@@ -1466,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;
@@ -1495,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) {
@@ -1511,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;
 }
@@ -1943,6 +1948,16 @@
             }
         }
 
+        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();
@@ -2016,13 +2031,14 @@
             << indent() << "{" << endl;
         indent_up();
 
+        string tmpvar = tmp("tmp");
         string argsname = (*functions_iterator)->get_name() + "Args";
 
         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();
@@ -2041,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;
 
@@ -2053,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;
             }
@@ -2084,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;
             }
@@ -2285,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
@@ -2312,10 +2333,15 @@
     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." << func_name(normalize_name(tfunction->get_name()) + (add_async_postfix ? "Async" : "")) << "(";
@@ -2334,7 +2360,7 @@
             out << ", ";
         }
 
-        out << "args." << prop_name(*f_iter);
+        out << args << "." << prop_name(*f_iter);
     }
 
     cleanup_member_name_mapping(arg_struct);
@@ -2346,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);
@@ -2363,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;
@@ -2374,29 +2404,31 @@
     {
         out << indent() << "await oprot.WriteMessageBeginAsync(new TMessage(\""
                 << tfunction->get_name() << "\", TMessageType.Reply, seqid), cancellationToken); " << endl
-            << indent() << "await result.WriteAsync(oprot, 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())
@@ -2406,10 +2438,11 @@
     }
     else
     {
-        out << indent() << "var x = new TApplicationException(TApplicationException.ExceptionType.InternalError,\" Internal error.\");" << endl
+        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
@@ -2434,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);
@@ -2455,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();
     }
@@ -2469,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();
 
@@ -2485,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);
@@ -2947,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;
diff --git a/compiler/cpp/src/thrift/generate/t_netstd_generator.h b/compiler/cpp/src/thrift/generate/t_netstd_generator.h
index 8a812a3..b35550d 100644
--- a/compiler/cpp/src/thrift/generate/t_netstd_generator.h
+++ b/compiler/cpp/src/thrift/generate/t_netstd_generator.h
@@ -165,6 +165,7 @@
   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(t_struct* scope, const vector<t_field*>& members, const string& structname);
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/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/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/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/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/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/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/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/Thrift/Server/TThreadPoolAsyncServer.cs b/lib/netstd/Thrift/Server/TThreadPoolAsyncServer.cs
index 877d595..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)
@@ -177,7 +178,7 @@
                     try
                     {
                         TTransport client = await ServerTransport.AcceptAsync(cancellationToken);
-                        ThreadPool.QueueUserWorkItem(this.Execute, client);
+                        _ = Task.Run(async () => await ExecuteAsync(client), cancellationToken);  // intentionally ignoring retval
                     }
                     catch (TaskCanceledException)
                     {
@@ -209,7 +210,7 @@
             }
             finally
             {
-                ServerCancellationToken = default(CancellationToken);
+                ServerCancellationToken = default;
             }
         }
 
@@ -218,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;
@@ -241,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
@@ -254,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;
                         }
                     }
@@ -272,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/rs/src/lib.rs b/lib/rs/src/lib.rs
index 279690e..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))))]
diff --git a/test/netstd/Client/Client.csproj b/test/netstd/Client/Client.csproj
index 828ea73..d3504d4 100644
--- a/test/netstd/Client/Client.csproj
+++ b/test/netstd/Client/Client.csproj
@@ -20,6 +20,7 @@
 
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
+    <LangVersion>9.0</LangVersion>
     <AssemblyName>Client</AssemblyName>
     <PackageId>Client</PackageId>
     <OutputType>Exe</OutputType>
diff --git a/test/netstd/Client/Program.cs b/test/netstd/Client/Program.cs
index 7e502cd..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,8 +27,8 @@
     {
         public static int Main(string[] args)
         {
-            if (OperatingSystem.IsWindows())
-            { 
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+            {
                 try
                 {
                     Console.SetBufferSize(Console.BufferWidth, 4096);
@@ -69,5 +70,3 @@
         }
     }
 }
-
-
diff --git a/test/netstd/Server/Program.cs b/test/netstd/Server/Program.cs
index 0052bce..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,7 +27,7 @@
     {
         public static int Main(string[] args)
         {
-            if (OperatingSystem.IsWindows())
+            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
             {
                 try
                 {
@@ -65,5 +66,3 @@
         }
     }
 }
-
-
diff --git a/test/netstd/Server/Server.csproj b/test/netstd/Server/Server.csproj
index fe1c394..e2ec93c 100644
--- a/test/netstd/Server/Server.csproj
+++ b/test/netstd/Server/Server.csproj
@@ -20,6 +20,7 @@
 
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
+    <LangVersion>9.0</LangVersion>
     <AssemblyName>Server</AssemblyName>
     <PackageId>Server</PackageId>
     <OutputType>Exe</OutputType>
diff --git a/test/netstd/Server/TestServer.cs b/test/netstd/Server/TestServer.cs
index 895c3ff..471d6c8 100644
--- a/test/netstd/Server/TestServer.cs
+++ b/test/netstd/Server/TestServer.cs
@@ -60,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;
 
@@ -103,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")
                 {
@@ -613,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/tutorial/netstd/Client/Client.csproj b/tutorial/netstd/Client/Client.csproj
index 8a923e1..e91b7a9 100644
--- a/tutorial/netstd/Client/Client.csproj
+++ b/tutorial/netstd/Client/Client.csproj
@@ -20,6 +20,7 @@
 
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
+    <LangVersion>9.0</LangVersion>
     <AssemblyName>Client</AssemblyName>
     <PackageId>Client</PackageId>
     <OutputType>Exe</OutputType>
diff --git a/tutorial/netstd/Server/Server.csproj b/tutorial/netstd/Server/Server.csproj
index 9da3249..b63967b 100644
--- a/tutorial/netstd/Server/Server.csproj
+++ b/tutorial/netstd/Server/Server.csproj
@@ -20,6 +20,7 @@
 
   <PropertyGroup>
     <TargetFramework>net5.0</TargetFramework>
+    <LangVersion>9.0</LangVersion>
     <AssemblyName>Server</AssemblyName>
     <PackageId>Server</PackageId>
     <OutputType>Exe</OutputType>