Merge pull request #1690 from cyyever/const_members

THRIFT-4740:Use std::chrono for timeout and add const to some methods.
diff --git a/.gitignore b/.gitignore
index b3a5920..82d3d48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -196,6 +196,7 @@
 /lib/d/test/transport_test
 /lib/d/unittest/
 /lib/dart/coverage
+/lib/dart/**/.dart_tool
 /lib/dart/**/.packages
 /lib/dart/**/packages
 /lib/dart/**/.pub/
@@ -305,6 +306,7 @@
 /test/cpp/TestServer
 /test/csharp/obj
 /test/csharp/bin
+/test/dart/**/.dart_tool
 /test/dart/**/.packages
 /test/dart/**/packages
 /test/dart/**/.pub/
diff --git a/.travis.yml b/.travis.yml
index 75685d5..5b93140 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -68,18 +68,8 @@
 
     # ========================= stage: thrift =======================
     # ------------------------- phase: cross ------------------------
-    # apache/thrift official PR builds can exceed 50 minutes per job so combine all cross tests
     - stage: thrift
       script: build/docker/run.sh
-      if: repo = apache/thrift
-      env:
-        - JOB="Cross Language Tests"
-        - SCRIPT="cross-test.sh"
-
-    # fork based PR builds cannot exceed 50 minutes per job
-    - stage: thrift
-      script: build/docker/run.sh
-      if: repo != apache/thrift
       env:
         - JOB="Cross Language Tests (Binary Protocol)"
         - SCRIPT="cross-test.sh"
@@ -87,7 +77,6 @@
 
     - stage: thrift
       script: build/docker/run.sh
-      if: repo != apache/thrift
       env:
         - JOB="Cross Language Tests (Header, JSON Protocols)"
         - SCRIPT="cross-test.sh"
@@ -95,7 +84,6 @@
 
     - stage: thrift
       script: build/docker/run.sh
-      if: repo != apache/thrift
       env:
         - JOB="Cross Language Tests (Compact and Multiplexed Protocols)"
         - SCRIPT="cross-test.sh"
diff --git a/build/docker/README.md b/build/docker/README.md
index d00f87d..56b98a9 100644
--- a/build/docker/README.md
+++ b/build/docker/README.md
@@ -167,7 +167,7 @@
 
 | Language  | ubuntu-xenial | ubuntu-bionic | Notes |
 | :-------- | :------------ | :------------ | :---- |
-| as of     | Mar 06, 2018  | Jan 4, 2019   |       |
+| as of     | Mar 06, 2018  | Jan 21, 2019  |       |
 | as3       |               |               | Not in CI |
 | C++ gcc   | 5.4.0         | 7.3.0         |       |
 | C++ clang | 3.8           | 6.0           |       |
@@ -175,23 +175,23 @@
 | c_glib    | 2.48.2        | 2.56.0        |       |
 | cl (sbcl) |               | 1.4.15        |       |
 | d         | 2.075.1       | 2.083.1       |       |
-| dart      | 1.22.1        | 1.24.3        |       |
+| dart      | 1.24.3        | 2.1.0         |       |
 | delphi    |               |               | Not in CI |
-| dotnet    | 2.1.4         | 2.2.101       |       |
+| dotnet    | 2.1.503       | 2.2.103       |       |
 | erlang    | 18.3          | 20.2.2        |       |
 | go        | 1.7.6         | 1.11.4        |       |
 | haskell   | 7.10.3        | 8.0.2         |       |
 | haxe      | 3.2.1         | 3.4.4         | THRIFT-4352: avoid 3.4.2 |
-| java      | 1.8.0_151     | 1.8.0_191     |       |
+| java      | 1.8.0_191     | 1.8.0_191     |       |
 | js        |               |               | Unsure how to look for version info? |
 | lua       | 5.2.4         | 5.2.4         | Lua 5.3: see THRIFT-4386 |
-| nodejs    | 6.13.0        | 8.15.0        |       |
+| nodejs    | 6.16.0        | 8.15.0        |       |
 | ocaml     |               | 4.05.0        | THRIFT-4517: ocaml 4.02.3 on xenial appears broken |
 | perl      | 5.22.1        | 5.26.1        |       |
-| php       | 7.0.22        | 7.2.10        |       |
+| php       | 7.0.32        | 7.2.10        |       |
 | python    | 2.7.12        | 2.7.15rc1     |       |
 | python3   | 3.5.2         | 3.6.7         |       |
 | ruby      | 2.3.1p112     | 2.5.1p57      |       |
-| rust      | 1.17.0        | 1.30.0        |       |
+| rust      | 1.30.0        | 1.30.0        |       |
 | smalltalk |               |               | Not in CI |
 | swift     |               | 4.2.1         |       |
diff --git a/build/docker/ubuntu-bionic/Dockerfile b/build/docker/ubuntu-bionic/Dockerfile
index 43c99a9..db19112 100644
--- a/build/docker/ubuntu-bionic/Dockerfile
+++ b/build/docker/ubuntu-bionic/Dockerfile
@@ -15,7 +15,7 @@
 # Using all stock Ubuntu Bionic packaging except for:
 # - cl: want latest
 # - d: dmd does not come with Ubuntu
-# - dart: does not come with Ubuntu. Pinned to last 1.x release
+# - dart: does not come with Ubuntu - we use 2.x here
 # - dotnet: does not come with Ubuntu
 # - go: want latest
 # - nodejs: want v8, bionic comes with v6
@@ -46,7 +46,6 @@
 RUN 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 > \
       /etc/apt/sources.list.d/dart_stable.list
-ENV DART_VERSION 1.24.3-1
 
 # dotnet (netcore)
 RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \
@@ -118,6 +117,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.1.0-1
 RUN apt-get install -y --no-install-recommends \
       `# Dart dependencies` \
       dart=$DART_VERSION
diff --git a/build/docker/ubuntu-xenial/Dockerfile b/build/docker/ubuntu-xenial/Dockerfile
index 3372b4d..88895a0 100644
--- a/build/docker/ubuntu-xenial/Dockerfile
+++ b/build/docker/ubuntu-xenial/Dockerfile
@@ -14,7 +14,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
-# - dart: does not come with Ubuntu so we're installing 1.22.1 for coverage
+# - dart: does not come with Ubuntu so we're installing 1.24.3 for coverage
 # - dotnet: does not come with Ubuntu
 # - go: Xenial comes with 1.6, but we need 1.7 or later
 # - nodejs: Xenial comes with 4.2.6 which exits LTS April 2018, so we're installing 6.x
@@ -50,7 +50,6 @@
 RUN 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 > \
       /etc/apt/sources.list.d/dart_stable.list
-ENV DART_VERSION 1.22.1-1
 
 # dotnet (core)
 RUN curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/microsoft.gpg && \
@@ -120,6 +119,7 @@
     mv openssl-1.1.6-1.0.1g/C/* /usr/include/dmd/druntime/import/C/ && \
     rm -rf openssl-1.1.6-1.0.1g
 
+ENV DART_VERSION 1.24.3-1
 RUN apt-get install -y --no-install-recommends \
 `# Dart dependencies` \
       dart=$DART_VERSION
@@ -127,7 +127,7 @@
 
 RUN apt-get install -y --no-install-recommends \
 `# dotnet core dependencies` \
-      dotnet-sdk-2.1.4
+      dotnet-sdk-2.1
 
 RUN apt-get install -y --no-install-recommends \
 `# Erlang dependencies` \
diff --git a/compiler/cpp/src/thrift/generate/t_dart_generator.cc b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
index 414c333..c82d26c 100644
--- a/compiler/cpp/src/thrift/generate/t_dart_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_dart_generator.cc
@@ -423,7 +423,7 @@
 
   indent(f_pubspec) << "environment:" << endl;
   indent_up();
-  indent(f_pubspec) << "sdk: ^1.12.0" << endl;
+  indent(f_pubspec) << "sdk: '>=1.24.3 <3.0.0'" << endl;
   indent_down();
   f_pubspec << endl;
 
diff --git a/compiler/cpp/src/thrift/generate/t_go_generator.cc b/compiler/cpp/src/thrift/generate/t_go_generator.cc
index ec16b87..11246f3 100644
--- a/compiler/cpp/src/thrift/generate/t_go_generator.cc
+++ b/compiler/cpp/src/thrift/generate/t_go_generator.cc
@@ -1338,7 +1338,13 @@
       t_type* fieldType = (*m_iter)->get_type();
       string goType = type_to_go_type_with_opt(fieldType, is_pointer_field(*m_iter));
       string gotag = "db:\"" + escape_string((*m_iter)->get_name())  + "\" ";
-      if ((*m_iter)->get_req() == t_field::T_OPTIONAL) {
+
+      // Only add the `omitempty` tag if this field is optional and has no default value.
+      // Otherwise a proper value like `false` for a bool field will be ommitted from
+      // the JSON output since Go Marshal won't output `zero values`.
+      bool has_default = (*m_iter)->get_value();
+      bool is_optional = (*m_iter)->get_req() == t_field::T_OPTIONAL;
+      if (is_optional && !has_default) {
         gotag += "json:\"" + escape_string((*m_iter)->get_name()) + ",omitempty\"";
       } else {
         gotag += "json:\"" + escape_string((*m_iter)->get_name()) + "\"";
diff --git a/lib/dart/README.md b/lib/dart/README.md
index 2be168b..4c30291 100644
--- a/lib/dart/README.md
+++ b/lib/dart/README.md
@@ -23,4 +23,4 @@
 Using Thrift with Dart
 ====================
 
-Dart 1.12.0 or newer is required
+Dart 1.24.3 or newer is required
diff --git a/lib/dart/lib/src/browser/t_web_socket.dart b/lib/dart/lib/src/browser/t_web_socket.dart
index 17693b3..dac9ffd 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 'dart:convert' show BASE64;
+import 'package:dart2_constant/convert.dart' show base64;
 import 'dart:html' show CloseEvent;
 import 'dart:html' show Event;
 import 'dart:html' show MessageEvent;
@@ -90,7 +90,7 @@
   void _sendRequests() {
     while (isOpen && _requests.isNotEmpty) {
       Uint8List data = _requests.removeAt(0);
-      _socket.sendString(BASE64.encode(data));
+      _socket.sendString(base64.encode(data));
     }
   }
 
@@ -113,8 +113,7 @@
 
   void _onMessage(MessageEvent message) {
     try {
-      Uint8List data =
-          new Uint8List.fromList(BASE64.decode(message.data));
+      Uint8List data = new Uint8List.fromList(base64.decode(message.data));
       _onMessageController.add(data);
     } on FormatException catch (_) {
       var error = new TProtocolError(TProtocolErrorType.INVALID_DATA,
diff --git a/lib/dart/lib/src/console/t_web_socket.dart b/lib/dart/lib/src/console/t_web_socket.dart
index 4ed7284..c938a96 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 'dart:convert' show BASE64;
+import 'package:dart2_constant/convert.dart' show base64;
 import 'dart:io';
 import 'dart:typed_data' show Uint8List;
 
@@ -67,13 +67,12 @@
   }
 
   void send(Uint8List data) {
-    _socket.add(BASE64.encode(data));
+    _socket.add(base64.encode(data));
   }
 
   void _onMessage(String message) {
     try {
-      Uint8List data =
-          new Uint8List.fromList(BASE64.decode(message));
+      Uint8List data = new Uint8List.fromList(base64.decode(message));
       _onMessageController.add(data);
     } on FormatException catch (_) {
       var error = new TProtocolError(TProtocolErrorType.INVALID_DATA,
diff --git a/lib/dart/lib/src/protocol/t_compact_protocol.dart b/lib/dart/lib/src/protocol/t_compact_protocol.dart
index 72d7641..ee8094f 100644
--- a/lib/dart/lib/src/protocol/t_compact_protocol.dart
+++ b/lib/dart/lib/src/protocol/t_compact_protocol.dart
@@ -187,7 +187,7 @@
 
   void writeDouble(double d) {
     if (d == null) d = 0.0;
-    tempBD.setFloat64(0, d, Endianness.LITTLE_ENDIAN);
+    tempBD.setFloat64(0, d, Endianness.little);
     transport.write(tempBD.buffer.asUint8List(), 0, 8);
   }
 
@@ -364,7 +364,7 @@
 
   double readDouble() {
     transport.readAll(tempList, 0, 8);
-    return tempList.buffer.asByteData().getFloat64(0, Endianness.LITTLE_ENDIAN);
+    return tempList.buffer.asByteData().getFloat64(0, Endianness.little);
   }
 
   String readString() {
diff --git a/lib/dart/lib/src/protocol/t_json_protocol.dart b/lib/dart/lib/src/protocol/t_json_protocol.dart
index 7fbb7c4..180568d 100644
--- a/lib/dart/lib/src/protocol/t_json_protocol.dart
+++ b/lib/dart/lib/src/protocol/t_json_protocol.dart
@@ -155,8 +155,8 @@
     _context.write();
     transport.writeAll(_Constants.QUOTE_BYTES);
 
-    String base64 = BASE64.encode(bytes);
-    transport.writeAll(utf8Codec.encode(base64));
+    String base64text = base64.encode(bytes);
+    transport.writeAll(utf8Codec.encode(base64text));
 
     transport.writeAll(_Constants.QUOTE_BYTES);
   }
@@ -421,9 +421,9 @@
   Uint8List _readJsonBase64() {
     // convert UTF-8 bytes of a Base 64 encoded string to binary bytes
     Uint8List base64Bytes = _readJsonString();
-    String base64 = utf8Codec.decode(base64Bytes);
+    String base64text = utf8Codec.decode(base64Bytes);
 
-    return new Uint8List.fromList(BASE64.decode(base64));
+    return new Uint8List.fromList(base64.decode(base64text));
   }
 
   void _readJsonObjectStart() {
diff --git a/lib/dart/lib/src/serializer/t_deserializer.dart b/lib/dart/lib/src/serializer/t_deserializer.dart
index ed1d139..aefbee2 100644
--- a/lib/dart/lib/src/serializer/t_deserializer.dart
+++ b/lib/dart/lib/src/serializer/t_deserializer.dart
@@ -26,7 +26,7 @@
     this.transport = new TBufferedTransport();
     
     if (protocolFactory == null) {
-        protocolFactory = new TBinaryProtocolFactory();
+      protocolFactory = new TBinaryProtocolFactory();
     }
     
     this.protocol = protocolFactory.getProtocol(this.transport);
@@ -41,8 +41,8 @@
   }
 
   void readString(TBase base, String data) {
-    transport.writeAll(BASE64.decode(data));
     
+    transport.writeAll(base64.decode(data));
     transport.flush();
 
     base.read(protocol);
diff --git a/lib/dart/lib/src/serializer/t_serializer.dart b/lib/dart/lib/src/serializer/t_serializer.dart
index 20ddb6d..feec822 100644
--- a/lib/dart/lib/src/serializer/t_serializer.dart
+++ b/lib/dart/lib/src/serializer/t_serializer.dart
@@ -43,6 +43,6 @@
     
     Uint8List bytes = transport.consumeWriteBuffer();
     
-    return BASE64.encode(bytes);
+    return base64.encode(bytes);
   }
 }
diff --git a/lib/dart/lib/src/transport/t_http_transport.dart b/lib/dart/lib/src/transport/t_http_transport.dart
index aa78e9c..630213f 100644
--- a/lib/dart/lib/src/transport/t_http_transport.dart
+++ b/lib/dart/lib/src/transport/t_http_transport.dart
@@ -44,7 +44,7 @@
   }
 
   Future flush() {
-    var requestBody = BASE64.encode(consumeWriteBuffer());
+    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
@@ -56,8 +56,7 @@
         .then((response) {
       Uint8List data;
       try {
-        data = new Uint8List.fromList(
-            BASE64.decode(response.body));
+        data = new Uint8List.fromList(base64.decode(response.body));
       } on FormatException catch (_) {
         throw new TProtocolError(TProtocolErrorType.INVALID_DATA,
             "Expected a Base 64 encoded string.");
diff --git a/lib/dart/lib/thrift.dart b/lib/dart/lib/thrift.dart
index 3d9bb01..c429d77 100644
--- a/lib/dart/lib/thrift.dart
+++ b/lib/dart/lib/thrift.dart
@@ -19,11 +19,12 @@
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:convert' show Utf8Codec, BASE64;
+import 'dart:convert' show Utf8Codec;
 import 'dart:typed_data' show ByteData;
-import 'dart:typed_data' show Endianness;
 import 'dart:typed_data' show Uint8List;
 
+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 fdc4a0d..ded0269 100644
--- a/lib/dart/pubspec.yaml
+++ b/lib/dart/pubspec.yaml
@@ -24,20 +24,15 @@
 documentation: http://thrift.apache.org
 
 environment:
-  sdk: ">=1.13.0 <2.0.0"
+  sdk: ">=1.24.3 <3.0.0"
 
 dependencies:
+  dart2_constant: ^1.0.0
   fixnum: ^0.10.2
   http: ^0.11.3
   logging: ^0.11.0
 
 dev_dependencies:
-  # test
-  mockito: ^1.0.0
-  test: ^0.12.0
-
-  # dart_dev - https://github.com/Workiva/dart_dev
-  dart_dev: ^1.5.0
-  coverage: ^0.7.3
-  dart_style: ">=0.2.4 <0.3.0"
-  dartdoc: ^0.9.0
+  dart_dev: ^2.0.0
+  mockito: ">=2.2.2 <4.0.0"
+  test: ">=0.12.30 <2.0.0"
diff --git a/lib/dart/test/protocol/t_protocol_test.dart b/lib/dart/test/protocol/t_protocol_test.dart
index 0e6cde5..dc63dbb 100644
--- a/lib/dart/test/protocol/t_protocol_test.dart
+++ b/lib/dart/test/protocol/t_protocol_test.dart
@@ -18,9 +18,9 @@
 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';
 
@@ -362,7 +362,7 @@
            UTF-8:  0xF0 0x9D 0x84 0x9E
            UTF-16: 0xD834 0xDD1E
        */
-      var buffer = UTF8.encode(r'"\u0001\u0e01 \ud834\udd1e"');
+      var buffer = utf8.encode(r'"\u0001\u0e01 \ud834\udd1e"');
       var transport = new TBufferedTransport();
       transport.writeAll(buffer);
 
@@ -372,7 +372,7 @@
 
       var subject = protocol.readString();
       expect(subject,
-          UTF8.decode([0x01, 0xE0, 0xB8, 0x81, 0x20, 0xF0, 0x9D, 0x84, 0x9E]));
+          utf8.decode([0x01, 0xE0, 0xB8, 0x81, 0x20, 0xF0, 0x9D, 0x84, 0x9E]));
     });
 
     group('shared tests', sharedTests);
diff --git a/lib/dart/test/transport/t_framed_transport_test.dart b/lib/dart/test/transport/t_framed_transport_test.dart
index e072e68..7ab4905 100644
--- a/lib/dart/test/transport/t_framed_transport_test.dart
+++ b/lib/dart/test/transport/t_framed_transport_test.dart
@@ -18,9 +18,9 @@
 library thrift.test.transport.t_framed_transport_test;
 
 import 'dart:async';
-import 'dart:convert';
 import 'dart:typed_data' show Uint8List;
 
+import 'package:dart2_constant/convert.dart' show utf8;
 import 'package:test/test.dart';
 import 'package:thrift/thrift.dart';
 
@@ -66,14 +66,14 @@
       expectNoReadableBytes();
 
       // write first batch of body
-      socket.messageController.add(new Uint8List.fromList(UTF8.encode("He")));
+      socket.messageController.add(new 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(new 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
@@ -83,7 +83,7 @@
       // at this point the frame is complete, so we expect the read to complete
       readBytes = transport.read(readBuffer, 0, readBuffer.lengthInBytes);
       expect(readBytes, 6);
-      expect(readBuffer.sublist(0, 6), UTF8.encode("Hello!"));
+      expect(readBuffer.sublist(0, 6), utf8.encode("Hello!"));
     });
 
     test('Test transport reads messages where header is sent in pieces '
@@ -112,14 +112,14 @@
       readBytes = expectNoReadableBytes();
 
       // write first batch of body
-      socket.messageController.add(new Uint8List.fromList(UTF8.encode("H")));
+      socket.messageController.add(new 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(new 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
@@ -129,7 +129,7 @@
       // at this point the frame is complete, so we expect the read to complete
       readBytes = transport.read(readBuffer, 0, readBuffer.lengthInBytes);
       expect(readBytes, 3);
-      expect(readBuffer.sublist(0, 3), UTF8.encode("Hi!"));
+      expect(readBuffer.sublist(0, 3), utf8.encode("Hi!"));
     });
   });
 }
diff --git a/lib/dart/test/transport/t_http_transport_test.dart b/lib/dart/test/transport/t_http_transport_test.dart
index 66f3d05..03ccede 100644
--- a/lib/dart/test/transport/t_http_transport_test.dart
+++ b/lib/dart/test/transport/t_http_transport_test.dart
@@ -19,9 +19,10 @@
 
 import 'dart:async';
 import 'dart:convert' show Encoding;
-import 'dart:convert' show Utf8Codec, BASE64;
+import 'dart:convert' show Utf8Codec;
 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;
@@ -52,15 +53,14 @@
 
       expect(client.postRequest, isNotEmpty);
 
-      var requestText =
-          utf8Codec.decode(BASE64.decode(client.postRequest));
+      var requestText = utf8Codec.decode(base64.decode(client.postRequest));
       expect(requestText, expectedText);
     });
 
     test('Test transport receives response', () async {
       var expectedText = 'my response';
       var expectedBytes = utf8Codec.encode(expectedText);
-      client.postResponse = BASE64.encode(expectedBytes);
+      client.postResponse = base64.encode(expectedBytes);
 
       transport.writeAll(utf8Codec.encode('my request'));
       expect(transport.hasReadData, isFalse);
@@ -94,7 +94,7 @@
 
       // prepare a response
       transport.writeAll(utf8Codec.encode('request 1'));
-      client.postResponse = BASE64.encode(expectedBytes);
+      client.postResponse = base64.encode(expectedBytes);
 
       Future responseReady = transport.flush().then((_) {
         var buffer = new Uint8List(expectedBytes.length);
@@ -105,7 +105,7 @@
       // prepare a second response
       transport.writeAll(utf8Codec.encode('request 2'));
       var response2Bytes = utf8Codec.encode('response 2');
-      client.postResponse = BASE64.encode(response2Bytes);
+      client.postResponse = base64.encode(response2Bytes);
       await transport.flush();
 
       await responseReady;
diff --git a/lib/dart/test/transport/t_socket_transport_test.dart b/lib/dart/test/transport/t_socket_transport_test.dart
index 929ab17..90bffbe 100644
--- a/lib/dart/test/transport/t_socket_transport_test.dart
+++ b/lib/dart/test/transport/t_socket_transport_test.dart
@@ -18,9 +18,11 @@
 library thrift.test.transport.t_socket_transport_test;
 
 import 'dart:async';
-import 'dart:convert' show Utf8Codec, BASE64;
+import 'dart:convert' show Utf8Codec;
 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';
@@ -30,14 +32,13 @@
 
   final requestText = 'my test request';
   final requestBytes = new Uint8List.fromList(utf8Codec.encode(requestText));
-  final requestBase64 = BASE64.encode(requestBytes);
+  final requestBase64 = base64.encode(requestBytes);
 
   final responseText = 'response 1';
   final responseBytes = new Uint8List.fromList(utf8Codec.encode(responseText));
-  final responseBase64 = BASE64.encode(responseBytes);
+  final responseBase64 = base64.encode(responseBytes);
 
-  final framedResponseBase64 =
-      BASE64.encode(_getFramedResponse(responseBytes));
+  final framedResponseBase64 = base64.encode(_getFramedResponse(responseBytes));
 
   group('TClientSocketTransport', () {
     FakeSocket socket;
@@ -117,7 +118,7 @@
       protocolFactory.message = new TMessage('foo', TMessageType.CALL, 123);
       transport = new TAsyncClientSocketTransport(
           socket, new TMessageReader(protocolFactory),
-          responseTimeout: Duration.ZERO);
+          responseTimeout: core.Duration.zero);
       await transport.open();
       transport.writeAll(requestBytes);
     });
@@ -139,7 +140,7 @@
       var response2Text = 'response 2';
       var response2Bytes =
           new Uint8List.fromList(utf8Codec.encode(response2Text));
-      var response2Base64 = BASE64.encode(response2Bytes);
+      var response2Base64 = base64.encode(response2Bytes);
       protocolFactory.message = new TMessage('foo2', TMessageType.REPLY, 124);
       socket.receiveFakeMessage(response2Base64);
 
@@ -169,7 +170,7 @@
 
       transport = new TFramedTransport(new TAsyncClientSocketTransport(
           socket, messageReader,
-          responseTimeout: Duration.ZERO));
+          responseTimeout: core.Duration.zero));
       await transport.open();
       transport.writeAll(requestBytes);
     });
@@ -275,11 +276,10 @@
     _sendPayload = data;
   }
 
-  void receiveFakeMessage(String base64) {
+  void receiveFakeMessage(String base64text) {
     if (!isOpen) throw new StateError('The socket is not open');
 
-    var message =
-        new Uint8List.fromList(BASE64.decode(base64));
+    var message = new Uint8List.fromList(base64.decode(base64text));
     _onMessageController.add(message);
   }
 }
diff --git a/lib/go/test/GoTagTest.thrift b/lib/go/test/GoTagTest.thrift
index 508b3b6..5667c6e 100644
--- a/lib/go/test/GoTagTest.thrift
+++ b/lib/go/test/GoTagTest.thrift
@@ -21,4 +21,5 @@
     1: string string_thing,
     2: i64 int_thing (go.tag = "json:\"int_thing,string\""),
     3: optional i64 optional_int_thing
+    4: optional bool optional_bool_thing = false
 }
diff --git a/lib/go/test/tests/gotag_test.go b/lib/go/test/tests/gotag_test.go
index 32f056f..ff2f14e 100644
--- a/lib/go/test/tests/gotag_test.go
+++ b/lib/go/test/tests/gotag_test.go
@@ -51,3 +51,12 @@
 		t.Error("Unexpected default tag value for optional field")
 	}
 }
+
+func TestOptionalTagWithDefaultValue(t *testing.T) {
+	s := gotagtest.Tagged{}
+	st := reflect.TypeOf(s)
+	field, ok := st.FieldByName("OptionalBoolThing")
+	if !ok || field.Tag.Get("json") != "optional_bool_thing" {
+		t.Error("Unexpected default tag value for optional field that has a default value")
+	}
+}
diff --git a/test/dart/test_client/pubspec.yaml b/test/dart/test_client/pubspec.yaml
index d1642f8..113054a 100644
--- a/test/dart/test_client/pubspec.yaml
+++ b/test/dart/test_client/pubspec.yaml
@@ -22,10 +22,10 @@
 homepage: http://thrift.apache.org
 
 environment:
-  sdk: ">=1.13.0 <2.0.0"
+  sdk: ">=1.24.3 <3.0.0"
 
 dependencies:
-  args: ^0.13.0
+  args: ">=0.13.0 <2.0.0"
   http: ^0.11.0
   thrift:
     path: ../../../lib/dart
@@ -33,4 +33,4 @@
     path: ../gen-dart/thrift_test
 
 dev_dependencies:
-  test: "^0.12.0"
+  test: ">=0.12.30 <2.0.0"
diff --git a/test/tests.json b/test/tests.json
index 43d6ded..3381a1f 100644
--- a/test/tests.json
+++ b/test/tests.json
@@ -562,6 +562,7 @@
   {
     "name": "dart",
     "client": {
+      "timeout": 15,
       "transports": [
         "buffered",
         "framed",
@@ -577,6 +578,7 @@
       ],
       "command": [
         "dart",
+	"--enable-asserts",
         "test_client/bin/main.dart"
       ]
     },
diff --git a/tutorial/dart/client/pubspec.yaml b/tutorial/dart/client/pubspec.yaml
index d8ede14..109db0f 100644
--- a/tutorial/dart/client/pubspec.yaml
+++ b/tutorial/dart/client/pubspec.yaml
@@ -22,10 +22,9 @@
 homepage: http://thrift.apache.org
 
 environment:
-  sdk: ">=1.13.0 <2.0.0"
+  sdk: ">=1.13.0 <3.0.0"
 
 dependencies:
-  browser: ^0.10.0
   shared:
     path: ../gen-dart/shared
   thrift:
diff --git a/tutorial/dart/client/web/index.html b/tutorial/dart/client/web/index.html
index 64b184e..9d36b43 100644
--- a/tutorial/dart/client/web/index.html
+++ b/tutorial/dart/client/web/index.html
@@ -24,8 +24,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Thrift Tutorial</title>
     <link rel="stylesheet" href="styles.css">
-    <script async src="client.dart" type="application/dart"></script>
-    <script async src="packages/browser/dart.js"></script>
+  <script async src="client.dart.js"></script>
 </head>
 
 <body>
diff --git a/tutorial/dart/console_client/pubspec.yaml b/tutorial/dart/console_client/pubspec.yaml
index a34e26f..602bb5e 100644
--- a/tutorial/dart/console_client/pubspec.yaml
+++ b/tutorial/dart/console_client/pubspec.yaml
@@ -23,10 +23,10 @@
 homepage: http://thrift.apache.org
 
 environment:
-  sdk: ">=1.13.0 <2.0.0"
+  sdk: ">=1.13.0 <3.0.0"
 
 dependencies:
-  args: ^0.13.0
+  args: ">=0.13.0 <2.0.0"
   collection: ^1.1.0
   shared:
     path: ../gen-dart/shared
diff --git a/tutorial/dart/server/pubspec.yaml b/tutorial/dart/server/pubspec.yaml
index 18d0737..b0b012d 100644
--- a/tutorial/dart/server/pubspec.yaml
+++ b/tutorial/dart/server/pubspec.yaml
@@ -22,10 +22,10 @@
 homepage: http://thrift.apache.org
 
 environment:
-  sdk: ">=1.13.0 <2.0.0"
+  sdk: ">=1.13.0 <3.0.0"
 
 dependencies:
-  args: ^0.13.0
+  args: ">=0.13.0 <2.0.0"
   shared:
     path: ../gen-dart/shared
   thrift: