Move NNBD migration tool to a fresh package.

This gives us more flexibility for how we want to publish and deploy
the tool.  We now have the option, for example, of making a command
line app that invokes the tool and does not depend on analysis_server.

Note that some testing infrastructure had to be duplicated.  I plan to
consolidate this infrastructure in follow-up CLs.

Change-Id: I046506bc2bb5c3e467e15885f198ee0632351ee9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/105463
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/.packages b/.packages
index db0e7d7..37c475e 100644
--- a/.packages
+++ b/.packages
@@ -61,6 +61,7 @@
 mockito:third_party/pkg/mockito/lib
 modular_test:pkg/modular_test/lib
 mustache:third_party/pkg/mustache/lib
+nnbd_migration:pkg/nnbd_migration/lib
 oauth2:third_party/pkg/oauth2/lib
 observatory:runtime/observatory/lib
 observatory_test_package:runtime/observatory/tests/service/observatory_test_package
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index 44970b6..ae1db3e 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -5,7 +5,7 @@
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
 import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
-import 'package:analysis_server/src/nullability/provisional_api.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/experiments.dart';
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index d9f2c93..c542415 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -15,6 +15,7 @@
   linter: any
   logging: any
   meta: any
+  nnbd_migration: any
   source_span: any
   package_config: any
   path: any
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index 86eb450..a45add5 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.dart
@@ -9,7 +9,6 @@
 import 'domains/test_all.dart' as domains;
 import 'flutter/test_all.dart' as flutter;
 import 'lsp/test_all.dart' as lsp;
-import 'nullability/test_all.dart' as nullability;
 import 'plugin/test_all.dart' as plugin;
 import 'services/test_all.dart' as services;
 import 'utilities/test_all.dart' as utilities;
@@ -25,7 +24,6 @@
     domains.main();
     flutter.main();
     lsp.main();
-    nullability.main();
     plugin.main();
     services.main();
     utilities.main();
diff --git a/pkg/nnbd_migration/CHANGELOG.md b/pkg/nnbd_migration/CHANGELOG.md
new file mode 100644
index 0000000..aea8052
--- /dev/null
+++ b/pkg/nnbd_migration/CHANGELOG.md
@@ -0,0 +1,2 @@
+## 0.1.0-dev (not yet published)
+* Separated from analysis_server project.
diff --git a/pkg/nnbd_migration/LICENSE b/pkg/nnbd_migration/LICENSE
new file mode 100644
index 0000000..f75d7c2
--- /dev/null
+++ b/pkg/nnbd_migration/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2019, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/nnbd_migration/README.md b/pkg/nnbd_migration/README.md
new file mode 100644
index 0000000..b1d8f0a
--- /dev/null
+++ b/pkg/nnbd_migration/README.md
@@ -0,0 +1,4 @@
+# NNBD Migration Engine
+
+This package provides infrastructure for migrating code to be non-nullable by
+default.
diff --git a/pkg/analysis_server/lib/src/nullability/provisional_api.dart b/pkg/nnbd_migration/lib/nnbd_migration.dart
similarity index 95%
rename from pkg/analysis_server/lib/src/nullability/provisional_api.dart
rename to pkg/nnbd_migration/lib/nnbd_migration.dart
index bf50955..36cbfef 100644
--- a/pkg/analysis_server/lib/src/nullability/provisional_api.dart
+++ b/pkg/nnbd_migration/lib/nnbd_migration.dart
@@ -2,16 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/decorated_type.dart'
-    as analyzer;
-import 'package:analysis_server/src/nullability/expression_checks.dart'
-    as analyzer;
-import 'package:analysis_server/src/nullability/transitional_api.dart'
-    as analyzer;
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:meta/meta.dart';
+import 'package:nnbd_migration/src/decorated_type.dart' as analyzer;
+import 'package:nnbd_migration/src/expression_checks.dart' as analyzer;
+import 'package:nnbd_migration/src/transitional_api.dart' as analyzer;
 
 /// Kinds of fixes that might be performed by nullability migration.
 class NullabilityFixKind {
diff --git a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart b/pkg/nnbd_migration/lib/src/conditional_discard.dart
similarity index 96%
rename from pkg/analysis_server/lib/src/nullability/conditional_discard.dart
rename to pkg/nnbd_migration/lib/src/conditional_discard.dart
index dca55ce..144bd82 100644
--- a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart
+++ b/pkg/nnbd_migration/lib/src/conditional_discard.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/nullability_node.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
 
 /// Container for information gathered during nullability migration about a
 /// conditional check that might need to be discarded.
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type.dart b/pkg/nnbd_migration/lib/src/decorated_type.dart
similarity index 97%
rename from pkg/analysis_server/lib/src/nullability/decorated_type.dart
rename to pkg/nnbd_migration/lib/src/decorated_type.dart
index 0dbc5ac..41be111 100644
--- a/pkg/analysis_server/lib/src/nullability/decorated_type.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type.dart
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/nullability_node.dart';
-import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/transitional_api.dart';
 
 /// Representation of a type in the code to be migrated.  In addition to
 /// tracking the (unmigrated) [DartType], we track the [ConstraintVariable]s
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type_operations.dart b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
similarity index 87%
rename from pkg/analysis_server/lib/src/nullability/decorated_type_operations.dart
rename to pkg/nnbd_migration/lib/src/decorated_type_operations.dart
index 0788209..b1e3fa8 100644
--- a/pkg/analysis_server/lib/src/nullability/decorated_type_operations.dart
+++ b/pkg/nnbd_migration/lib/src/decorated_type_operations.dart
@@ -2,11 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/decorated_type.dart';
-import 'package:analysis_server/src/nullability/node_builder.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type_system.dart';
 import 'package:analyzer/src/dart/resolver/flow_analysis.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/node_builder.dart';
 
 /// [TypeOperations] that works with [DecoratedType]s.
 class DecoratedTypeOperations implements TypeOperations<DecoratedType> {
diff --git a/pkg/analysis_server/lib/src/nullability/expression_checks.dart b/pkg/nnbd_migration/lib/src/expression_checks.dart
similarity index 91%
rename from pkg/analysis_server/lib/src/nullability/expression_checks.dart
rename to pkg/nnbd_migration/lib/src/expression_checks.dart
index bc533d6..0b1f185 100644
--- a/pkg/analysis_server/lib/src/nullability/expression_checks.dart
+++ b/pkg/nnbd_migration/lib/src/expression_checks.dart
@@ -2,9 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/nullability_node.dart';
-import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/transitional_api.dart';
 
 /// Container for information gathered during nullability migration about the
 /// set of runtime checks that might need to be performed on the value of an
diff --git a/pkg/analysis_server/lib/src/nullability/graph_builder.dart b/pkg/nnbd_migration/lib/src/graph_builder.dart
similarity index 97%
rename from pkg/analysis_server/lib/src/nullability/graph_builder.dart
rename to pkg/nnbd_migration/lib/src/graph_builder.dart
index feddad2..3610a6f 100644
--- a/pkg/analysis_server/lib/src/nullability/graph_builder.dart
+++ b/pkg/nnbd_migration/lib/src/graph_builder.dart
@@ -2,12 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/conditional_discard.dart';
-import 'package:analysis_server/src/nullability/decorated_type.dart';
-import 'package:analysis_server/src/nullability/expression_checks.dart';
-import 'package:analysis_server/src/nullability/node_builder.dart';
-import 'package:analysis_server/src/nullability/nullability_node.dart';
-import 'package:analysis_server/src/nullability/provisional_api.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
@@ -17,6 +11,12 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:meta/meta.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/conditional_discard.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
+import 'package:nnbd_migration/src/node_builder.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
 
 /// Visitor that builds nullability graph edges by examining code to be
 /// migrated.
diff --git a/pkg/analysis_server/lib/src/nullability/node_builder.dart b/pkg/nnbd_migration/lib/src/node_builder.dart
similarity index 96%
rename from pkg/analysis_server/lib/src/nullability/node_builder.dart
rename to pkg/nnbd_migration/lib/src/node_builder.dart
index 6d91d13..6d1bad3 100644
--- a/pkg/analysis_server/lib/src/nullability/node_builder.dart
+++ b/pkg/nnbd_migration/lib/src/node_builder.dart
@@ -2,11 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/conditional_discard.dart';
-import 'package:analysis_server/src/nullability/decorated_type.dart';
-import 'package:analysis_server/src/nullability/expression_checks.dart';
-import 'package:analysis_server/src/nullability/nullability_node.dart';
-import 'package:analysis_server/src/nullability/provisional_api.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -15,6 +10,11 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:front_end/src/scanner/token.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/conditional_discard.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
 
 /// Visitor that builds nullability nodes based on visiting code to be migrated.
 ///
diff --git a/pkg/analysis_server/lib/src/nullability/nullability_node.dart b/pkg/nnbd_migration/lib/src/nullability_node.dart
similarity index 100%
rename from pkg/analysis_server/lib/src/nullability/nullability_node.dart
rename to pkg/nnbd_migration/lib/src/nullability_node.dart
diff --git a/pkg/analysis_server/lib/src/nullability/transitional_api.dart b/pkg/nnbd_migration/lib/src/transitional_api.dart
similarity index 94%
rename from pkg/analysis_server/lib/src/nullability/transitional_api.dart
rename to pkg/nnbd_migration/lib/src/transitional_api.dart
index fc2ca3c..9c2c5eb 100644
--- a/pkg/analysis_server/lib/src/nullability/transitional_api.dart
+++ b/pkg/nnbd_migration/lib/src/transitional_api.dart
@@ -2,18 +2,18 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/conditional_discard.dart';
-import 'package:analysis_server/src/nullability/decorated_type.dart';
-import 'package:analysis_server/src/nullability/expression_checks.dart';
-import 'package:analysis_server/src/nullability/graph_builder.dart';
-import 'package:analysis_server/src/nullability/node_builder.dart';
-import 'package:analysis_server/src/nullability/nullability_node.dart';
-import 'package:analysis_server/src/nullability/provisional_api.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' show SourceEdit;
+import 'package:nnbd_migration/nnbd_migration.dart';
+import 'package:nnbd_migration/src/conditional_discard.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
+import 'package:nnbd_migration/src/graph_builder.dart';
+import 'package:nnbd_migration/src/node_builder.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
 
 /// Records information about how a conditional expression or statement might
 /// need to be modified.
diff --git a/pkg/nnbd_migration/pubspec.yaml b/pkg/nnbd_migration/pubspec.yaml
new file mode 100644
index 0000000..bacb556
--- /dev/null
+++ b/pkg/nnbd_migration/pubspec.yaml
@@ -0,0 +1,6 @@
+name: nnbd_migration
+publish_to: none
+environment:
+  sdk: '>=2.2.2 <3.0.0'
+dependencies:
+  analyzer: ^0.36.3
diff --git a/pkg/nnbd_migration/test/abstract_context.dart b/pkg/nnbd_migration/test/abstract_context.dart
new file mode 100644
index 0000000..a9f80a5
--- /dev/null
+++ b/pkg/nnbd_migration/test/abstract_context.dart
@@ -0,0 +1,140 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/analysis_context.dart';
+import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/overlay_file_system.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+
+/// TODO(paulberry): this logic is duplicated from other packages.  Find a way
+/// share it, or avoid relying on it.
+class AbstractContextTest with ResourceProviderMixin {
+  OverlayResourceProvider overlayResourceProvider;
+
+  AnalysisContextCollection _analysisContextCollection;
+  AnalysisDriver _driver;
+
+  AnalysisDriver get driver => _driver;
+
+  AnalysisSession get session => driver.currentSession;
+
+  void addMetaPackage() {
+    addPackageFile('meta', 'meta.dart', r'''
+library meta;
+
+const Required required = const Required();
+
+class Required {
+  final String reason;
+  const Required([this.reason]);
+}
+''');
+  }
+
+  /// Add a new file with the given [pathInLib] to the package with the
+  /// given [packageName].  Then ensure that the test package depends on the
+  /// [packageName].
+  File addPackageFile(String packageName, String pathInLib, String content) {
+    var packagePath = '/.pub-cache/$packageName';
+    _addTestPackageDependency(packageName, packagePath);
+    return newFile('$packagePath/lib/$pathInLib', content: content);
+  }
+
+  Source addSource(String path, String content, [Uri uri]) {
+    File file = newFile(path, content: content);
+    Source source = file.createSource(uri);
+    driver.addFile(file.path);
+    driver.changeFile(file.path);
+    return source;
+  }
+
+  /// Create all analysis contexts in `/home`.
+  void createAnalysisContexts() {
+    _analysisContextCollection = AnalysisContextCollectionImpl(
+      includedPaths: [convertPath('/home')],
+      enableIndex: true,
+      resourceProvider: overlayResourceProvider,
+      sdkPath: convertPath('/sdk'),
+    );
+
+    var testPath = convertPath('/home/test');
+    _driver = getDriver(testPath);
+  }
+
+  /// Return the existing analysis context that should be used to analyze the
+  /// given [path], or throw [StateError] if the [path] is not analyzed in any
+  /// of the created analysis contexts.
+  AnalysisContext getContext(String path) {
+    path = convertPath(path);
+    return _analysisContextCollection.contextFor(path);
+  }
+
+  /// Return the existing analysis driver that should be used to analyze the
+  /// given [path], or throw [StateError] if the [path] is not analyzed in any
+  /// of the created analysis contexts.
+  AnalysisDriver getDriver(String path) {
+    DriverBasedAnalysisContext context =
+        getContext(path) as DriverBasedAnalysisContext;
+    return context.driver;
+  }
+
+  void setUp() {
+    setupResourceProvider();
+    overlayResourceProvider = OverlayResourceProvider(resourceProvider);
+
+    new MockSdk(resourceProvider: resourceProvider);
+
+    newFolder('/home/test');
+    newFile('/home/test/.packages', content: r'''
+test:file:///home/test/lib
+''');
+
+    createAnalysisContexts();
+  }
+
+  void setupResourceProvider() {}
+
+  void tearDown() {
+    AnalysisEngine.instance.clearCaches();
+    AnalysisEngine.instance.logger = null;
+  }
+
+  void _addTestPackageDependency(String name, String rootPath) {
+    var packagesFile = getFile('/home/test/.packages');
+    var packagesContent = packagesFile.readAsStringSync();
+
+    // Ignore if there is already the same package dependency.
+    if (packagesContent.contains('$name:file://')) {
+      return;
+    }
+
+    packagesContent += '$name:${toUri('$rootPath/lib')}\n';
+
+    packagesFile.writeAsStringSync(packagesContent);
+
+    _createDriver();
+  }
+
+  void _createDriver() {
+    var collection = AnalysisContextCollectionImpl(
+      includedPaths: [convertPath('/home')],
+      enableIndex: true,
+      resourceProvider: resourceProvider,
+      sdkPath: convertPath('/sdk'),
+    );
+
+    var testPath = convertPath('/home/test');
+    var context = collection.contextFor(testPath) as DriverBasedAnalysisContext;
+
+    _driver = context.driver;
+  }
+}
diff --git a/pkg/nnbd_migration/test/abstract_single_unit.dart b/pkg/nnbd_migration/test/abstract_single_unit.dart
new file mode 100644
index 0000000..25c5f87
--- /dev/null
+++ b/pkg/nnbd_migration/test/abstract_single_unit.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/find_node.dart';
+import 'package:test/test.dart';
+
+import 'abstract_context.dart';
+
+/// TODO(paulberry): this logic is duplicated from other packages.  Find a way
+/// share it, or avoid relying on it.
+class AbstractSingleUnitTest extends AbstractContextTest {
+  bool verifyNoTestUnitErrors = true;
+
+  String testCode;
+  String testFile;
+  Source testSource;
+  ResolvedUnitResult testAnalysisResult;
+  CompilationUnit testUnit;
+  CompilationUnitElement testUnitElement;
+  LibraryElement testLibraryElement;
+  FindNode findNode;
+
+  void addTestSource(String code, [Uri uri]) {
+    testCode = code;
+    testSource = addSource(testFile, code, uri);
+  }
+
+  Future<void> resolveTestUnit(String code) async {
+    addTestSource(code);
+    testAnalysisResult = await session.getResolvedUnit(testFile);
+    testUnit = testAnalysisResult.unit;
+    if (verifyNoTestUnitErrors) {
+      expect(testAnalysisResult.errors.where((AnalysisError error) {
+        return error.errorCode != HintCode.DEAD_CODE &&
+            error.errorCode != HintCode.UNUSED_CATCH_CLAUSE &&
+            error.errorCode != HintCode.UNUSED_CATCH_STACK &&
+            error.errorCode != HintCode.UNUSED_ELEMENT &&
+            error.errorCode != HintCode.UNUSED_FIELD &&
+            error.errorCode != HintCode.UNUSED_IMPORT &&
+            error.errorCode != HintCode.UNUSED_LOCAL_VARIABLE;
+      }), isEmpty);
+    }
+    testUnitElement = testUnit.declaredElement;
+    testLibraryElement = testUnitElement.library;
+    findNode = FindNode(code, testUnit);
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    testFile = convertPath('/home/test/lib/test.dart');
+  }
+}
diff --git a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart b/pkg/nnbd_migration/test/api_test.dart
similarity index 98%
rename from pkg/analysis_server/test/src/nullability/provisional_api_test.dart
rename to pkg/nnbd_migration/test/api_test.dart
index c8730d7..1419873 100644
--- a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -2,13 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/provisional_api.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:nnbd_migration/nnbd_migration.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../abstract_context.dart';
+import 'abstract_context.dart';
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart b/pkg/nnbd_migration/test/migration_visitor_test.dart
similarity index 98%
rename from pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
rename to pkg/nnbd_migration/test/migration_visitor_test.dart
index 46e0e5b..23b759b 100644
--- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
+++ b/pkg/nnbd_migration/test/migration_visitor_test.dart
@@ -2,21 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analysis_server/src/nullability/conditional_discard.dart';
-import 'package:analysis_server/src/nullability/decorated_type.dart';
-import 'package:analysis_server/src/nullability/expression_checks.dart';
-import 'package:analysis_server/src/nullability/graph_builder.dart';
-import 'package:analysis_server/src/nullability/node_builder.dart';
-import 'package:analysis_server/src/nullability/nullability_node.dart';
-import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:meta/meta.dart';
+import 'package:nnbd_migration/src/conditional_discard.dart';
+import 'package:nnbd_migration/src/decorated_type.dart';
+import 'package:nnbd_migration/src/expression_checks.dart';
+import 'package:nnbd_migration/src/graph_builder.dart';
+import 'package:nnbd_migration/src/node_builder.dart';
+import 'package:nnbd_migration/src/nullability_node.dart';
+import 'package:nnbd_migration/src/transitional_api.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import '../../abstract_single_unit.dart';
+import 'abstract_single_unit.dart';
 
 main() {
   defineReflectiveSuite(() {
diff --git a/pkg/analysis_server/test/src/nullability/test_all.dart b/pkg/nnbd_migration/test/test_all.dart
similarity index 81%
rename from pkg/analysis_server/test/src/nullability/test_all.dart
rename to pkg/nnbd_migration/test/test_all.dart
index c43a34f..8f19fb9 100644
--- a/pkg/analysis_server/test/src/nullability/test_all.dart
+++ b/pkg/nnbd_migration/test/test_all.dart
@@ -4,12 +4,12 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import 'api_test.dart' as api_test;
 import 'migration_visitor_test.dart' as migration_visitor_test;
-import 'provisional_api_test.dart' as provisional_api_test;
 
 main() {
   defineReflectiveSuite(() {
     migration_visitor_test.main();
-    provisional_api_test.main();
+    api_test.main();
   });
 }
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 26698f9..367542c 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -78,6 +78,7 @@
 dartfix/test/*: SkipByDesign # Only meant to run on vm
 front_end/test/*: SkipByDesign # Only meant to run on vm, most use dart:mirrors and dart:io
 front_end/tool/*: SkipByDesign # Only meant to run on vm
+nnbd_migration/test/*: SkipByDesign # Uses mirrors
 smith/test/*: SkipByDesign # Only meant to run on vm
 status_file/test/normalize_test: SkipByDesign # Uses dart:io
 status_file/test/parse_and_normalize_test: SkipByDesign # Uses dart:io