Merge branch 'master' into null_safety
diff --git a/.travis.yml b/.travis.yml
index 0d83a59..7ccf79c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,22 +1,43 @@
 language: dart
 dart:
-  - stable
   - dev
 
-dart_task:
-  - test: -p vm
-  - test: -p firefox
-  - dartanalyzer: --fatal-infos --fatal-warnings .
-
-matrix:
+jobs:
   include:
-  # Only validate formatting using the dev release
-  - dart: dev
-    dart_task: dartfmt
+    - stage: analyze_and_format
+      name: "Analyze lib/"
+      dart: dev
+      os: linux
+      script: dartanalyzer --fatal-warnings --fatal-infos lib/
+    # Dirs outside of `lib` are not supported by allowed_experiments.json
+    - stage: analyze_and_format
+      name: "Analyze test/"
+      dart: dev
+      os: linux
+      script: dartanalyzer --enable-experiment=non-nullable --fatal-warnings --fatal-infos test/
+    - stage: analyze_and_format
+      name: "Format"
+      dart: dev
+      os: linux
+      script: dartfmt -n --set-exit-if-changed .
+    - stage: test
+      name: "Vm Tests"
+      dart: dev
+      os: linux
+      script: pub run --enable-experiment=non-nullable test -p vm 
+    - stage: test
+      name: "Web Tests"
+      dart: dev
+      os: linux
+      script: pub run --enable-experiment=non-nullable test -p chrome
+
+stages:
+  - analyze_and_format
+  - test
 
 # Only building master means that we don't run two builds for each pull request.
 branches:
-  only: [master]
+  only: [master, null_safety]
 
 cache:
  directories:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7edf873..a35d3c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,12 @@
+## 1.3.0-nnbd
+
+* Migrate to NNBD
+
 ## 1.2.0
 
 * Add typed queue classes such as `Uint8Queue`. These classes implement both
   `Queue` and `List` with a highly-efficient typed-data-backed implementation.
   Their `sublist()` methods also return typed data classes.
-
 * Update min Dart SDK to `2.4.0`.
 
 ## 1.1.6
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 4a774a7..c03796b 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -6,6 +6,8 @@
   errors:
     annotate_overrides: ignore
     prefer_single_quotes: ignore
+  enable-experiment:
+    - non-nullable
 
 linter:
   rules:
diff --git a/lib/src/typed_buffer.dart b/lib/src/typed_buffer.dart
index f85bd16..37933f9 100644
--- a/lib/src/typed_buffer.dart
+++ b/lib/src/typed_buffer.dart
@@ -82,7 +82,7 @@
   /// least [start] elements, and if [end] is specified, it must be greater than
   /// or equal to [start] and [values] must have at least [end] elements.
   @override
-  void addAll(Iterable<E> values, [int start = 0, int end]) {
+  void addAll(Iterable<E> values, [int start = 0, int? end]) {
     RangeError.checkNotNegative(start, 'start');
     if (end != null && start > end) {
       throw RangeError.range(end, start, null, 'end');
@@ -101,7 +101,7 @@
   /// least [start] elements, and if [end] is specified, it must be greater than
   /// or equal to [start] and [values] must have at least [end] elements.
   @override
-  void insertAll(int index, Iterable<E> values, [int start = 0, int end]) {
+  void insertAll(int index, Iterable<E> values, [int start = 0, int? end]) {
     RangeError.checkValidIndex(index, this, 'index', _length + 1);
     RangeError.checkNotNegative(start, 'start');
     if (end != null) {
@@ -176,7 +176,7 @@
   /// This allows [addAll] and [insertAll] to share implementation without a
   /// subclass unexpectedly overriding both when it intended to only override
   /// [addAll].
-  void _addAll(Iterable<E> values, [int start = 0, int end]) {
+  void _addAll(Iterable<E> values, [int start = 0, int? end]) {
     if (values is List) end ??= values.length;
 
     // If we know the length of the segment to add, do so with [addRange]. This
@@ -199,12 +199,9 @@
   /// Like [insertAll], but with a guaranteed non-`null` [start] and [end].
   void _insertKnownLength(int index, Iterable<E> values, int start, int end) {
     if (values is List) {
-      end ??= values.length;
       if (start > values.length || end > values.length) {
         throw StateError('Too few elements');
       }
-    } else {
-      assert(end != null);
     }
 
     var valuesLength = end - start;
@@ -252,7 +249,7 @@
   /// be. If [requiredCapacity] is not null, it will be at least that
   /// size. It will always have at least have double the capacity of
   /// the current buffer.
-  List<E> _createBiggerBuffer(int requiredCapacity) {
+  List<E> _createBiggerBuffer(int? requiredCapacity) {
     var newLength = _buffer.length * 2;
     if (requiredCapacity != null && newLength < requiredCapacity) {
       newLength = requiredCapacity;
diff --git a/lib/src/typed_queue.dart b/lib/src/typed_queue.dart
index 13e63d4..a7ee91a 100644
--- a/lib/src/typed_queue.dart
+++ b/lib/src/typed_queue.dart
@@ -21,8 +21,9 @@
   int _tail;
 
   /// Create an empty queue.
-  _TypedQueue(this._table)
-      : _head = 0,
+  _TypedQueue(List<E> table)
+      : _table = table as L,
+        _head = 0,
         _tail = 0;
 
   // Iterable interface.
@@ -230,7 +231,7 @@
     }
   }
 
-  void fillRange(int start, int end, [E value]) {
+  void fillRange(int start, int end, [E? value]) {
     var startInTable = (_head + start) & (_table.length - 1);
     var endInTable = (_head + end) & (_table.length - 1);
     if (startInTable <= endInTable) {
@@ -241,12 +242,12 @@
     }
   }
 
-  L sublist(int start, [int end]) {
+  L sublist(int start, [int? end]) {
     var length = this.length;
-    end = RangeError.checkValidRange(start, end, length);
+    var nonNullEnd = RangeError.checkValidRange(start, end, length);
 
-    var list = _createList(end - start);
-    _writeToList(list, start, end);
+    var list = _createList(nonNullEnd - start);
+    _writeToList(list, start, nonNullEnd);
     return list;
   }
 
@@ -259,7 +260,7 @@
   /// start)`, but it's more efficient when [target] is typed data.
   ///
   /// Returns the number of elements written to [target].
-  int _writeToList(List<E> target, [int start, int end]) {
+  int _writeToList(List<E> target, [int? start, int? end]) {
     start ??= 0;
     end ??= length;
     assert(target.length >= end - start);
@@ -346,7 +347,7 @@
 class Uint8Queue extends _IntQueue<Uint8List> implements QueueList<int> {
   /// Creates an empty [Uint8Queue] with the given initial internal capacity (in
   /// elements).
-  Uint8Queue([int initialCapacity])
+  Uint8Queue([int? initialCapacity])
       : super(Uint8List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Uint8Queue] with the same length and contents as [elements].
@@ -368,7 +369,7 @@
 class Int8Queue extends _IntQueue<Int8List> implements QueueList<int> {
   /// Creates an empty [Int8Queue] with the given initial internal capacity (in
   /// elements).
-  Int8Queue([int initialCapacity])
+  Int8Queue([int? initialCapacity])
       : super(Int8List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Int8Queue] with the same length and contents as [elements].
@@ -391,7 +392,7 @@
     implements QueueList<int> {
   /// Creates an empty [Uint8ClampedQueue] with the given initial internal
   /// capacity (in elements).
-  Uint8ClampedQueue([int initialCapacity])
+  Uint8ClampedQueue([int? initialCapacity])
       : super(Uint8ClampedList(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Uint8ClampedQueue] with the same length and contents as
@@ -413,7 +414,7 @@
 class Uint16Queue extends _IntQueue<Uint16List> implements QueueList<int> {
   /// Creates an empty [Uint16Queue] with the given initial internal capacity
   /// (in elements).
-  Uint16Queue([int initialCapacity])
+  Uint16Queue([int? initialCapacity])
       : super(Uint16List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Uint16Queue] with the same length and contents as [elements].
@@ -435,7 +436,7 @@
 class Int16Queue extends _IntQueue<Int16List> implements QueueList<int> {
   /// Creates an empty [Int16Queue] with the given initial internal capacity (in
   /// elements).
-  Int16Queue([int initialCapacity])
+  Int16Queue([int? initialCapacity])
       : super(Int16List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Int16Queue] with the same length and contents as [elements].
@@ -456,7 +457,7 @@
 class Uint32Queue extends _IntQueue<Uint32List> implements QueueList<int> {
   /// Creates an empty [Uint32Queue] with the given initial internal capacity
   /// (in elements).
-  Uint32Queue([int initialCapacity])
+  Uint32Queue([int? initialCapacity])
       : super(Uint32List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Uint32Queue] with the same length and contents as [elements].
@@ -478,7 +479,7 @@
 class Int32Queue extends _IntQueue<Int32List> implements QueueList<int> {
   /// Creates an empty [Int32Queue] with the given initial internal capacity (in
   /// elements).
-  Int32Queue([int initialCapacity])
+  Int32Queue([int? initialCapacity])
       : super(Int32List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Int32Queue] with the same length and contents as [elements].
@@ -500,7 +501,7 @@
 class Uint64Queue extends _IntQueue<Uint64List> implements QueueList<int> {
   /// Creates an empty [Uint64Queue] with the given initial internal capacity
   /// (in elements).
-  Uint64Queue([int initialCapacity])
+  Uint64Queue([int? initialCapacity])
       : super(Uint64List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Uint64Queue] with the same length and contents as [elements].
@@ -522,7 +523,7 @@
 class Int64Queue extends _IntQueue<Int64List> implements QueueList<int> {
   /// Creates an empty [Int64Queue] with the given initial internal capacity (in
   /// elements).
-  Int64Queue([int initialCapacity])
+  Int64Queue([int? initialCapacity])
       : super(Int64List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Int64Queue] with the same length and contents as [elements].
@@ -545,7 +546,7 @@
     implements QueueList<double> {
   /// Creates an empty [Float32Queue] with the given initial internal capacity
   /// (in elements).
-  Float32Queue([int initialCapacity])
+  Float32Queue([int? initialCapacity])
       : super(Float32List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Float32Queue] with the same length and contents as [elements].
@@ -565,7 +566,7 @@
     implements QueueList<double> {
   /// Creates an empty [Float64Queue] with the given initial internal capacity
   /// (in elements).
-  Float64Queue([int initialCapacity])
+  Float64Queue([int? initialCapacity])
       : super(Float64List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Float64Queue] with the same length and contents as [elements].
@@ -586,7 +587,7 @@
 
   /// Creates an empty [Int32x4Queue] with the given initial internal capacity
   /// (in elements).
-  Int32x4Queue([int initialCapacity])
+  Int32x4Queue([int? initialCapacity])
       : super(Int32x4List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Int32x4Queue] with the same length and contents as [elements].
@@ -606,7 +607,7 @@
     implements QueueList<Float32x4> {
   /// Creates an empty [Float32x4Queue] with the given initial internal capacity (in
   /// elements).
-  Float32x4Queue([int initialCapacity])
+  Float32x4Queue([int? initialCapacity])
       : super(Float32x4List(_chooseRealInitialCapacity(initialCapacity)));
 
   /// Creates a [Float32x4Queue] with the same length and contents as [elements].
@@ -623,7 +624,7 @@
 
 /// Choose the next-highest power of two given a user-specified
 /// [initialCapacity] for a queue.
-int _chooseRealInitialCapacity(int initialCapacity) {
+int _chooseRealInitialCapacity(int? initialCapacity) {
   if (initialCapacity == null || initialCapacity < _defaultInitialCapacity) {
     return _defaultInitialCapacity;
   } else if (!_isPowerOf2(initialCapacity)) {
diff --git a/pubspec.yaml b/pubspec.yaml
index 564b1a5..7bdb374 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,16 +1,103 @@
 name: typed_data
-version: 1.2.0
+version: 1.3.0-nnbd
 
 description: >-
   Utility functions and classes related to the dart:typed_data library.
 homepage: https://github.com/dart-lang/typed_data
 
 environment:
-  sdk: '>=2.4.0 <3.0.0'
+  sdk: '>=2.9.0-18.0 <2.9.0'
 
 dependencies:
-  collection: ^1.1.0
+  collection: ^1.15.0-nnbd
 
 dev_dependencies:
   pedantic: ^1.9.0
   test: ^1.0.0
+
+dependency_overrides:
+  async:
+    git:
+      url: git://github.com/dart-lang/async.git
+      ref: null_safety
+  boolean_selector:
+    git:
+      url: git://github.com/dart-lang/boolean_selector.git
+      ref: null_safety
+  charcode:
+    git:
+      url: git://github.com/dart-lang/charcode.git
+      ref: null_safety
+  collection:
+    git:
+      url: git://github.com/dart-lang/collection.git
+      ref: null_safety
+  js:
+    git:
+      url: git://github.com/dart-lang/sdk.git
+      ref: null_safety-pkgs
+      path: pkg/js
+  matcher:
+    git:
+      url: git://github.com/dart-lang/matcher.git
+      ref: null_safety
+  meta:
+    git:
+      url: git://github.com/dart-lang/sdk.git
+      ref: null_safety-pkgs
+      path: pkg/meta
+  path:
+    git:
+      url: git://github.com/dart-lang/path.git
+      ref: null_safety
+  pedantic:
+    git:
+      url: git://github.com/dart-lang/pedantic.git
+      ref: null_safety
+  pool:
+    git:
+      url: git://github.com/dart-lang/pool.git
+      ref: null_safety
+  source_maps:
+    git:
+      url: git://github.com/dart-lang/source_maps.git
+      ref: null_safety
+  source_map_stack_trace:
+    git:
+      url: git://github.com/dart-lang/source_map_stack_trace.git
+      ref: null_safety
+  source_span:
+    git:
+      url: git://github.com/dart-lang/source_span.git
+      ref: null_safety
+  stack_trace:
+    git:
+      url: git://github.com/dart-lang/stack_trace.git
+      ref: null_safety
+  stream_channel:
+    git:
+      url: git://github.com/dart-lang/stream_channel.git
+      ref: null_safety
+  string_scanner:
+    git:
+      url: git://github.com/dart-lang/string_scanner.git
+      ref: null_safety
+  term_glyph:
+    git:
+      url: git://github.com/dart-lang/term_glyph.git
+      ref: null_safety
+  test_api:
+    git:
+      url: git://github.com/dart-lang/test.git
+      ref: null_safety
+      path: pkgs/test_api
+  test_core:
+    git:
+      url: git://github.com/dart-lang/test.git
+      ref: null_safety
+      path: pkgs/test_core
+  test:
+    git:
+      url: git://github.com/dart-lang/test.git
+      ref: null_safety
+      path: pkgs/test
diff --git a/test/queue_test.dart b/test/queue_test.dart
index 82d96f6..ccd93ac 100644
--- a/test/queue_test.dart
+++ b/test/queue_test.dart
@@ -225,7 +225,7 @@
   });
 
   group("throws a modification error for", () {
-    Uint8Queue queue;
+    late Uint8Queue queue;
     setUp(() {
       queue = Uint8Queue.fromList([1, 2, 3]);
     });
diff --git a/test/typed_buffers_test.dart b/test/typed_buffers_test.dart
index 174806b..f5aea86 100644
--- a/test/typed_buffers_test.dart
+++ b/test/typed_buffers_test.dart
@@ -74,8 +74,8 @@
   group('addAll', () {
     for (var type in ['a list', 'an iterable']) {
       group('with $type', () {
-        Iterable<int> source;
-        Uint8Buffer buffer;
+        late Iterable<int> source;
+        late Uint8Buffer buffer;
         setUp(() {
           source = [1, 2, 3, 4, 5];
           if (type == 'an iterable') {
@@ -127,8 +127,8 @@
   group('insertAll', () {
     for (var type in ['a list', 'an iterable']) {
       group('with $type', () {
-        Iterable<int> source;
-        Uint8Buffer buffer;
+        late Iterable<int> source;
+        late Uint8Buffer buffer;
         setUp(() {
           source = [1, 2, 3, 4, 5];
           if (type == 'an iterable') {
@@ -376,7 +376,7 @@
   List<int> intSamples,
   int bits,
   TypedDataBuffer<int> Function(int length) buffer, {
-  String testOn,
+  String? testOn,
 }) {
   var min = -(1 << (bits - 1));
   var max = -(min + 1);
@@ -525,7 +525,7 @@
   List<int> intSamples,
   int bits,
   TypedDataBuffer<int> Function(int length) buffer, {
-  String testOn,
+  String? testOn,
 }) {
   var min = 0;
   var rounder = uintRounder(bits);