migrate to null safety (#16)

diff --git a/.github/workflows/test-package.yml b/.github/workflows/test-package.yml
index bd3c848..21a3c50 100644
--- a/.github/workflows/test-package.yml
+++ b/.github/workflows/test-package.yml
@@ -59,27 +59,3 @@
       - name: Run VM tests
         run: dart test --platform vm
         if: always() && steps.install.outcome == 'success'
-
-  # Run tests on a matrix consisting of two dimensions:
-  # 1. OS: ubuntu-latest, (macos-latest, windows-latest)
-  # 2. release channel: 2.8.0
-  test-legacy-sdk:
-    needs: analyze
-    runs-on: ${{ matrix.os }}
-    strategy:
-      fail-fast: false
-      matrix:
-        # Add macos-latest and/or windows-latest if relevant for this package.
-        os: [ubuntu-latest]
-        sdk: [2.8.4]
-    steps:
-      - uses: actions/checkout@v2
-      - uses: dart-lang/setup-dart@v0.3
-        with:
-          sdk: ${{ matrix.sdk }}
-      - id: install
-        name: Install dependencies
-        run: pub get
-      - name: Run VM tests
-        run: pub run test --platform vm
-        if: always() && steps.install.outcome == 'success'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 63fcfe2..5bf529e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,10 @@
+## 3.0.0-dev
+
+* Migrate to null safety.
+
 ## 2.0.1
 
-- Allow the latest (null-safe) version of `pkg:shelf`.
+* Allow the latest (null-safe) version of `pkg:shelf`.
 
 ## 2.0.0
 
@@ -17,17 +21,17 @@
 
 ## 1.0.3
 
-- Require Dart SDK 1.22.0
-- Support `package:async` v2
+* Require Dart SDK 1.22.0
+* Support `package:async` v2
 
 ## 1.0.2
 
-- Fix Strong mode errors with `package:shelf` v0.7.x
+* Fix Strong mode errors with `package:shelf` v0.7.x
 
 ## 1.0.1
 
-- Allow dependencies on `package:shelf` v0.7.x
+* Allow dependencies on `package:shelf` v0.7.x
 
 ## 0.0.1
 
-- Initial version
+* Initial version
diff --git a/lib/shelf_packages_handler.dart b/lib/shelf_packages_handler.dart
index 694dcb5..165314a 100644
--- a/lib/shelf_packages_handler.dart
+++ b/lib/shelf_packages_handler.dart
@@ -19,7 +19,7 @@
 /// `package:` uris for that package.
 ///
 /// This can only serve assets from `file:` URIs.
-Handler packagesHandler({Map<String, Uri> packageMap}) =>
+Handler packagesHandler({Map<String, Uri>? packageMap}) =>
     PackageConfigHandler(packageMap: packageMap).handleRequest;
 
 /// A handler that serves virtual `packages/` directories wherever they're
@@ -30,5 +30,5 @@
 ///
 /// This is useful for ensuring that `package:` imports work for all entrypoints
 /// in Dartium.
-Handler packagesDirHandler({Map<String, Uri> packageMap}) =>
+Handler packagesDirHandler({Map<String, Uri>? packageMap}) =>
     DirHandler('packages', packagesHandler(packageMap: packageMap));
diff --git a/lib/src/package_config_handler.dart b/lib/src/package_config_handler.dart
index 8e6a761..460885f 100644
--- a/lib/src/package_config_handler.dart
+++ b/lib/src/package_config_handler.dart
@@ -18,9 +18,9 @@
 
   /// Optional, a map of package names to base uri for resolving `package:`
   /// uris for that package.
-  final Map<String, Uri> _packageMap;
+  final Map<String, Uri>? _packageMap;
 
-  PackageConfigHandler({Map<String, Uri> packageMap})
+  PackageConfigHandler({Map<String, Uri>? packageMap})
       : _packageMap = packageMap;
 
   /// The callback for handling a single request.
@@ -34,9 +34,9 @@
   /// [_packageMap] or the current isolate resolver.
   Future<Handler> _handlerFor(String packageName) =>
       _packageHandlers.putIfAbsent(packageName, () async {
-        Uri packageUri;
+        Uri? packageUri;
         if (_packageMap != null) {
-          packageUri = _packageMap[packageName];
+          packageUri = _packageMap![packageName];
         } else {
           final fakeResolvedUri = await Isolate.resolvePackageUri(
               Uri(scheme: 'package', path: '$packageName/'));
diff --git a/pubspec.yaml b/pubspec.yaml
index fd54189..c8bd176 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,17 +1,22 @@
 name: shelf_packages_handler
-version: 2.0.1
+version: 3.0.0-dev
 
 description: A shelf handler for serving a `packages/` directory.
 repository: https://github.com/dart-lang/shelf_packages_handler
 
 environment:
-  sdk: '>=2.8.0 <3.0.0'
+  sdk: '>=2.12.0-0 <3.0.0'
 
 dependencies:
-  path: ^1.0.0
-  shelf: '>=0.7.0 <2.0.0'
-  shelf_static: ^0.2.0
+  path: ^1.8.0
+  shelf: ^1.0.0
+  shelf_static: ^1.0.0
 
 dev_dependencies:
-  pedantic: ^1.9.0
-  test: '>=1.0.0 <2.0.0'
+  pedantic: ^1.10.0
+  test: ^1.16.0
+
+dependency_overrides:
+  shelf_static:
+    git: https://github.com/dart-lang/shelf_static
+  test: ^1.16.0
diff --git a/test/packages_handler_test.dart b/test/packages_handler_test.dart
index 02b8215..3b6bcc2 100644
--- a/test/packages_handler_test.dart
+++ b/test/packages_handler_test.dart
@@ -9,7 +9,7 @@
 import 'package:test/test.dart';
 
 void main() {
-  String dir;
+  late String dir;
   setUp(() {
     dir =
         Directory.systemTemp.createTempSync('shelf_packages_handler_test').path;
@@ -37,7 +37,7 @@
     });
 
     group('with a package map', () {
-      Handler handler;
+      late Handler handler;
 
       setUp(() {
         handler = packagesHandler(packageMap: {