diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index b4df57c..4c75ebb 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -16,11 +16,11 @@
         NullType,
         Nullability,
         Supertype,
+        TreeNode,
         getAsTypeArguments;
 import 'package:kernel/class_hierarchy.dart'
     show ClassHierarchy, ClassHierarchyBase;
 import 'package:kernel/src/unaliasing.dart';
-import 'package:kernel/text/text_serialization_verifier.dart';
 
 import '../fasta_codes.dart';
 import '../modifier.dart';
@@ -37,6 +37,8 @@
 import 'type_builder.dart';
 import 'type_variable_builder.dart';
 
+const Uri? noUri = null;
+
 abstract class ClassBuilder implements DeclarationBuilder {
   /// The type variables declared on a class, extension or mixin declaration.
   List<TypeVariableBuilder>? get typeVariables;
@@ -304,7 +306,7 @@
         return nonNullableRawType;
       case Nullability.undetermined:
       default:
-        return unhandled("$nullability", "rawType", noOffset, noUri);
+        return unhandled("$nullability", "rawType", TreeNode.noOffset, noUri);
     }
   }
 
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index ae6bc65..a9e1916 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -135,7 +135,6 @@
 import '../../utils/kernel_chain.dart'
     show
         ComponentResult,
-        KernelTextSerialization,
         MatchContext,
         MatchExpectation,
         Print,
@@ -200,8 +199,6 @@
 ]
 ''';
 
-const String KERNEL_TEXT_SERIALIZATION = " kernel text serialization ";
-
 final Expectation runtimeError = ExpectationSet.Default["RuntimeError"];
 
 const String experimentalFlagOptions = '--enable-experiment=';
@@ -358,7 +355,6 @@
       bool updateComments,
       this.skipVm,
       this.semiFuzz,
-      bool kernelTextSerialization,
       CompileMode compileMode,
       this.verify,
       this.soundNullSafety)
@@ -402,9 +398,6 @@
     }
     steps.add(const TypeCheck());
     steps.add(const EnsureNoErrors());
-    if (kernelTextSerialization) {
-      steps.add(const KernelTextSerialization());
-    }
     switch (compileMode) {
       case CompileMode.full:
         steps.add(const Transform());
@@ -758,7 +751,6 @@
       "skipVm",
       "semiFuzz",
       "verify",
-      KERNEL_TEXT_SERIALIZATION,
       "platformBinaries",
       COMPILATION_MODE,
     };
@@ -788,8 +780,6 @@
     bool skipVm = environment["skipVm"] == "true";
     bool semiFuzz = environment["semiFuzz"] == "true";
     bool verify = environment["verify"] != "false";
-    bool kernelTextSerialization =
-        environment.containsKey(KERNEL_TEXT_SERIALIZATION);
     String? platformBinaries = environment["platformBinaries"];
     if (platformBinaries != null && !platformBinaries.endsWith('/')) {
       platformBinaries = '$platformBinaries/';
@@ -807,7 +797,6 @@
         updateComments,
         skipVm,
         semiFuzz,
-        kernelTextSerialization,
         compileModeFromName(environment[COMPILATION_MODE]),
         verify,
         soundNullSafety));
@@ -1248,6 +1237,9 @@
       }
 
       return pass(result);
+    } catch (e, st) {
+      return new Result<ComponentResult>(result, semiFuzzCrash,
+          "Crashed with '$e' when fuzz compiling.\n\n$st");
     } finally {
       if (originalFlag != null) {
         context.explicitExperimentalFlags[
diff --git a/pkg/front_end/test/fasta/text_serialization_suite.dart b/pkg/front_end/test/fasta/text_serialization_suite.dart
deleted file mode 100644
index caf682e..0000000
--- a/pkg/front_end/test/fasta/text_serialization_suite.dart
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2017, 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.md file.
-
-library fasta.test.text_serialization_suite;
-
-import 'suite_utils.dart' show internalMain;
-import 'testing/suite.dart';
-
-Future<FastaContext> createContext(
-    Chain suite, Map<String, String> environment) {
-  environment[COMPILATION_MODE] = CompileMode.full.name;
-  environment[KERNEL_TEXT_SERIALIZATION] = "";
-  return FastaContext.create(suite, environment);
-}
-
-Future<void> main(List<String> arguments) async {
-  await internalMain(createContext, arguments: arguments);
-}
diff --git a/pkg/front_end/test/unit_test_suites.dart b/pkg/front_end/test/unit_test_suites.dart
index 20fd455..f8eba4b 100644
--- a/pkg/front_end/test/unit_test_suites.dart
+++ b/pkg/front_end/test/unit_test_suites.dart
@@ -23,8 +23,6 @@
 import 'fasta/modular_suite.dart' as modular show createContext;
 import 'fasta/outline_suite.dart' as outline show createContext;
 import 'fasta/strong_suite.dart' as strong show createContext;
-import 'fasta/text_serialization_suite.dart' as text_serialization
-    show createContext;
 import 'fasta/textual_outline_suite.dart' as textual_outline show createContext;
 import 'fasta/weak_suite.dart' as weak show createContext;
 import 'incremental_bulk_compiler_smoke_suite.dart' as incremental_bulk_compiler
@@ -386,13 +384,6 @@
     requiresGit: true,
   ),
   const Suite(
-    "fasta/text_serialization",
-    text_serialization.createContext,
-    "../../testing.json",
-    path: "fasta/text_serialization_suite.dart",
-    shardCount: 10,
-  ),
-  const Suite(
     "fasta/strong",
     strong.createContext,
     "../../testing.json",
diff --git a/pkg/front_end/test/utils/kernel_chain.dart b/pkg/front_end/test/utils/kernel_chain.dart
index 58b15da..94f121e 100644
--- a/pkg/front_end/test/utils/kernel_chain.dart
+++ b/pkg/front_end/test/utils/kernel_chain.dart
@@ -11,7 +11,7 @@
     show isWindows, relativizeUri;
 
 import 'package:front_end/src/api_prototype/compiler_options.dart'
-    show CompilerOptions, DiagnosticMessage;
+    show DiagnosticMessage;
 
 import 'package:front_end/src/base/processed_options.dart'
     show ProcessedOptions;
@@ -21,15 +21,13 @@
 
 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
 
-import 'package:front_end/src/fasta/fasta_codes.dart' show templateUnspecified;
-
 import 'package:front_end/src/fasta/kernel/kernel_target.dart'
     show KernelTarget;
 
 import 'package:front_end/src/fasta/kernel/utils.dart' show ByteSink;
 
 import 'package:front_end/src/fasta/messages.dart'
-    show DiagnosticMessageFromJson, LocatedMessage, Message;
+    show DiagnosticMessageFromJson;
 
 import 'package:kernel/ast.dart'
     show
@@ -54,9 +52,6 @@
 
 import 'package:kernel/text/ast_to_text.dart' show Printer;
 
-import 'package:kernel/text/text_serialization_verifier.dart'
-    show RoundTripStatus, TextSerializationVerifier;
-
 import 'package:testing/testing.dart'
     show
         ChainContext,
@@ -359,77 +354,6 @@
   }
 }
 
-class KernelTextSerialization
-    extends Step<ComponentResult, ComponentResult, ChainContext> {
-  static const bool writeRoundTripStatus = bool.fromEnvironment(
-      "text_serialization.writeRoundTripStatus",
-      defaultValue: false);
-
-  static const String suffix = ".roundtrip";
-
-  const KernelTextSerialization();
-
-  @override
-  String get name => "kernel text serialization";
-
-  @override
-  Future<Result<ComponentResult>> run(
-      ComponentResult result, ChainContext context) async {
-    Component component = result.component;
-    StringBuffer messages = new StringBuffer();
-    ProcessedOptions options = new ProcessedOptions(
-        options: new CompilerOptions()
-          ..onDiagnostic = (DiagnosticMessage message) {
-            if (messages.isNotEmpty) {
-              messages.write("\n");
-            }
-            messages.writeAll(message.plainTextFormatted, "\n");
-          });
-    return await CompilerContext.runWithOptions(options,
-        (compilerContext) async {
-      component.computeCanonicalNames();
-      compilerContext.uriToSource.addAll(component.uriToSource);
-      TextSerializationVerifier verifier =
-          new TextSerializationVerifier(root: component.root);
-      for (Library library in component.libraries) {
-        if (!library.importUri.isScheme("dart") &&
-            !library.importUri.isScheme("package")) {
-          verifier.verify(library);
-        }
-      }
-
-      List<RoundTripStatus> failures = verifier.failures;
-      for (RoundTripStatus failure in failures) {
-        Message message = templateUnspecified.withArguments("\n${failure}");
-        LocatedMessage locatedMessage = failure.uri != null
-            ? message.withLocation(failure.uri!, failure.offset, 1)
-            : message.withoutLocation();
-        options.report(locatedMessage, locatedMessage.code.severity);
-      }
-
-      if (writeRoundTripStatus) {
-        Uri uri = component.uriToSource.keys
-            .firstWhere((uri) => uri.isScheme("file"));
-        String filename = "${uri.toFilePath()}${suffix}";
-        uri = new File(filename).uri;
-        StringBuffer buffer = new StringBuffer();
-        for (RoundTripStatus status in verifier.takeStatus()) {
-          status.printOn(buffer);
-        }
-        await openWrite(uri, (IOSink sink) {
-          sink.write(buffer.toString());
-        });
-      }
-
-      if (failures.isNotEmpty) {
-        return new Result<ComponentResult>(null,
-            context.expectationSet["TextSerializationFailure"], "$messages");
-      }
-      return pass(result);
-    });
-  }
-}
-
 class WriteDill extends Step<ComponentResult, ComponentResult, ChainContext> {
   final bool skipVm;
 
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
index ec6a7f6..e218902 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.outline.expect
@@ -28,19 +28,19 @@
 
 
 Extra constant evaluation status:
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:814:13 -> SymbolConstant(#catchError)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:814:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:814:13 -> SymbolConstant(#test)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:865:13 -> SymbolConstant(#whenComplete)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:865:13 -> ListConstant(const <Type*>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:865:13 -> MapConstant(const <Symbol*, dynamic>{})
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:909:13 -> SymbolConstant(#timeout)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:909:13 -> ListConstant(const <Type*>[])
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:909:13 -> SymbolConstant(#onTimeout)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:763:13 -> SymbolConstant(#then)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:763:13 -> SymbolConstant(#onError)
-Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:874:13 -> SymbolConstant(#asStream)
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:874:13 -> ListConstant(const <Type*>[])
-Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:874:13 -> ListConstant(const <dynamic>[])
-Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:874:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#catchError)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:821:13 -> SymbolConstant(#test)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> SymbolConstant(#whenComplete)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> ListConstant(const <Type*>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:872:13 -> MapConstant(const <Symbol*, dynamic>{})
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#timeout)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> ListConstant(const <Type*>[])
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:916:13 -> SymbolConstant(#onTimeout)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:770:13 -> SymbolConstant(#then)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:770:13 -> SymbolConstant(#onError)
+Evaluated: SymbolLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> SymbolConstant(#asStream)
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <Type*>[])
+Evaluated: ListLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> ListConstant(const <dynamic>[])
+Evaluated: MapLiteral @ org-dartlang-sdk:///sdk/lib/async/future.dart:881:13 -> MapConstant(const <Symbol*, dynamic>{})
 Extra constant evaluation: evaluated: 61, effectively constant: 15
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 5eca28b..0d2af9b 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -13,6 +13,8 @@
 dart2js/late_statics: SemiFuzzFailure
 static_field_lowering/opt_in: SemiFuzzFailure
 
+dartdevc/static_interop_erasure/main: SemiFuzzCrash # https://github.com/dart-lang/sdk/issues/49301
+
 const_functions/const_functions_list: SemiFuzzCrash
 generic_metadata/typedef_generic_types_in_arguments_and_bounds: SemiFuzzCrash
 
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
deleted file mode 100644
index fda1207..0000000
--- a/pkg/front_end/testcases/text_serialization.status
+++ /dev/null
@@ -1,182 +0,0 @@
-# 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.md file.
-
-# Status file for the text_serialization_test.dart test suite. This is testing
-# the round trip for Kernel textual serialization where the initial binary
-# Kernel files are produced by compiling Dart code via Fasta.
-
-constructor_tearoffs/call_instantiation: TypeCheckError
-constructor_tearoffs/lowering/invalid_redirect: VerificationError
-enhanced_enums/declared_hashcode: TypeCheckError
-enhanced_enums/declared_index: TypeCheckError
-enhanced_enums/named_arguments_anywhere/issue48276: TextSerializationFailure # Issue 47524.
-enhanced_enums/named_arguments_anywhere/redirecting_constructor: TextSerializationFailure # Issue 47524.
-enhanced_enums/simple_mixins: RuntimeError
-extension_types/access_setter_as_getter: ExpectationFileMismatchSerialized # Expected.
-extension_types/call_not_get: ExpectationFileMismatchSerialized # Expected.
-extension_types/extension_on_nullable: ExpectationFileMismatchSerialized # Expected.
-extension_types/issue45775: ExpectationFileMismatchSerialized # Expected.
-extension_types/show_and_run_ceil: ExpectationFileMismatchSerialized # Expected.
-extension_types/simple: ExpectationFileMismatchSerialized # Expected.
-extension_types/simple_getter_resolution: ExpectationFileMismatchSerialized # Expected.
-extension_types/simple_method_resolution: ExpectationFileMismatchSerialized # Expected.
-extension_types/simple_operator_resolution: ExpectationFileMismatchSerialized # Expected.
-extension_types/simple_setter_resolution: ExpectationFileMismatchSerialized # Expected.
-extension_types/simple_show_hide: ExpectationFileMismatchSerialized # Expected.
-extension_types/type_variable_in_static_context: ExpectationFileMismatchSerialized # Expected.
-extensions/extension_setter_error: TypeCheckError
-extensions/instance_access_of_static: RuntimeError
-extensions/invalid_explicit_access: RuntimeError
-extensions/static_access_of_instance: RuntimeError
-general/abstract_members: TypeCheckError
-general/accessors: RuntimeError
-general/await_in_non_async: RuntimeError
-general/bounded_implicit_instantiation: TypeCheckError
-general/bounds_instances: TypeCheckError
-general/bug30695: TypeCheckError
-general/call: RuntimeError
-general/cascade: RuntimeError
-general/constructor_initializer_invalid: RuntimeError
-general/covariant_field: TypeCheckError
-general/covariant_generic2: RuntimeError
-general/covariant_generic: RuntimeError
-general/crashes/crash_02/main: Crash
-general/crashes/crash_06/main: Crash
-general/duplicated_field_initializer: RuntimeError
-general/error_locations/error_location_01: RuntimeError
-general/error_locations/error_location_02: RuntimeError
-general/error_locations/error_location_03: RuntimeError
-general/error_recovery/empty_await_for: RuntimeError
-general/error_recovery/empty_for: RuntimeError
-general/expressions: RuntimeError
-general/getter_vs_setter_type: TypeCheckError
-general/implement_semi_stub: TypeCheckError
-general/infer_field_from_multiple2: TypeCheckError
-general/infer_field_from_multiple: TypeCheckError
-general/invalid_operator: TypeCheckError
-general/invalid_operator_override: TypeCheckError
-general/invocations: TypeCheckError
-general/issue37776: RuntimeError
-general/issue41210a: TypeCheckError
-general/issue41210b/issue41210.no_link: TypeCheckError
-general/issue41210b/issue41210: TypeCheckError
-general/issue47994b: RuntimeError # Assertions are not enabled
-general/issue_46886: RuntimeError
-general/micro: RuntimeError
-general/mixin_application_override: TypeCheckError
-general/mixin_constructors_with_default_values: RuntimeError
-general/mixin_covariant2: RuntimeError
-general/named_parameters_super_and_not: TextSerializationFailure # Issue 47524.
-general/operator_method_not_found: RuntimeError
-general/optional: RuntimeError
-general/override_check_accessor_after_inference: TypeCheckError # Issue #31620
-general/override_check_accessor_basic: TypeCheckError # Issue #31620
-general/override_check_accessor_with_covariant_modifier: TypeCheckError # Issue #31620
-general/override_check_after_inference: TypeCheckError # Issue #31620
-general/override_check_basic: TypeCheckError # Issue #31620
-general/override_check_with_covariant_modifier: TypeCheckError # Issue #31620
-general/override_setter_with_field: TypeCheckError
-general/redirecting_factory: RuntimeError
-general/spread_collection: RuntimeError # Should be fixed as part of implementing spread collection support
-general/super_semi_stub: TypeCheckError
-general/type_variable_as_super: RuntimeError
-general/unsound_promotion: TypeCheckError
-general/void_methods: RuntimeError
-general/with_dependencies/issue_43084/issue_43084: RuntimeError
-inference/constructors_infer_from_arguments_argument_not_assignable: TypeCheckError
-inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer: TypeCheckError
-inference/downwards_inference_for_each: RuntimeError
-inference/downwards_inference_on_list_literals_infer_downwards: RuntimeError
-inference/future_then_upwards: RuntimeError
-inference/future_then_upwards_2: RuntimeError
-inference/generic_methods_correctly_recognize_generic_upper_bound: TypeCheckError
-inference/generic_methods_do_not_infer_invalid_override_of_generic_method: TypeCheckError
-inference/generic_methods_handle_override_of_non_generic_with_generic: TypeCheckError
-inference/infer_method_missing_params: TypeCheckError
-inference/infer_type_regardless_of_declaration_order_or_cycles: RuntimeError
-inference/infer_types_on_generic_instantiations_4: RuntimeError
-inference/infer_types_on_generic_instantiations_infer: TypeCheckError
-inference/instantiate_to_bounds_generic_has_bound_defined_after transform: RuntimeError
-inference/mixin_inference_outwards_3: TypeCheckError
-inference/mixin_inference_outwards_4: TypeCheckError
-inference/mixin_inference_unification_1: TypeCheckError
-inference/mixin_inference_unification_2: TypeCheckError
-inference/override_equals: RuntimeError
-inference_new/infer_assign_to_index_super_upwards: TypeCheckError
-inference_new/infer_assign_to_index_this_upwards: TypeCheckError
-inference_new/infer_assign_to_index_upwards: TypeCheckError
-late_lowering/covariant_late_field: TypeCheckError
-named_arguments_anywhere/redirecting_constructor_initializers: TextSerializationFailure # Issue 47524.
-nnbd/covariant_late_field: TypeCheckError
-nnbd/getter_vs_setter_type: TypeCheckError
-nnbd/issue42603: TypeCheckError
-nnbd/no_support_for_old_null_aware_index_access_syntax: RuntimeError # Expected.
-nnbd_mixed/bad_mixins: TypeCheckError
-nnbd_mixed/covariant_from_opt_in: TypeCheckError
-nnbd_mixed/hierarchy/conflict: TypeCheckError
-nnbd_mixed/hierarchy/duplicates: TypeCheckError
-nnbd_mixed/hierarchy/forwarding_semi_stub_field: TypeCheckError
-nnbd_mixed/hierarchy/forwarding_semi_stub_method: TypeCheckError
-nnbd_mixed/hierarchy/forwarding_semi_stub_setter: TypeCheckError
-nnbd_mixed/hierarchy/getter_setter: TypeCheckError
-nnbd_mixed/hierarchy/mix_in_override: TypeCheckError
-nnbd_mixed/hierarchy/override: TypeCheckError
-nnbd_mixed/inheritance_from_opt_in: TypeCheckError
-nnbd_mixed/issue41567: TypeCheckError
-nnbd_mixed/messages_with_types_opt_in: TypeCheckError
-nnbd_mixed/messages_with_types_opt_out: TypeCheckError
-nnbd_mixed/mixin_from_opt_in/main: RuntimeError
-rasta/abstract_constructor: RuntimeError
-rasta/bad_constructor_redirection: RuntimeError
-rasta/bad_continue: RuntimeError
-rasta/bad_default_constructor: RuntimeError
-rasta/bad_explicit_super_constructor: RuntimeError
-rasta/bad_implicit_super_constructor: RuntimeError
-rasta/bad_interpolation: RuntimeError
-rasta/bad_redirection: RuntimeError
-rasta/bad_setter_initializer: RuntimeError
-rasta/breaking_bad: RuntimeError
-rasta/class_hierarchy: RuntimeError
-rasta/constant_get_and_invoke: RuntimeError
-rasta/generic_factory: RuntimeError
-rasta/issue_000001: RuntimeError
-rasta/issue_000031: RuntimeError
-rasta/issue_000032: RuntimeError
-rasta/issue_000034: RuntimeError
-rasta/issue_000036: RuntimeError
-rasta/issue_000041: RuntimeError
-rasta/issue_000042: RuntimeError
-rasta/issue_000044: RuntimeError
-rasta/malformed_const_constructor: RuntimeError
-rasta/malformed_function: RuntimeError
-rasta/parser_error: RuntimeError
-rasta/static: RuntimeError
-rasta/super: RuntimeError
-rasta/super_mixin: RuntimeError
-rasta/type_literals: RuntimeError
-rasta/typedef: RuntimeError
-rasta/unresolved: RuntimeError
-rasta/unresolved_constructor: RuntimeError
-rasta/unresolved_for_in: RuntimeError
-regress/issue_29976: RuntimeError
-regress/issue_29982: RuntimeError
-regress/issue_31180: TypeCheckError
-regress/issue_31180_2: TypeCheckError
-regress/issue_32972: RuntimeError
-regress/issue_33452: RuntimeError
-regress/issue_34225: RuntimeError
-regress/issue_34563: RuntimeError
-regress/issue_35258: RuntimeError
-regress/issue_35259: RuntimeError
-regress/issue_35260: RuntimeError
-regress/issue_35266: RuntimeError
-regress/issue_37285: RuntimeError
-regress/issue_39091_2: RuntimeError
-runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
-set_literals/disambiguation_rule: RuntimeError
-set_literals/disambiguation_rule2: RuntimeError
-value_class/copy_with_call_sites: RuntimeError # Expected
-value_class/simple: RuntimeError # Expected
-value_class/value_extends_non_value: RuntimeError # Expected
-value_class/value_implements_non_value: RuntimeError # Expected
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 6154e48..f8898ce 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -10,6 +10,8 @@
 no_such_method_forwarders/abstract_override_abstract_different_type: SemiFuzzFailure
 no_such_method_forwarders/abstract_override_with_different_signature: SemiFuzzFailure
 
+dartdevc/static_interop_erasure/main: SemiFuzzCrash # https://github.com/dart-lang/sdk/issues/49301
+
 dart2js/tear_off_patch/main: semiFuzzFailureOnForceRebuildBodies # needs custom libraries.json (and platform?) not setup here
 general/constants/with_unevaluated_agnostic/various_2: SemiFuzzFailure # Looks similar to https://dart-review.googlesource.com/c/sdk/+/242441
 general/no_such_method_forwarder: SemiFuzzFailure # https://dart-review.googlesource.com/c/sdk/+/242444
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 2d92f0b..435e80e 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -82,23 +82,6 @@
       ]
     },
     {
-      "name": "text_serialization",
-      "kind": "Chain",
-      "source": "test/fasta/text_serialization_suite.dart",
-      "path": "testcases/",
-      "status": "testcases/text_serialization.status",
-      "pattern": [
-        "\\.dart$",
-        "\\.crash_dart$"
-      ],
-      "exclude": [
-        "/testcases/.*_part[0-9]*\\.dart$",
-        "/testcases/.*_lib[0-9]*\\.dart$",
-        "/testcases/dartino/",
-        "/testcases/expression/"
-      ]
-    },
-    {
       "name": "modular",
       "kind": "Chain",
       "source": "test/fasta/modular_suite.dart",
diff --git a/pkg/front_end/tool/update_expectations.dart b/pkg/front_end/tool/update_expectations.dart
index 8a99e2e..fd75621 100644
--- a/pkg/front_end/tool/update_expectations.dart
+++ b/pkg/front_end/tool/update_expectations.dart
@@ -9,7 +9,6 @@
   'outline',
   'strong',
   'modular',
-  'text_serialization',
   'textual_outline',
 ];
 
diff --git a/pkg/kernel/lib/text/serializer_combinators.dart b/pkg/kernel/lib/text/serializer_combinators.dart
deleted file mode 100644
index 7eed26a..0000000
--- a/pkg/kernel/lib/text/serializer_combinators.dart
+++ /dev/null
@@ -1,923 +0,0 @@
-// Copyright (c) 2018, 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.
-
-library kernel.serializer_combinators;
-
-import 'dart:convert' show json;
-
-import '../ast.dart' show Node;
-import '../canonical_name.dart' show CanonicalName;
-import 'text_serializer.dart' show Tagger;
-
-class DeserializationEnvironment<T extends Node> {
-  final DeserializationEnvironment<T>? parent;
-
-  final Map<String, T> locals = <String, T>{};
-
-  final Map<String, T> binders = <String, T>{};
-
-  final Map<T, String> distinctNames = new Map<T, String>.identity();
-
-  DeserializationEnvironment(this.parent);
-
-  T lookup(String name) =>
-      locals[name] ??
-      parent?.lookup(name) ??
-      (throw StateError("No local '${name}' found in this scope."));
-
-  T addBinder(T node, String distinctName) {
-    if (lookupDistinctName(node) != null) {
-      throw StateError(
-          "Name '${distinctName}' is already declared in this scope.");
-    }
-    distinctNames[node] = distinctName;
-    return binders[distinctName] = node;
-  }
-
-  // TODO(cstefantsova): Consider combining with [addBinder] into a single
-  // method.
-  void extend() {
-    locals.addAll(binders);
-    binders.clear();
-  }
-
-  String? lookupDistinctName(T object) {
-    return distinctNames[object] ?? parent?.lookupDistinctName(object);
-  }
-}
-
-class SerializationEnvironment<T extends Node> {
-  final SerializationEnvironment<T>? parent;
-
-  final Map<T, String> locals = new Map<T, String>.identity();
-
-  final Map<T, String> binders = new Map<T, String>.identity();
-
-  int nameCount;
-
-  Map<T, String> distinctNames = new Map<T, String>.identity();
-
-  SerializationEnvironment(this.parent) : nameCount = parent?.nameCount ?? 0;
-
-  String lookup(T node) =>
-      locals[node] ??
-      parent?.lookup(node) ??
-      (throw StateError("No name for ${node} found in this scope."));
-
-  String addBinder(T node, {String? nameClue}) {
-    final String separator = "^";
-    final int codeOfZero = "0".codeUnitAt(0);
-    final int codeOfNine = "9".codeUnitAt(0);
-
-    String prefix;
-    if (nameClue != null) {
-      int prefixLength = nameClue.length - 1;
-      bool isOnlyDigits = true;
-      while (prefixLength >= 0 && nameClue[prefixLength] != separator) {
-        int code = nameClue.codeUnitAt(prefixLength);
-        isOnlyDigits =
-            isOnlyDigits && (codeOfZero <= code && code <= codeOfNine);
-        --prefixLength;
-      }
-      if (prefixLength < 0 || !isOnlyDigits) {
-        prefixLength = nameClue.length;
-      }
-      prefix = nameClue.substring(0, prefixLength);
-    } else {
-      prefix = "ID";
-    }
-    String distinctName = "$prefix$separator${nameCount++}";
-    // The following checks for an internal error, not an error caused by the
-    // user. So, an assert is used instead of an exception.
-    assert(
-        lookupDistinctName(node) == null,
-        "Can't assign distinct name '${distinctName}' "
-        "to an object of kind '${node.runtimeType}': "
-        "it's already known by name '${lookupDistinctName(node)}'.");
-    distinctNames[node] = distinctName;
-    return binders[node] = distinctName;
-  }
-
-  // TODO(cstefantsova): Consider combining with [addBinder] into a single
-  // method.
-  void extend() {
-    locals.addAll(binders);
-    binders.clear();
-  }
-
-  String? lookupDistinctName(T object) {
-    return distinctNames[object] ?? parent?.lookupDistinctName(object);
-  }
-}
-
-class DeserializationState {
-  final DeserializationEnvironment environment;
-  final CanonicalName nameRoot;
-
-  DeserializationState(this.environment, this.nameRoot);
-}
-
-class SerializationState {
-  final SerializationEnvironment environment;
-
-  SerializationState(this.environment);
-}
-
-abstract class TextSerializer<T> {
-  const TextSerializer();
-
-  T readFrom(Iterator<Object?> stream, DeserializationState? state);
-  void writeTo(StringBuffer buffer, T object, SerializationState? state);
-
-  /// True if this serializer/deserializer writes/reads nothing.  This is true
-  /// for the serializer [Nothing] and also some serializers derived from it.
-  bool get isEmpty => false;
-}
-
-class Nothing extends TextSerializer<void> {
-  const Nothing();
-
-  @override
-  void readFrom(Iterator<Object?> stream, DeserializationState? _) {}
-
-  @override
-  void writeTo(StringBuffer buffer, void ignored, SerializationState? _) {}
-
-  @override
-  bool get isEmpty => true;
-}
-
-class DartString extends TextSerializer<String> {
-  const DartString();
-
-  @override
-  String readFrom(Iterator<Object?> stream, DeserializationState? _) {
-    Object? current = stream.current;
-    if (current is! String) {
-      throw StateError("Expected an atom, found a list: '${current}'.");
-    }
-    String result = json.decode(current);
-    stream.moveNext();
-    return result;
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, String object, SerializationState? _) {
-    buffer.write(json.encode(object));
-  }
-}
-
-class DartInt extends TextSerializer<int> {
-  const DartInt();
-
-  @override
-  int readFrom(Iterator<Object?> stream, DeserializationState? _) {
-    Object? current = stream.current;
-    if (current is! String) {
-      throw StateError("Expected an atom, found a list: '${current}'.");
-    }
-    int result = int.parse(current);
-    stream.moveNext();
-    return result;
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, int object, SerializationState? _) {
-    buffer.write(object);
-  }
-}
-
-class DartDouble extends TextSerializer<double> {
-  const DartDouble();
-
-  @override
-  double readFrom(Iterator<Object?> stream, DeserializationState? _) {
-    Object? current = stream.current;
-    if (current is! String) {
-      throw StateError("Expected an atom, found a list: '${current}'.");
-    }
-    double result = double.parse(current);
-    stream.moveNext();
-    return result;
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, double object, SerializationState? _) {
-    buffer.write(object);
-  }
-}
-
-class DartBool extends TextSerializer<bool> {
-  const DartBool();
-
-  @override
-  bool readFrom(Iterator<Object?> stream, DeserializationState? _) {
-    Object? current = stream.current;
-    if (current is! String) {
-      throw StateError("Expected an atom, found a list: '${current}'.");
-    }
-    bool result;
-    if (current == "true") {
-      result = true;
-    } else if (current == "false") {
-      result = false;
-    } else {
-      throw StateError("Expected 'true' or 'false', found '${current}'");
-    }
-    stream.moveNext();
-    return result;
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, bool object, SerializationState? _) {
-    buffer.write(object ? 'true' : 'false');
-  }
-}
-
-class UriSerializer extends TextSerializer<Uri> {
-  const UriSerializer();
-
-  @override
-  Uri readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    String uriAsString = const DartString().readFrom(stream, state);
-    return Uri.parse(uriAsString);
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, Uri object, SerializationState? state) {
-    const DartString().writeTo(buffer, object.toString(), state);
-  }
-}
-
-// == Serializers for tagged (disjoint) unions.
-//
-// They require a function mapping serializables to a tag string.  This is
-// implemented by Tagger visitors.
-// A tagged union of serializer/deserializers.
-class Case<T> extends TextSerializer<T> {
-  final Tagger<T> tagger;
-  final List<String> _tags;
-  final List<TextSerializer<T>> _serializers;
-
-  Case(this.tagger, Map<String, TextSerializer<T>> tagsAndSerializers)
-      : _tags = tagsAndSerializers.keys.toList(),
-        _serializers = tagsAndSerializers.values.toList();
-
-  Case.uninitialized(this.tagger)
-      : _tags = [],
-        _serializers = [];
-
-  void registerTags(Map<String, TextSerializer<T>> tagsAndSerializers) {
-    _tags.addAll(tagsAndSerializers.keys);
-    _serializers.addAll(tagsAndSerializers.values);
-  }
-
-  @override
-  T readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    Object? iterator = stream.current;
-    if (iterator is! Iterator<Object?>) {
-      throw StateError("Expected list, found atom: '${iterator}'.");
-    }
-    iterator.moveNext();
-    Object? element = iterator.current;
-    if (element is! String) {
-      throw StateError("Expected atom, found list: '${element}'.");
-    }
-    String tag = element;
-    for (int i = 0; i < _tags.length; ++i) {
-      if (_tags[i] == tag) {
-        iterator.moveNext();
-        T result = _serializers[i].readFrom(iterator, state);
-        if (iterator.moveNext()) {
-          throw StateError(
-              "Extra data in tagged '${tag}': '${iterator.current}'.");
-        }
-        stream.moveNext();
-        return result;
-      }
-    }
-    throw StateError("Unrecognized tag '${tag}'.");
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, T object, SerializationState? state) {
-    String tag = tagger.tag(object);
-    for (int i = 0; i < _tags.length; ++i) {
-      if (_tags[i] == tag) {
-        buffer.write("(${tag}");
-        if (!_serializers[i].isEmpty) {
-          buffer.write(" ");
-        }
-        _serializers[i].writeTo(buffer, object, state);
-        buffer.write(")");
-        return;
-      }
-    }
-    throw StateError("Unrecognized tag '${tag}'.");
-  }
-}
-
-// A serializer/deserializer that unwraps/wraps nodes before serialization and
-// after deserialization.
-class Wrapped<S, K> extends TextSerializer<K> {
-  final S Function(K) unwrap;
-  final K Function(S) wrap;
-  final TextSerializer<S> contents;
-
-  const Wrapped(this.unwrap, this.wrap, this.contents);
-
-  @override
-  K readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    return wrap(contents.readFrom(stream, state));
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, K object, SerializationState? state) {
-    contents.writeTo(buffer, unwrap(object), state);
-  }
-
-  @override
-  bool get isEmpty => contents.isEmpty;
-}
-
-class ScopedUse<T extends Node> extends TextSerializer<T> {
-  final DartString stringSerializer = const DartString();
-
-  const ScopedUse();
-
-  @override
-  T readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No deserialization state provided for ${runtimeType}.readFrom.");
-    }
-    return state.environment.lookup(stringSerializer.readFrom(stream, null))
-        as T;
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, T object, SerializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No serialization state provided for ${runtimeType}.writeTo.");
-    }
-    stringSerializer.writeTo(buffer, state.environment.lookup(object), null);
-  }
-}
-
-// A serializer/deserializer for pairs.
-class Tuple2Serializer<T1, T2> extends TextSerializer<Tuple2<T1, T2>> {
-  final TextSerializer<T1> first;
-  final TextSerializer<T2> second;
-
-  const Tuple2Serializer(this.first, this.second);
-
-  @override
-  Tuple2<T1, T2> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    return new Tuple2(
-        first.readFrom(stream, state), second.readFrom(stream, state));
-  }
-
-  @override
-  void writeTo(
-      StringBuffer buffer, Tuple2<T1, T2> object, SerializationState? state) {
-    first.writeTo(buffer, object.first, state);
-    if (!second.isEmpty) buffer.write(' ');
-    second.writeTo(buffer, object.second, state);
-  }
-}
-
-class Tuple2<T1, T2> {
-  final T1 first;
-  final T2 second;
-
-  const Tuple2(this.first, this.second);
-}
-
-class Tuple3Serializer<T1, T2, T3> extends TextSerializer<Tuple3<T1, T2, T3>> {
-  final TextSerializer<T1> first;
-  final TextSerializer<T2> second;
-  final TextSerializer<T3> third;
-
-  const Tuple3Serializer(this.first, this.second, this.third);
-
-  @override
-  Tuple3<T1, T2, T3> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    return new Tuple3(first.readFrom(stream, state),
-        second.readFrom(stream, state), third.readFrom(stream, state));
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, Tuple3<T1, T2, T3> object,
-      SerializationState? state) {
-    first.writeTo(buffer, object.first, state);
-    if (!second.isEmpty) buffer.write(' ');
-    second.writeTo(buffer, object.second, state);
-    if (!third.isEmpty) buffer.write(' ');
-    third.writeTo(buffer, object.third, state);
-  }
-}
-
-class Tuple3<T1, T2, T3> {
-  final T1 first;
-  final T2 second;
-  final T3 third;
-
-  const Tuple3(this.first, this.second, this.third);
-}
-
-class Tuple4Serializer<T1, T2, T3, T4>
-    extends TextSerializer<Tuple4<T1, T2, T3, T4>> {
-  final TextSerializer<T1> first;
-  final TextSerializer<T2> second;
-  final TextSerializer<T3> third;
-  final TextSerializer<T4> fourth;
-
-  const Tuple4Serializer(this.first, this.second, this.third, this.fourth);
-
-  @override
-  Tuple4<T1, T2, T3, T4> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    return new Tuple4(
-        first.readFrom(stream, state),
-        second.readFrom(stream, state),
-        third.readFrom(stream, state),
-        fourth.readFrom(stream, state));
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, Tuple4<T1, T2, T3, T4> object,
-      SerializationState? state) {
-    first.writeTo(buffer, object.first, state);
-    if (!second.isEmpty) buffer.write(' ');
-    second.writeTo(buffer, object.second, state);
-    if (!third.isEmpty) buffer.write(' ');
-    third.writeTo(buffer, object.third, state);
-    if (!fourth.isEmpty) buffer.write(' ');
-    fourth.writeTo(buffer, object.fourth, state);
-  }
-}
-
-class Tuple4<T1, T2, T3, T4> {
-  final T1 first;
-  final T2 second;
-  final T3 third;
-  final T4 fourth;
-
-  const Tuple4(this.first, this.second, this.third, this.fourth);
-}
-
-class Tuple5Serializer<T1, T2, T3, T4, T5>
-    extends TextSerializer<Tuple5<T1, T2, T3, T4, T5>> {
-  final TextSerializer<T1> first;
-  final TextSerializer<T2> second;
-  final TextSerializer<T3> third;
-  final TextSerializer<T4> fourth;
-  final TextSerializer<T5> fifth;
-
-  const Tuple5Serializer(
-      this.first, this.second, this.third, this.fourth, this.fifth);
-
-  @override
-  Tuple5<T1, T2, T3, T4, T5> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    return new Tuple5(
-        first.readFrom(stream, state),
-        second.readFrom(stream, state),
-        third.readFrom(stream, state),
-        fourth.readFrom(stream, state),
-        fifth.readFrom(stream, state));
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, Tuple5<T1, T2, T3, T4, T5> object,
-      SerializationState? state) {
-    first.writeTo(buffer, object.first, state);
-    if (!second.isEmpty) buffer.write(' ');
-    second.writeTo(buffer, object.second, state);
-    if (!third.isEmpty) buffer.write(' ');
-    third.writeTo(buffer, object.third, state);
-    if (!fourth.isEmpty) buffer.write(' ');
-    fourth.writeTo(buffer, object.fourth, state);
-    if (!fifth.isEmpty) buffer.write(' ');
-    fifth.writeTo(buffer, object.fifth, state);
-  }
-}
-
-class Tuple5<T1, T2, T3, T4, T5> {
-  final T1 first;
-  final T2 second;
-  final T3 third;
-  final T4 fourth;
-  final T5 fifth;
-
-  const Tuple5(this.first, this.second, this.third, this.fourth, this.fifth);
-}
-
-class Tuple6Serializer<T1, T2, T3, T4, T5, T6>
-    extends TextSerializer<Tuple6<T1, T2, T3, T4, T5, T6>> {
-  final TextSerializer<T1> first;
-  final TextSerializer<T2> second;
-  final TextSerializer<T3> third;
-  final TextSerializer<T4> fourth;
-  final TextSerializer<T5> fifth;
-  final TextSerializer<T6> sixth;
-
-  const Tuple6Serializer(
-      this.first, this.second, this.third, this.fourth, this.fifth, this.sixth);
-
-  @override
-  Tuple6<T1, T2, T3, T4, T5, T6> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    return new Tuple6(
-        first.readFrom(stream, state),
-        second.readFrom(stream, state),
-        third.readFrom(stream, state),
-        fourth.readFrom(stream, state),
-        fifth.readFrom(stream, state),
-        sixth.readFrom(stream, state));
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, Tuple6<T1, T2, T3, T4, T5, T6> object,
-      SerializationState? state) {
-    first.writeTo(buffer, object.first, state);
-    if (!second.isEmpty) buffer.write(' ');
-    second.writeTo(buffer, object.second, state);
-    if (!third.isEmpty) buffer.write(' ');
-    third.writeTo(buffer, object.third, state);
-    if (!fourth.isEmpty) buffer.write(' ');
-    fourth.writeTo(buffer, object.fourth, state);
-    if (!fifth.isEmpty) buffer.write(' ');
-    fifth.writeTo(buffer, object.fifth, state);
-    if (!sixth.isEmpty) buffer.write(' ');
-    sixth.writeTo(buffer, object.sixth, state);
-  }
-}
-
-class Tuple6<T1, T2, T3, T4, T5, T6> {
-  final T1 first;
-  final T2 second;
-  final T3 third;
-  final T4 fourth;
-  final T5 fifth;
-  final T6 sixth;
-
-  const Tuple6(
-      this.first, this.second, this.third, this.fourth, this.fifth, this.sixth);
-}
-
-class Tuple7Serializer<T1, T2, T3, T4, T5, T6, T7>
-    extends TextSerializer<Tuple7<T1, T2, T3, T4, T5, T6, T7>> {
-  final TextSerializer<T1> first;
-  final TextSerializer<T2> second;
-  final TextSerializer<T3> third;
-  final TextSerializer<T4> fourth;
-  final TextSerializer<T5> fifth;
-  final TextSerializer<T6> sixth;
-  final TextSerializer<T7> seventh;
-
-  const Tuple7Serializer(this.first, this.second, this.third, this.fourth,
-      this.fifth, this.sixth, this.seventh);
-
-  @override
-  Tuple7<T1, T2, T3, T4, T5, T6, T7> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    return new Tuple7(
-        first.readFrom(stream, state),
-        second.readFrom(stream, state),
-        third.readFrom(stream, state),
-        fourth.readFrom(stream, state),
-        fifth.readFrom(stream, state),
-        sixth.readFrom(stream, state),
-        seventh.readFrom(stream, state));
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, Tuple7<T1, T2, T3, T4, T5, T6, T7> object,
-      SerializationState? state) {
-    first.writeTo(buffer, object.first, state);
-    if (!second.isEmpty) buffer.write(' ');
-    second.writeTo(buffer, object.second, state);
-    if (!third.isEmpty) buffer.write(' ');
-    third.writeTo(buffer, object.third, state);
-    if (!fourth.isEmpty) buffer.write(' ');
-    fourth.writeTo(buffer, object.fourth, state);
-    if (!fifth.isEmpty) buffer.write(' ');
-    fifth.writeTo(buffer, object.fifth, state);
-    if (!sixth.isEmpty) buffer.write(' ');
-    sixth.writeTo(buffer, object.sixth, state);
-    if (!seventh.isEmpty) buffer.write(' ');
-    seventh.writeTo(buffer, object.seventh, state);
-  }
-}
-
-class Tuple7<T1, T2, T3, T4, T5, T6, T7> {
-  final T1 first;
-  final T2 second;
-  final T3 third;
-  final T4 fourth;
-  final T5 fifth;
-  final T6 sixth;
-  final T7 seventh;
-
-  const Tuple7(this.first, this.second, this.third, this.fourth, this.fifth,
-      this.sixth, this.seventh);
-}
-
-class Tuple8Serializer<T1, T2, T3, T4, T5, T6, T7, T8>
-    extends TextSerializer<Tuple8<T1, T2, T3, T4, T5, T6, T7, T8>> {
-  final TextSerializer<T1> first;
-  final TextSerializer<T2> second;
-  final TextSerializer<T3> third;
-  final TextSerializer<T4> fourth;
-  final TextSerializer<T5> fifth;
-  final TextSerializer<T6> sixth;
-  final TextSerializer<T7> seventh;
-  final TextSerializer<T8> eighth;
-
-  const Tuple8Serializer(this.first, this.second, this.third, this.fourth,
-      this.fifth, this.sixth, this.seventh, this.eighth);
-
-  @override
-  Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    return new Tuple8(
-        first.readFrom(stream, state),
-        second.readFrom(stream, state),
-        third.readFrom(stream, state),
-        fourth.readFrom(stream, state),
-        fifth.readFrom(stream, state),
-        sixth.readFrom(stream, state),
-        seventh.readFrom(stream, state),
-        eighth.readFrom(stream, state));
-  }
-
-  @override
-  void writeTo(
-      StringBuffer buffer,
-      Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> object,
-      SerializationState? state) {
-    first.writeTo(buffer, object.first, state);
-    if (!second.isEmpty) buffer.write(' ');
-    second.writeTo(buffer, object.second, state);
-    if (!third.isEmpty) buffer.write(' ');
-    third.writeTo(buffer, object.third, state);
-    if (!fourth.isEmpty) buffer.write(' ');
-    fourth.writeTo(buffer, object.fourth, state);
-    if (!fifth.isEmpty) buffer.write(' ');
-    fifth.writeTo(buffer, object.fifth, state);
-    if (!sixth.isEmpty) buffer.write(' ');
-    sixth.writeTo(buffer, object.sixth, state);
-    if (!seventh.isEmpty) buffer.write(' ');
-    seventh.writeTo(buffer, object.seventh, state);
-    if (!eighth.isEmpty) buffer.write(' ');
-    eighth.writeTo(buffer, object.eighth, state);
-  }
-}
-
-class Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> {
-  final T1 first;
-  final T2 second;
-  final T3 third;
-  final T4 fourth;
-  final T5 fifth;
-  final T6 sixth;
-  final T7 seventh;
-  final T8 eighth;
-
-  const Tuple8(this.first, this.second, this.third, this.fourth, this.fifth,
-      this.sixth, this.seventh, this.eighth);
-}
-
-// A serializer/deserializer for lists.
-class ListSerializer<T> extends TextSerializer<List<T>> {
-  final TextSerializer<T> elements;
-
-  const ListSerializer(this.elements);
-
-  @override
-  List<T> readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    Object? iterator = stream.current;
-    if (iterator is! Iterator<Object?>) {
-      throw StateError("Expected a list, found an atom: '${iterator}'.");
-    }
-    iterator.moveNext();
-    List<T> result = [];
-    while (iterator.current != null) {
-      result.add(elements.readFrom(iterator, state));
-    }
-    stream.moveNext();
-    return result;
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, List<T> object, SerializationState? state) {
-    buffer.write('(');
-    for (int i = 0; i < object.length; ++i) {
-      if (i != 0) buffer.write(' ');
-      elements.writeTo(buffer, object[i], state);
-    }
-    buffer.write(')');
-  }
-}
-
-class Optional<T> extends TextSerializer<T?> {
-  final TextSerializer<T> contents;
-
-  const Optional(this.contents);
-
-  @override
-  T? readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    if (stream.current == '_') {
-      stream.moveNext();
-      return null;
-    }
-    return contents.readFrom(stream, state);
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, T? object, SerializationState? state) {
-    if (object == null) {
-      buffer.write('_');
-    } else {
-      contents.writeTo(buffer, object, state);
-    }
-  }
-}
-
-/// Introduces a binder to the environment.
-///
-/// Serializes an object and uses it as a binder for the name that is retrieved
-/// from the object using [nameGetter] and (temporarily) modified using
-/// [nameSetter].  The binder is added to the enclosing environment.
-class Binder<T extends Node> extends TextSerializer<Tuple2<String?, T>> {
-  final Tuple2Serializer<String, T> namedContents;
-
-  Binder(TextSerializer<T> contents)
-      : namedContents = new Tuple2Serializer(const DartString(), contents);
-
-  @override
-  Tuple2<String, T> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No deserialization state provided for ${runtimeType}.readFrom.");
-    }
-    Tuple2<String, T> namedObject = namedContents.readFrom(stream, state);
-    String name = namedObject.first;
-    T object = namedObject.second;
-    state.environment.addBinder(object, name);
-    return new Tuple2(name, object);
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, Tuple2<String?, T> namedObject,
-      SerializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No serialization state provided for ${runtimeType}.writeTo.");
-    }
-    String? nameClue = namedObject.first;
-    T object = namedObject.second;
-    String distinctName =
-        state.environment.addBinder(object, nameClue: nameClue);
-    namedContents.writeTo(buffer, new Tuple2(distinctName, object), state);
-  }
-}
-
-/// Binds binders from one term in the other.
-///
-/// Serializes a [Tuple2] of [pattern] and [term], closing [term] over the
-/// binders found in [pattern].  The binders aren't added to the enclosing
-/// environment.
-class Bind<P, T> extends TextSerializer<Tuple2<P, T>> {
-  final TextSerializer<P> pattern;
-  final TextSerializer<T> term;
-
-  const Bind(this.pattern, this.term);
-
-  @override
-  Tuple2<P, T> readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No deserialization state provided for ${runtimeType}.readFrom.");
-    }
-    DeserializationState bindingState = new DeserializationState(
-        new DeserializationEnvironment(state.environment), state.nameRoot);
-    P first = pattern.readFrom(stream, bindingState);
-    bindingState.environment.extend();
-    T second = term.readFrom(stream, bindingState);
-    return new Tuple2(first, second);
-  }
-
-  @override
-  void writeTo(
-      StringBuffer buffer, Tuple2<P, T> tuple, SerializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No serialization state provided for ${runtimeType}.writeTo.");
-    }
-    SerializationState bindingState =
-        new SerializationState(new SerializationEnvironment(state.environment));
-    pattern.writeTo(buffer, tuple.first, bindingState);
-    bindingState.environment.extend();
-    buffer.write(' ');
-    term.writeTo(buffer, tuple.second, bindingState);
-  }
-}
-
-/// Nested binding pattern that also binds binders from one term in the other.
-///
-/// Serializes a [Tuple2] of [pattern1] and [pattern2], closing [pattern2] over
-/// the binders found in [pattern1].  The binders from both [pattern1] and
-/// [pattern2] are added to the enclosing environment.
-class Rebind<P, T> extends TextSerializer<Tuple2<P, T>> {
-  final TextSerializer<P> pattern1;
-  final TextSerializer<T> pattern2;
-
-  const Rebind(this.pattern1, this.pattern2);
-
-  @override
-  Tuple2<P, T> readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No deserialization state provided for ${runtimeType}.readFrom.");
-    }
-    P first = pattern1.readFrom(stream, state);
-    DeserializationState closedState = new DeserializationState(
-        new DeserializationEnvironment(state.environment)
-          ..binders.addAll(state.environment.binders)
-          ..extend(),
-        state.nameRoot);
-    T second = pattern2.readFrom(stream, closedState);
-    state.environment.binders.addAll(closedState.environment.binders);
-    return new Tuple2(first, second);
-  }
-
-  @override
-  void writeTo(
-      StringBuffer buffer, Tuple2<P, T> tuple, SerializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No serialization state provided for ${runtimeType}.writeTo.");
-    }
-    pattern1.writeTo(buffer, tuple.first, state);
-    SerializationState closedState =
-        new SerializationState(new SerializationEnvironment(state.environment)
-          ..binders.addAll(state.environment.binders)
-          ..extend());
-    buffer.write(' ');
-    pattern2.writeTo(buffer, tuple.second, closedState);
-    state.environment.binders.addAll(closedState.environment.binders);
-  }
-}
-
-class Zip<T, T1, T2> extends TextSerializer<List<T>> {
-  final TextSerializer<Tuple2<List<T1>, List<T2>>> lists;
-  final T Function(T1, T2) zip;
-  final Tuple2<T1, T2> Function(T) unzip;
-
-  const Zip(this.lists, this.zip, this.unzip);
-
-  @override
-  List<T> readFrom(Iterator<Object?> stream, DeserializationState? state) {
-    Tuple2<List<T1>, List<T2>> toZip = lists.readFrom(stream, state);
-    List<T1> firsts = toZip.first;
-    List<T> zipped;
-    if (firsts.isEmpty) {
-      zipped = <T>[];
-    } else {
-      List<T2> seconds = toZip.second;
-      zipped =
-          new List<T>.filled(toZip.first.length, zip(firsts[0], seconds[0]));
-      for (int i = 1; i < zipped.length; ++i) {
-        zipped[i] = zip(firsts[i], seconds[i]);
-      }
-    }
-    return zipped;
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, List<T> zipped, SerializationState? state) {
-    List<T1> firsts;
-    List<T2> seconds;
-    if (zipped.isEmpty) {
-      firsts = <T1>[];
-      seconds = <T2>[];
-    } else {
-      Tuple2<T1, T2> initial = unzip(zipped[0]);
-      firsts = new List<T1>.filled(zipped.length, initial.first);
-      seconds = new List<T2>.filled(zipped.length, initial.second);
-      for (int i = 1; i < zipped.length; ++i) {
-        Tuple2<T1, T2> tuple = unzip(zipped[i]);
-        firsts[i] = tuple.first;
-        seconds[i] = tuple.second;
-      }
-    }
-    lists.writeTo(buffer, new Tuple2(firsts, seconds), state);
-  }
-}
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
deleted file mode 100644
index a8a0283..0000000
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ /dev/null
@@ -1,308 +0,0 @@
-// 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 'dart:convert' show json;
-
-import '../ast.dart';
-
-import '../text/serializer_combinators.dart';
-
-import '../text/text_reader.dart' show TextIterator;
-
-import '../text/text_serializer.dart';
-
-const Uri? noUri = null;
-
-const int noOffset = -1;
-
-abstract class RoundTripStatus implements Comparable<RoundTripStatus> {
-  /// The round-trip serialization was run on that [node].
-  final Node node;
-
-  /// The context of the failure.
-  ///
-  /// The [context] node is a [TreeNode] and is set either to the node that the
-  /// round-trip serialization failed on or to the closest parent with location.
-  final TreeNode context;
-
-  RoundTripStatus(this.node, {required TreeNode context})
-      : context = node is TreeNode && node.location != null ? node : context;
-
-  Uri? get uri => context.location?.file;
-
-  int get offset => context.fileOffset;
-
-  bool get isSuccess;
-
-  bool get isFailure => !isSuccess;
-
-  String get nameForDebugging;
-
-  @override
-  int compareTo(RoundTripStatus other) {
-    Node thisNode = this.node;
-    Node otherNode = other.node;
-    if (thisNode is TreeNode && otherNode is TreeNode) {
-      Uri? thisUri = thisNode.location?.file;
-      Uri? otherUri = otherNode.location?.file;
-      int thisOffset = thisNode.fileOffset;
-      int otherOffset = otherNode.fileOffset;
-
-      int compareUri;
-      if (thisUri == null && otherUri == null) {
-        compareUri = 0;
-      } else if (thisUri == null) {
-        compareUri = 1;
-      } else if (otherUri == null) {
-        compareUri = -1;
-      } else {
-        // ignore: unnecessary_null_comparison
-        assert(thisUri != null && otherUri != null);
-        compareUri = thisUri.toString().compareTo(otherUri.toString());
-      }
-      if (compareUri != 0) return compareUri;
-
-      int compareOffset;
-      // ignore: unnecessary_null_comparison
-      if (thisOffset == null && otherOffset == null) {
-        compareOffset = 0;
-        // ignore: unnecessary_null_comparison
-      } else if (thisOffset == null) {
-        compareOffset = 1;
-        // ignore: unnecessary_null_comparison
-      } else if (otherOffset == null) {
-        compareOffset = -1;
-      } else {
-        compareOffset = thisOffset = otherOffset;
-      }
-      if (compareOffset != 0) return compareOffset;
-
-      // The "success" outcome has the lowest index.  Make it so that it appears
-      // last, and the failures are at the beginning and are more visible.
-      if (isFailure && other.isSuccess) {
-        return -1;
-      }
-      if (isSuccess && other.isFailure) {
-        return 1;
-      }
-
-      return 0;
-    } else if (node is TreeNode) {
-      return -1;
-    } else {
-      return 1;
-    }
-  }
-
-  void printOn(StringBuffer sb) {
-    sb.writeln(""
-        ";; -------------------------------------"
-        "----------------------------------------");
-    sb.writeln("Status: ${nameForDebugging}");
-    sb.writeln("Node type: ${node.runtimeType}");
-    sb.writeln("Node: ${json.encode(node.leakingDebugToString())}");
-    Node treeNode = node;
-    if (treeNode is TreeNode) {
-      if (treeNode.parent != null) {
-        sb.writeln("Parent type: ${treeNode.parent.runtimeType}");
-        sb.writeln(
-            "Parent: ${json.encode(treeNode.parent!.leakingDebugToString())}");
-      }
-    }
-  }
-
-  @override
-  String toString() {
-    StringBuffer sb = new StringBuffer();
-    printOn(sb);
-    return sb.toString();
-  }
-}
-
-class RoundTripSuccess extends RoundTripStatus {
-  final String serialized;
-
-  RoundTripSuccess(Node node, this.serialized, {required TreeNode context})
-      : super(node, context: context);
-
-  @override
-  bool get isSuccess => true;
-
-  @override
-  String get nameForDebugging => "RoundTripSuccess";
-
-  @override
-  void printOn(StringBuffer sb) {
-    super.printOn(sb);
-    sb.writeln("Serialized: ${serialized}");
-  }
-}
-
-class RoundTripInitialSerializationFailure extends RoundTripStatus {
-  final String message;
-
-  RoundTripInitialSerializationFailure(Node node, this.message,
-      {required TreeNode context})
-      : super(node, context: context);
-
-  @override
-  bool get isSuccess => false;
-
-  @override
-  String get nameForDebugging => "RoundTripInitialSerializationFailure";
-
-  @override
-  void printOn(StringBuffer sb) {
-    super.printOn(sb);
-    sb.writeln("Message: ${message}");
-  }
-}
-
-class RoundTripDeserializationFailure extends RoundTripStatus {
-  final String message;
-
-  RoundTripDeserializationFailure(Node node, this.message,
-      {required TreeNode context})
-      : super(node, context: context);
-
-  @override
-  bool get isSuccess => false;
-
-  @override
-  String get nameForDebugging => "RoundTripDeserializationFailure";
-
-  @override
-  void printOn(StringBuffer sb) {
-    super.printOn(sb);
-    sb.writeln("Message: ${message}");
-  }
-}
-
-class RoundTripSecondSerializationFailure extends RoundTripStatus {
-  final String initial;
-  final String serialized;
-
-  RoundTripSecondSerializationFailure(Node node, this.initial, this.serialized,
-      {required TreeNode context})
-      : super(node, context: context);
-
-  @override
-  bool get isSuccess => false;
-
-  @override
-  String get nameForDebugging => "RoundTripSecondSerializationFailure";
-
-  @override
-  void printOn(StringBuffer sb) {
-    super.printOn(sb);
-    sb.writeln("Initial: ${initial}");
-    sb.writeln("Serialized: ${serialized}");
-  }
-}
-
-class TextSerializationVerifier {
-  static const bool showStackTrace = bool.fromEnvironment(
-      "text_serialization.showStackTrace",
-      defaultValue: false);
-
-  /// List of status for all round-trip serialization attempts.
-  final List<RoundTripStatus> _status = <RoundTripStatus>[];
-
-  final CanonicalName root;
-
-  TextSerializationVerifier({CanonicalName? root})
-      : root = root ?? new CanonicalName.root() {
-    initializeSerializers();
-  }
-
-  /// List of errors produced during round trips on the visited nodes.
-  Iterable<RoundTripStatus> get _failures => _status.where((s) => s.isFailure);
-
-  List<RoundTripStatus> get failures => _failures.toList()..sort();
-
-  void verify(Library node) {
-    makeRoundTrip<Library>(node, librarySerializer);
-  }
-
-  T? readNode<T extends TreeNode>(
-      T node, String input, TextSerializer<T> serializer) {
-    TextIterator stream = new TextIterator(input, 0);
-    stream.moveNext();
-    T result;
-    try {
-      result = serializer.readFrom(stream,
-          new DeserializationState(new DeserializationEnvironment(null), root));
-    } catch (exception, stackTrace) {
-      String message =
-          showStackTrace ? "${exception}\n${stackTrace}" : "${exception}";
-      _status.add(
-          new RoundTripDeserializationFailure(node, message, context: node));
-      return null;
-    }
-    if (stream.moveNext()) {
-      _status.add(new RoundTripDeserializationFailure(
-          node, "unexpected trailing text",
-          context: node));
-    }
-    // ignore: unnecessary_null_comparison
-    if (result == null) {
-      _status.add(new RoundTripDeserializationFailure(
-          node, "Deserialization of the following returned null: '${input}'",
-          context: node));
-    }
-    return result;
-  }
-
-  String writeNode<T extends TreeNode>(T node, TextSerializer<T> serializer) {
-    StringBuffer buffer = new StringBuffer();
-    try {
-      serializer.writeTo(buffer, node,
-          new SerializationState(new SerializationEnvironment(null)));
-    } catch (exception, stackTrace) {
-      String message =
-          showStackTrace ? "${exception}\n${stackTrace}" : "${exception}";
-      _status.add(new RoundTripInitialSerializationFailure(node, message,
-          context: node));
-    }
-    return buffer.toString();
-  }
-
-  void makeRoundTrip<T extends TreeNode>(T node, TextSerializer<T> serializer) {
-    int failureCount = _failures.length;
-    String initial = writeNode(node, serializer);
-    if (_failures.length != failureCount) {
-      return;
-    }
-
-    // Do the round trip.
-    T? deserialized = readNode(node, initial, serializer);
-    if (_failures.length != failureCount) {
-      return;
-    }
-
-    if (deserialized == null) {
-      // The error is reported elsewhere for the case of null.
-      return;
-    }
-
-    String serialized = writeNode(deserialized, serializer);
-    if (_failures.length != failureCount) {
-      return;
-    }
-
-    if (initial != serialized) {
-      _status.add(new RoundTripSecondSerializationFailure(
-          node, initial, serialized,
-          context: node));
-    } else {
-      _status.add(new RoundTripSuccess(node, initial, context: node));
-    }
-  }
-
-  List<RoundTripStatus> takeStatus() {
-    List<RoundTripStatus> result = _status.toList()..sort();
-    _status.clear();
-    return result;
-  }
-}
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
deleted file mode 100644
index 9aa5e0e..0000000
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ /dev/null
@@ -1,2916 +0,0 @@
-// Copyright (c) 2018, 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.
-
-library kernel.text_serializer;
-
-import '../ast.dart';
-
-import 'serializer_combinators.dart';
-
-abstract class Tagger<T> {
-  String tag(T object);
-}
-
-class NameTagger implements Tagger<Name> {
-  const NameTagger();
-
-  @override
-  String tag(Name name) => name.isPrivate ? "private" : "public";
-}
-
-TextSerializer<Name> publicName =
-    Wrapped<String, Name>((w) => w.text, (u) => Name(u), const DartString());
-
-TextSerializer<Name> privateName = Wrapped<Tuple2<String, CanonicalName>, Name>(
-    (w) => Tuple2(w.text, w.library!.reference.canonicalName!),
-    (u) => Name.byReference(u.first, u.second.reference),
-    Tuple2Serializer(DartString(), CanonicalNameSerializer()));
-
-TextSerializer<Name> nameSerializer = new Case(
-    const NameTagger(), {"public": publicName, "private": privateName});
-
-class ExpressionTagger extends ExpressionVisitor<String>
-    implements Tagger<Expression> {
-  const ExpressionTagger();
-
-  @override
-  String tag(Expression expression) => expression.accept(this);
-
-  @override
-  String visitStringLiteral(StringLiteral _) => "string";
-  @override
-  String visitIntLiteral(IntLiteral _) => "int";
-  @override
-  String visitDoubleLiteral(DoubleLiteral _) => "double";
-  @override
-  String visitBoolLiteral(BoolLiteral _) => "bool";
-  @override
-  String visitNullLiteral(NullLiteral _) => "null";
-  @override
-  String visitInvalidExpression(InvalidExpression _) => "invalid";
-  @override
-  String visitNot(Not _) => "not";
-  @override
-  String visitLogicalExpression(LogicalExpression expression) {
-    return logicalExpressionOperatorToString(expression.operatorEnum);
-  }
-
-  @override
-  String visitStringConcatenation(StringConcatenation _) => "concat";
-  @override
-  String visitSymbolLiteral(SymbolLiteral _) => "symbol";
-  @override
-  String visitThisExpression(ThisExpression _) => "this";
-  @override
-  String visitRethrow(Rethrow _) => "rethrow";
-  @override
-  String visitThrow(Throw _) => "throw";
-  @override
-  String visitAwaitExpression(AwaitExpression _) => "await";
-  @override
-  String visitConditionalExpression(ConditionalExpression _) => "cond";
-  @override
-  String visitIsExpression(IsExpression _) => "is";
-  @override
-  String visitAsExpression(AsExpression _) => "as";
-  @override
-  String visitTypeLiteral(TypeLiteral _) => "type";
-  @override
-  String visitListLiteral(ListLiteral expression) {
-    return expression.isConst ? "const-list" : "list";
-  }
-
-  @override
-  String visitSetLiteral(SetLiteral expression) {
-    return expression.isConst ? "const-set" : "set";
-  }
-
-  @override
-  String visitMapLiteral(MapLiteral expression) {
-    return expression.isConst ? "const-map" : "map";
-  }
-
-  @override
-  String visitLet(Let _) => "let";
-
-  @override
-  String visitInstanceGet(InstanceGet _) => "get-instance";
-  @override
-  String visitInstanceSet(InstanceSet _) => "set-instance";
-  @override
-  String visitDynamicGet(DynamicGet _) => "get-dynamic";
-  @override
-  String visitDynamicSet(DynamicSet _) => "set-dynamic";
-  @override
-  String visitInstanceTearOff(InstanceTearOff _) => "tearoff-instance";
-  @override
-  String visitFunctionTearOff(FunctionTearOff _) => "tearoff-function";
-  @override
-  String visitSuperPropertyGet(SuperPropertyGet _) => "get-super";
-  @override
-  String visitSuperPropertySet(SuperPropertySet _) => "set-super";
-  @override
-  String visitInstanceInvocation(InstanceInvocation _) => "invoke-instance";
-  @override
-  String visitInstanceGetterInvocation(InstanceGetterInvocation _) =>
-      "invoke-instance-getter";
-  @override
-  String visitDynamicInvocation(DynamicInvocation _) => "invoke-dynamic";
-  @override
-  String visitFunctionInvocation(FunctionInvocation _) => "invoke-function";
-  @override
-  String visitLocalFunctionInvocation(LocalFunctionInvocation _) =>
-      "invoke-local-function";
-  @override
-  String visitEqualsNull(EqualsNull _) => "equals-null";
-  @override
-  String visitEqualsCall(EqualsCall _) => "equals-call";
-  @override
-  String visitSuperMethodInvocation(SuperMethodInvocation _) => "invoke-super";
-
-  @override
-  String visitVariableGet(VariableGet _) => "get-var";
-  @override
-  String visitVariableSet(VariableSet _) => "set-var";
-  @override
-  String visitStaticGet(StaticGet _) => "get-static";
-  @override
-  String visitStaticSet(StaticSet _) => "set-static";
-  @override
-  String visitStaticTearOff(StaticTearOff _) => "tearoff-static";
-  @override
-  String visitConstructorTearOff(ConstructorTearOff _) => "tearoff-constructor";
-  @override
-  String visitRedirectingFactoryTearOff(RedirectingFactoryTearOff _) =>
-      "tearoff-redirecting-factory";
-  @override
-  String visitTypedefTearOff(TypedefTearOff _) => "tearoff-typedef";
-  @override
-  String visitStaticInvocation(StaticInvocation expression) {
-    return expression.isConst ? "invoke-const-static" : "invoke-static";
-  }
-
-  @override
-  String visitConstructorInvocation(ConstructorInvocation expression) {
-    return expression.isConst
-        ? "invoke-const-constructor"
-        : "invoke-constructor";
-  }
-
-  @override
-  String visitFunctionExpression(FunctionExpression _) => "fun";
-  @override
-  String visitListConcatenation(ListConcatenation _) => "lists";
-  @override
-  String visitSetConcatenation(SetConcatenation _) => "sets";
-  @override
-  String visitMapConcatenation(MapConcatenation _) => "maps";
-  @override
-  String visitBlockExpression(BlockExpression _) => "let-block";
-  @override
-  String visitInstantiation(Instantiation _) => "apply";
-  @override
-  String visitNullCheck(NullCheck _) => "not-null";
-  @override
-  String visitFileUriExpression(FileUriExpression _) => "with-uri";
-  @override
-  String visitCheckLibraryIsLoaded(CheckLibraryIsLoaded _) => "is-loaded";
-  @override
-  String visitLoadLibrary(LoadLibrary _) => "load";
-  @override
-  String visitConstantExpression(ConstantExpression _) => "const";
-  @override
-  String visitInstanceCreation(InstanceCreation _) => "object";
-
-  @override
-  String defaultExpression(Expression node) {
-    throw new UnimplementedError(
-        'Unimplemented expression $node (${node.runtimeType})');
-  }
-}
-
-TextSerializer<InvalidExpression> invalidExpressionSerializer =
-    new Wrapped<Tuple2<String?, Expression?>, InvalidExpression>(
-        unwrapInvalidExpression,
-        wrapInvalidExpression,
-        Tuple2Serializer<String?, Expression?>(
-            Optional(DartString()), Optional(expressionSerializer)));
-
-Tuple2<String?, Expression?> unwrapInvalidExpression(
-    InvalidExpression expression) {
-  return Tuple2(expression.message, expression.expression);
-}
-
-InvalidExpression wrapInvalidExpression(Tuple2<String?, Expression?> tuple) {
-  return new InvalidExpression(tuple.first, tuple.second);
-}
-
-TextSerializer<Not> notSerializer =
-    new Wrapped<Expression, Not>(unwrapNot, wrapNot, expressionSerializer);
-
-Expression unwrapNot(Not expression) => expression.operand;
-
-Not wrapNot(Expression operand) => new Not(operand);
-
-TextSerializer<LogicalExpression> logicalAndSerializer =
-    new Wrapped<Tuple2<Expression, Expression>, LogicalExpression>(
-        unwrapLogicalExpression,
-        wrapLogicalAnd,
-        new Tuple2Serializer(expressionSerializer, expressionSerializer));
-
-Tuple2<Expression, Expression> unwrapLogicalExpression(
-    LogicalExpression expression) {
-  return new Tuple2(expression.left, expression.right);
-}
-
-LogicalExpression wrapLogicalAnd(Tuple2<Expression, Expression> tuple) {
-  return new LogicalExpression(
-      tuple.first, LogicalExpressionOperator.AND, tuple.second);
-}
-
-TextSerializer<LogicalExpression> logicalOrSerializer =
-    new Wrapped<Tuple2<Expression, Expression>, LogicalExpression>(
-        unwrapLogicalExpression,
-        wrapLogicalOr,
-        new Tuple2Serializer(expressionSerializer, expressionSerializer));
-
-LogicalExpression wrapLogicalOr(Tuple2<Expression, Expression> tuple) {
-  return new LogicalExpression(
-      tuple.first, LogicalExpressionOperator.OR, tuple.second);
-}
-
-TextSerializer<StringConcatenation> stringConcatenationSerializer =
-    new Wrapped<List<Expression>, StringConcatenation>(
-        unwrapStringConcatenation,
-        wrapStringConcatenation,
-        new ListSerializer(expressionSerializer));
-
-List<Expression> unwrapStringConcatenation(StringConcatenation expression) {
-  return expression.expressions;
-}
-
-StringConcatenation wrapStringConcatenation(List<Expression> expressions) {
-  return new StringConcatenation(expressions);
-}
-
-const TextSerializer<StringLiteral> stringLiteralSerializer =
-    const Wrapped<String, StringLiteral>(
-        unwrapStringLiteral, wrapStringLiteral, const DartString());
-
-String unwrapStringLiteral(StringLiteral literal) => literal.value;
-
-StringLiteral wrapStringLiteral(String value) => new StringLiteral(value);
-
-const TextSerializer<IntLiteral> intLiteralSerializer =
-    const Wrapped<int, IntLiteral>(
-        unwrapIntLiteral, wrapIntLiteral, const DartInt());
-
-int unwrapIntLiteral(IntLiteral literal) => literal.value;
-
-IntLiteral wrapIntLiteral(int value) => new IntLiteral(value);
-
-const TextSerializer<DoubleLiteral> doubleLiteralSerializer =
-    const Wrapped<double, DoubleLiteral>(
-        unwrapDoubleLiteral, wrapDoubleLiteral, const DartDouble());
-
-double unwrapDoubleLiteral(DoubleLiteral literal) => literal.value;
-
-DoubleLiteral wrapDoubleLiteral(double value) => new DoubleLiteral(value);
-
-const TextSerializer<BoolLiteral> boolLiteralSerializer =
-    const Wrapped<bool, BoolLiteral>(
-        unwrapBoolLiteral, wrapBoolLiteral, const DartBool());
-
-bool unwrapBoolLiteral(BoolLiteral literal) => literal.value;
-
-BoolLiteral wrapBoolLiteral(bool value) => new BoolLiteral(value);
-
-const TextSerializer<NullLiteral> nullLiteralSerializer =
-    const Wrapped<void, NullLiteral>(
-        unwrapNullLiteral, wrapNullLiteral, const Nothing());
-
-void unwrapNullLiteral(NullLiteral literal) {}
-
-NullLiteral wrapNullLiteral(void ignored) => new NullLiteral();
-
-const TextSerializer<SymbolLiteral> symbolLiteralSerializer =
-    const Wrapped<String, SymbolLiteral>(
-        unwrapSymbolLiteral, wrapSymbolLiteral, const DartString());
-
-String unwrapSymbolLiteral(SymbolLiteral expression) => expression.value;
-
-SymbolLiteral wrapSymbolLiteral(String value) => new SymbolLiteral(value);
-
-const TextSerializer<ThisExpression> thisExpressionSerializer =
-    const Wrapped<void, ThisExpression>(
-        unwrapThisExpression, wrapThisExpression, const Nothing());
-
-void unwrapThisExpression(ThisExpression expression) {}
-
-ThisExpression wrapThisExpression(void ignored) => new ThisExpression();
-
-const TextSerializer<Rethrow> rethrowSerializer =
-    const Wrapped<void, Rethrow>(unwrapRethrow, wrapRethrow, const Nothing());
-
-void unwrapRethrow(Rethrow expression) {}
-
-Rethrow wrapRethrow(void ignored) => new Rethrow();
-
-TextSerializer<Throw> throwSerializer = new Wrapped<Expression, Throw>(
-    unwrapThrow, wrapThrow, expressionSerializer);
-
-Expression unwrapThrow(Throw expression) => expression.expression;
-
-Throw wrapThrow(Expression expression) => new Throw(expression);
-
-TextSerializer<AwaitExpression> awaitExpressionSerializer =
-    new Wrapped<Expression, AwaitExpression>(
-        unwrapAwaitExpression, wrapAwaitExpression, expressionSerializer);
-
-Expression unwrapAwaitExpression(AwaitExpression expression) =>
-    expression.operand;
-
-AwaitExpression wrapAwaitExpression(Expression operand) =>
-    new AwaitExpression(operand);
-
-TextSerializer<ConditionalExpression> conditionalExpressionSerializer =
-    new Wrapped<Tuple4<Expression, DartType, Expression, Expression>,
-            ConditionalExpression>(
-        unwrapConditionalExpression,
-        wrapConditionalExpression,
-        new Tuple4Serializer(expressionSerializer, dartTypeSerializer,
-            expressionSerializer, expressionSerializer));
-
-Tuple4<Expression, DartType, Expression, Expression>
-    unwrapConditionalExpression(ConditionalExpression expression) {
-  return new Tuple4(expression.condition, expression.staticType,
-      expression.then, expression.otherwise);
-}
-
-ConditionalExpression wrapConditionalExpression(
-    Tuple4<Expression, DartType, Expression, Expression> tuple) {
-  return new ConditionalExpression(
-      tuple.first, tuple.third, tuple.fourth, tuple.second);
-}
-
-TextSerializer<IsExpression> isExpressionSerializer =
-    new Wrapped<Tuple2<Expression, DartType>, IsExpression>(
-        unwrapIsExpression,
-        wrapIsExpression,
-        new Tuple2Serializer(expressionSerializer, dartTypeSerializer));
-
-Tuple2<Expression, DartType> unwrapIsExpression(IsExpression expression) {
-  return new Tuple2(expression.operand, expression.type);
-}
-
-IsExpression wrapIsExpression(Tuple2<Expression, DartType> tuple) {
-  return new IsExpression(tuple.first, tuple.second);
-}
-
-TextSerializer<AsExpression> asExpressionSerializer =
-    new Wrapped<Tuple2<Expression, DartType>, AsExpression>(
-        unwrapAsExpression,
-        wrapAsExpression,
-        new Tuple2Serializer(expressionSerializer, dartTypeSerializer));
-
-Tuple2<Expression, DartType> unwrapAsExpression(AsExpression expression) {
-  return new Tuple2(expression.operand, expression.type);
-}
-
-AsExpression wrapAsExpression(Tuple2<Expression, DartType> tuple) {
-  return new AsExpression(tuple.first, tuple.second);
-}
-
-TextSerializer<TypeLiteral> typeLiteralSerializer =
-    new Wrapped<DartType, TypeLiteral>(
-        unwrapTypeLiteral, wrapTypeLiteral, dartTypeSerializer);
-
-DartType unwrapTypeLiteral(TypeLiteral expression) => expression.type;
-
-TypeLiteral wrapTypeLiteral(DartType type) => new TypeLiteral(type);
-
-TextSerializer<ListLiteral> listLiteralSerializer =
-    new Wrapped<Tuple2<DartType, List<Expression>>, ListLiteral>(
-        unwrapListLiteral,
-        wrapListLiteral,
-        new Tuple2Serializer(
-            dartTypeSerializer, new ListSerializer(expressionSerializer)));
-
-Tuple2<DartType, List<Expression>> unwrapListLiteral(ListLiteral expression) {
-  return new Tuple2(expression.typeArgument, expression.expressions);
-}
-
-ListLiteral wrapListLiteral(Tuple2<DartType, List<Expression>> tuple) {
-  return new ListLiteral(tuple.second,
-      typeArgument: tuple.first, isConst: false);
-}
-
-TextSerializer<ListLiteral> constListLiteralSerializer =
-    new Wrapped<Tuple2<DartType, List<Expression>>, ListLiteral>(
-        unwrapListLiteral,
-        wrapConstListLiteral,
-        new Tuple2Serializer(
-            dartTypeSerializer, new ListSerializer(expressionSerializer)));
-
-ListLiteral wrapConstListLiteral(Tuple2<DartType, List<Expression>> tuple) {
-  return new ListLiteral(tuple.second,
-      typeArgument: tuple.first, isConst: true);
-}
-
-TextSerializer<SetLiteral> setLiteralSerializer =
-    new Wrapped<Tuple2<DartType, List<Expression>>, SetLiteral>(
-        unwrapSetLiteral,
-        wrapSetLiteral,
-        new Tuple2Serializer(
-            dartTypeSerializer, new ListSerializer(expressionSerializer)));
-
-Tuple2<DartType, List<Expression>> unwrapSetLiteral(SetLiteral expression) {
-  return new Tuple2(expression.typeArgument, expression.expressions);
-}
-
-SetLiteral wrapSetLiteral(Tuple2<DartType, List<Expression>> tuple) {
-  return new SetLiteral(tuple.second,
-      typeArgument: tuple.first, isConst: false);
-}
-
-TextSerializer<SetLiteral> constSetLiteralSerializer =
-    new Wrapped<Tuple2<DartType, List<Expression>>, SetLiteral>(
-        unwrapSetLiteral,
-        wrapConstSetLiteral,
-        new Tuple2Serializer(
-            dartTypeSerializer, new ListSerializer(expressionSerializer)));
-
-SetLiteral wrapConstSetLiteral(Tuple2<DartType, List<Expression>> tuple) {
-  return new SetLiteral(tuple.second, typeArgument: tuple.first, isConst: true);
-}
-
-TextSerializer<MapLiteral> mapLiteralSerializer =
-    new Wrapped<Tuple3<DartType, DartType, List<Expression>>, MapLiteral>(
-        unwrapMapLiteral,
-        wrapMapLiteral,
-        new Tuple3Serializer(dartTypeSerializer, dartTypeSerializer,
-            new ListSerializer(expressionSerializer)));
-
-Tuple3<DartType, DartType, List<Expression>> unwrapMapLiteral(
-    MapLiteral expression) {
-  List<Expression> entries =
-      new List.filled(2 * expression.entries.length, dummyExpression);
-  for (int from = 0, to = 0; from < expression.entries.length; ++from) {
-    MapLiteralEntry entry = expression.entries[from];
-    entries[to++] = entry.key;
-    entries[to++] = entry.value;
-  }
-  return new Tuple3(expression.keyType, expression.valueType, entries);
-}
-
-MapLiteral wrapMapLiteral(Tuple3<DartType, DartType, List<Expression>> tuple) {
-  List<MapLiteralEntry> entries =
-      new List.filled(tuple.third.length ~/ 2, dummyMapLiteralEntry);
-  for (int from = 0, to = 0; to < entries.length; ++to) {
-    entries[to] = new MapLiteralEntry(tuple.third[from++], tuple.third[from++]);
-  }
-  return new MapLiteral(entries,
-      keyType: tuple.first, valueType: tuple.second, isConst: false);
-}
-
-TextSerializer<MapLiteral> constMapLiteralSerializer =
-    new Wrapped<Tuple3<DartType, DartType, List<Expression>>, MapLiteral>(
-        unwrapMapLiteral,
-        wrapConstMapLiteral,
-        new Tuple3Serializer(dartTypeSerializer, dartTypeSerializer,
-            new ListSerializer(expressionSerializer)));
-
-MapLiteral wrapConstMapLiteral(
-    Tuple3<DartType, DartType, List<Expression>> tuple) {
-  List<MapLiteralEntry> entries =
-      new List.filled(tuple.third.length ~/ 2, dummyMapLiteralEntry);
-  for (int from = 0, to = 0; to < entries.length; ++to) {
-    entries[to] = new MapLiteralEntry(tuple.third[from++], tuple.third[from++]);
-  }
-  return new MapLiteral(entries,
-      keyType: tuple.first, valueType: tuple.second, isConst: true);
-}
-
-TextSerializer<Let> letSerializer =
-    new Wrapped<Tuple2<VariableDeclaration, Expression>, Let>(unwrapLet,
-        wrapLet, new Bind(variableDeclarationSerializer, expressionSerializer));
-
-Tuple2<VariableDeclaration, Expression> unwrapLet(Let expression) {
-  return new Tuple2(expression.variable, expression.body);
-}
-
-Let wrapLet(Tuple2<VariableDeclaration, Expression> tuple) {
-  return new Let(tuple.first, tuple.second);
-}
-
-TextSerializer<InstanceGet> instanceGetSerializer = new Wrapped<
-        Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>,
-        InstanceGet>(
-    unwrapInstanceGet,
-    wrapInstanceGet,
-    new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
-        nameSerializer, canonicalNameSerializer, dartTypeSerializer));
-
-Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
-    unwrapInstanceGet(InstanceGet expression) {
-  return new Tuple5(
-      expression.kind,
-      expression.receiver,
-      expression.name,
-      expression.interfaceTargetReference.canonicalName!,
-      expression.resultType);
-}
-
-InstanceGet wrapInstanceGet(
-    Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
-        tuple) {
-  return new InstanceGet.byReference(tuple.first, tuple.second, tuple.third,
-      interfaceTargetReference: tuple.fourth.reference,
-      resultType: tuple.fifth);
-}
-
-TextSerializer<InstanceSet> instanceSetSerializer = new Wrapped<
-        Tuple5<InstanceAccessKind, Expression, Name, Expression, CanonicalName>,
-        InstanceSet>(
-    unwrapInstanceSet,
-    wrapInstanceSet,
-    new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
-        nameSerializer, expressionSerializer, canonicalNameSerializer));
-
-Tuple5<InstanceAccessKind, Expression, Name, Expression, CanonicalName>
-    unwrapInstanceSet(InstanceSet expression) {
-  return new Tuple5(expression.kind, expression.receiver, expression.name,
-      expression.value, expression.interfaceTargetReference.canonicalName!);
-}
-
-InstanceSet wrapInstanceSet(
-    Tuple5<InstanceAccessKind, Expression, Name, Expression, CanonicalName>
-        tuple) {
-  return new InstanceSet.byReference(
-      tuple.first, tuple.second, tuple.third, tuple.fourth,
-      interfaceTargetReference: tuple.fifth.reference);
-}
-
-TextSerializer<DynamicGet> dynamicGetSerializer =
-    new Wrapped<Tuple3<DynamicAccessKind, Expression, Name>, DynamicGet>(
-        unwrapDynamicGet,
-        wrapDynamicGet,
-        new Tuple3Serializer(
-            dynamicAccessKindSerializer, expressionSerializer, nameSerializer));
-
-Tuple3<DynamicAccessKind, Expression, Name> unwrapDynamicGet(
-    DynamicGet expression) {
-  return new Tuple3(expression.kind, expression.receiver, expression.name);
-}
-
-DynamicGet wrapDynamicGet(Tuple3<DynamicAccessKind, Expression, Name> tuple) {
-  return new DynamicGet(tuple.first, tuple.second, tuple.third);
-}
-
-TextSerializer<DynamicSet> dynamicSetSerializer = new Wrapped<
-        Tuple4<DynamicAccessKind, Expression, Name, Expression>, DynamicSet>(
-    unwrapDynamicSet,
-    wrapDynamicSet,
-    new Tuple4Serializer(dynamicAccessKindSerializer, expressionSerializer,
-        nameSerializer, expressionSerializer));
-
-Tuple4<DynamicAccessKind, Expression, Name, Expression> unwrapDynamicSet(
-    DynamicSet expression) {
-  return new Tuple4(
-      expression.kind, expression.receiver, expression.name, expression.value);
-}
-
-DynamicSet wrapDynamicSet(
-    Tuple4<DynamicAccessKind, Expression, Name, Expression> tuple) {
-  return new DynamicSet(tuple.first, tuple.second, tuple.third, tuple.fourth);
-}
-
-TextSerializer<InstanceTearOff> instanceTearOffSerializer = new Wrapped<
-        Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>,
-        InstanceTearOff>(
-    unwrapInstanceTearOff,
-    wrapInstanceTearOff,
-    new Tuple5Serializer(instanceAccessKindSerializer, expressionSerializer,
-        nameSerializer, canonicalNameSerializer, dartTypeSerializer));
-
-Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
-    unwrapInstanceTearOff(InstanceTearOff expression) {
-  return new Tuple5(
-      expression.kind,
-      expression.receiver,
-      expression.name,
-      expression.interfaceTargetReference.canonicalName!,
-      expression.resultType);
-}
-
-InstanceTearOff wrapInstanceTearOff(
-    Tuple5<InstanceAccessKind, Expression, Name, CanonicalName, DartType>
-        tuple) {
-  return new InstanceTearOff.byReference(tuple.first, tuple.second, tuple.third,
-      interfaceTargetReference: tuple.fourth.reference,
-      resultType: tuple.fifth);
-}
-
-TextSerializer<FunctionTearOff> functionTearOffSerializer =
-    new Wrapped<Expression, FunctionTearOff>(
-        unwrapFunctionTearOff, wrapFunctionTearOff, expressionSerializer);
-
-Expression unwrapFunctionTearOff(FunctionTearOff expression) {
-  return expression.receiver;
-}
-
-FunctionTearOff wrapFunctionTearOff(Expression expression) {
-  return new FunctionTearOff(expression);
-}
-
-TextSerializer<SuperPropertyGet> superPropertyGetSerializer =
-    new Wrapped<Name, SuperPropertyGet>(
-        unwrapSuperPropertyGet, wrapSuperPropertyGet, nameSerializer);
-
-Name unwrapSuperPropertyGet(SuperPropertyGet expression) {
-  return expression.name;
-}
-
-SuperPropertyGet wrapSuperPropertyGet(Name name) {
-  return new SuperPropertyGet(name);
-}
-
-TextSerializer<SuperPropertySet> superPropertySetSerializer =
-    new Wrapped<Tuple2<Name, Expression>, SuperPropertySet>(
-        unwrapSuperPropertySet,
-        wrapSuperPropertySet,
-        new Tuple2Serializer(nameSerializer, expressionSerializer));
-
-Tuple2<Name, Expression> unwrapSuperPropertySet(SuperPropertySet expression) {
-  return new Tuple2(expression.name, expression.value);
-}
-
-SuperPropertySet wrapSuperPropertySet(Tuple2<Name, Expression> tuple) {
-  return new SuperPropertySet(tuple.first, tuple.second, null);
-}
-
-const Map<InstanceAccessKind, String> instanceAccessKindToName = const {
-  InstanceAccessKind.Instance: "instance",
-  InstanceAccessKind.Object: "object",
-  InstanceAccessKind.Nullable: "nullable",
-  InstanceAccessKind.Inapplicable: "inapplicable",
-};
-
-class InstanceAccessKindTagger implements Tagger<InstanceAccessKind> {
-  const InstanceAccessKindTagger();
-
-  @override
-  String tag(InstanceAccessKind kind) {
-    return instanceAccessKindToName[kind] ??
-        (throw StateError("Unknown InstanceAccessKind flag value: ${kind}."));
-  }
-}
-
-TextSerializer<InstanceAccessKind> instanceAccessKindSerializer =
-    Case(InstanceAccessKindTagger(), convertFlagsMap(instanceAccessKindToName));
-
-TextSerializer<InstanceInvocation> instanceInvocationSerializer = new Wrapped<
-        Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
-            DartType>,
-        InstanceInvocation>(
-    unwrapInstanceInvocation,
-    wrapInstanceInvocation,
-    new Tuple6Serializer(
-        instanceAccessKindSerializer,
-        expressionSerializer,
-        nameSerializer,
-        argumentsSerializer,
-        canonicalNameSerializer,
-        dartTypeSerializer));
-
-Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName, DartType>
-    unwrapInstanceInvocation(InstanceInvocation expression) {
-  return new Tuple6(
-      expression.kind,
-      expression.receiver,
-      expression.name,
-      expression.arguments,
-      expression.interfaceTargetReference.canonicalName!,
-      expression.functionType);
-}
-
-InstanceInvocation wrapInstanceInvocation(
-    Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
-            DartType>
-        tuple) {
-  return new InstanceInvocation.byReference(
-      tuple.first, tuple.second, tuple.third, tuple.fourth,
-      interfaceTargetReference: tuple.fifth.reference,
-      functionType: tuple.sixth as FunctionType);
-}
-
-TextSerializer<
-    InstanceGetterInvocation> instanceGetterInvocationSerializer = new Wrapped<
-        Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
-            DartType?>,
-        InstanceGetterInvocation>(
-    unwrapInstanceGetterInvocation,
-    wrapInstanceGetterInvocation,
-    new Tuple6Serializer(
-        instanceAccessKindSerializer,
-        expressionSerializer,
-        nameSerializer,
-        argumentsSerializer,
-        const CanonicalNameSerializer(),
-        Optional(dartTypeSerializer)));
-
-Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
-        DartType?>
-    unwrapInstanceGetterInvocation(InstanceGetterInvocation expression) {
-  return new Tuple6(
-      expression.kind,
-      expression.receiver,
-      expression.name,
-      expression.arguments,
-      expression.interfaceTargetReference.canonicalName!,
-      expression.functionType);
-}
-
-InstanceGetterInvocation wrapInstanceGetterInvocation(
-    Tuple6<InstanceAccessKind, Expression, Name, Arguments, CanonicalName,
-            DartType?>
-        tuple) {
-  return new InstanceGetterInvocation.byReference(
-      tuple.first, tuple.second, tuple.third, tuple.fourth,
-      interfaceTargetReference: tuple.fifth.reference,
-      functionType: tuple.sixth as FunctionType?);
-}
-
-const Map<DynamicAccessKind, String> dynamicAccessKindToName = const {
-  DynamicAccessKind.Dynamic: "dynamic",
-  DynamicAccessKind.Never: "never",
-  DynamicAccessKind.Invalid: "invalid",
-  DynamicAccessKind.Unresolved: "unresolved",
-};
-
-class DynamicAccessKindTagger implements Tagger<DynamicAccessKind> {
-  const DynamicAccessKindTagger();
-
-  @override
-  String tag(DynamicAccessKind kind) {
-    return dynamicAccessKindToName[kind] ??
-        (throw StateError("Unknown DynamicAccessKind flag value: ${kind}."));
-  }
-}
-
-TextSerializer<DynamicAccessKind> dynamicAccessKindSerializer =
-    Case(DynamicAccessKindTagger(), convertFlagsMap(dynamicAccessKindToName));
-
-TextSerializer<DynamicInvocation> dynamicInvocationSerializer = new Wrapped<
-        Tuple4<DynamicAccessKind, Expression, Name, Arguments>,
-        DynamicInvocation>(
-    unwrapDynamicInvocation,
-    wrapDynamicInvocation,
-    new Tuple4Serializer(dynamicAccessKindSerializer, expressionSerializer,
-        nameSerializer, argumentsSerializer));
-
-Tuple4<DynamicAccessKind, Expression, Name, Arguments> unwrapDynamicInvocation(
-    DynamicInvocation expression) {
-  return new Tuple4(expression.kind, expression.receiver, expression.name,
-      expression.arguments);
-}
-
-DynamicInvocation wrapDynamicInvocation(
-    Tuple4<DynamicAccessKind, Expression, Name, Arguments> tuple) {
-  return new DynamicInvocation(
-      tuple.first, tuple.second, tuple.third, tuple.fourth);
-}
-
-const Map<FunctionAccessKind, String> functionAccessKindToName = const {
-  FunctionAccessKind.Function: "function",
-  FunctionAccessKind.FunctionType: "function-type",
-  FunctionAccessKind.Inapplicable: "inapplicable",
-  FunctionAccessKind.Nullable: "nullable",
-};
-
-class FunctionAccessKindTagger implements Tagger<FunctionAccessKind> {
-  const FunctionAccessKindTagger();
-
-  @override
-  String tag(FunctionAccessKind kind) {
-    return functionAccessKindToName[kind] ??
-        (throw StateError("Unknown FunctionAccessKind flag value: ${kind}."));
-  }
-}
-
-TextSerializer<FunctionAccessKind> functionAccessKindSerializer =
-    Case(FunctionAccessKindTagger(), convertFlagsMap(functionAccessKindToName));
-
-TextSerializer<FunctionInvocation> functionInvocationSerializer = new Wrapped<
-        Tuple4<FunctionAccessKind, Expression, Arguments, DartType?>,
-        FunctionInvocation>(
-    unwrapFunctionInvocation,
-    wrapFunctionInvocation,
-    new Tuple4Serializer(functionAccessKindSerializer, expressionSerializer,
-        argumentsSerializer, new Optional(dartTypeSerializer)));
-
-Tuple4<FunctionAccessKind, Expression, Arguments, DartType?>
-    unwrapFunctionInvocation(FunctionInvocation expression) {
-  return new Tuple4(expression.kind, expression.receiver, expression.arguments,
-      expression.functionType);
-}
-
-FunctionInvocation wrapFunctionInvocation(
-    Tuple4<FunctionAccessKind, Expression, Arguments, DartType?> tuple) {
-  return new FunctionInvocation(tuple.first, tuple.second, tuple.third,
-      functionType: tuple.fourth as FunctionType?);
-}
-
-TextSerializer<LocalFunctionInvocation> localFunctionInvocationSerializer =
-    new Wrapped<Tuple3<VariableDeclaration, Arguments, DartType>,
-            LocalFunctionInvocation>(
-        unwrapLocalFunctionInvocation,
-        wrapLocalFunctionInvocation,
-        new Tuple3Serializer(const ScopedUse<VariableDeclaration>(),
-            argumentsSerializer, dartTypeSerializer));
-
-Tuple3<VariableDeclaration, Arguments, DartType> unwrapLocalFunctionInvocation(
-    LocalFunctionInvocation expression) {
-  return new Tuple3(
-      expression.variable, expression.arguments, expression.functionType);
-}
-
-LocalFunctionInvocation wrapLocalFunctionInvocation(
-    Tuple3<VariableDeclaration, Arguments, DartType> tuple) {
-  return new LocalFunctionInvocation(tuple.first, tuple.second,
-      functionType: tuple.third as FunctionType);
-}
-
-TextSerializer<EqualsNull> equalsNullSerializer =
-    new Wrapped<Expression, EqualsNull>(
-        unwrapEqualsNull, wrapEqualsNull, expressionSerializer);
-
-Expression unwrapEqualsNull(EqualsNull expression) {
-  return expression.expression;
-}
-
-EqualsNull wrapEqualsNull(Expression expression) {
-  return new EqualsNull(expression);
-}
-
-TextSerializer<EqualsCall> equalsCallSerializer = new Wrapped<
-        Tuple4<Expression, Expression, CanonicalName, DartType>, EqualsCall>(
-    unwrapEqualsCall,
-    wrapEqualsCall,
-    new Tuple4Serializer(expressionSerializer, expressionSerializer,
-        canonicalNameSerializer, dartTypeSerializer));
-
-Tuple4<Expression, Expression, CanonicalName, DartType> unwrapEqualsCall(
-    EqualsCall expression) {
-  return new Tuple4(
-      expression.left,
-      expression.right,
-      expression.interfaceTargetReference.canonicalName!,
-      expression.functionType);
-}
-
-EqualsCall wrapEqualsCall(
-    Tuple4<Expression, Expression, CanonicalName, DartType> tuple) {
-  return new EqualsCall.byReference(tuple.first, tuple.second,
-      interfaceTargetReference: tuple.third.reference,
-      functionType: tuple.fourth as FunctionType);
-}
-
-TextSerializer<SuperMethodInvocation> superMethodInvocationSerializer =
-    new Wrapped<Tuple2<Name, Arguments>, SuperMethodInvocation>(
-        unwrapSuperMethodInvocation,
-        wrapSuperMethodInvocation,
-        new Tuple2Serializer(nameSerializer, argumentsSerializer));
-
-Tuple2<Name, Arguments> unwrapSuperMethodInvocation(
-    SuperMethodInvocation expression) {
-  return new Tuple2(expression.name, expression.arguments);
-}
-
-SuperMethodInvocation wrapSuperMethodInvocation(Tuple2<Name, Arguments> tuple) {
-  return new SuperMethodInvocation(tuple.first, tuple.second);
-}
-
-TextSerializer<VariableGet> variableGetSerializer =
-    new Wrapped<Tuple2<VariableDeclaration, DartType?>, VariableGet>(
-        unwrapVariableGet,
-        wrapVariableGet,
-        new Tuple2Serializer(const ScopedUse<VariableDeclaration>(),
-            new Optional(dartTypeSerializer)));
-
-Tuple2<VariableDeclaration, DartType?> unwrapVariableGet(VariableGet node) {
-  return new Tuple2<VariableDeclaration, DartType?>(
-      node.variable, node.promotedType);
-}
-
-VariableGet wrapVariableGet(Tuple2<VariableDeclaration, DartType?> tuple) {
-  return new VariableGet(tuple.first, tuple.second);
-}
-
-TextSerializer<VariableSet> variableSetSerializer =
-    new Wrapped<Tuple2<VariableDeclaration, Expression>, VariableSet>(
-        unwrapVariableSet,
-        wrapVariableSet,
-        new Tuple2Serializer(
-            const ScopedUse<VariableDeclaration>(), expressionSerializer));
-
-Tuple2<VariableDeclaration, Expression> unwrapVariableSet(VariableSet node) {
-  return new Tuple2<VariableDeclaration, Expression>(node.variable, node.value);
-}
-
-VariableSet wrapVariableSet(Tuple2<VariableDeclaration, Expression> tuple) {
-  return new VariableSet(tuple.first, tuple.second);
-}
-
-const CanonicalNameSerializer canonicalNameSerializer =
-    const CanonicalNameSerializer();
-
-class CanonicalNameSerializer extends TextSerializer<CanonicalName> {
-  static const String delimiter = "::";
-
-  const CanonicalNameSerializer();
-
-  static void writeName(CanonicalName name, StringBuffer buffer) {
-    if (!name.isRoot) {
-      if (!name.parent!.isRoot) {
-        writeName(name.parent!, buffer);
-        buffer.write(delimiter);
-      }
-      buffer.write(name.name);
-    }
-  }
-
-  @override
-  CanonicalName readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No deserialization state provided for ${runtimeType}.readFrom.");
-    }
-    String string = const DartString().readFrom(stream, state);
-    CanonicalName name = state.nameRoot;
-    for (String s in string.split(delimiter)) {
-      name = name.getChild(s);
-    }
-    return name;
-  }
-
-  @override
-  void writeTo(
-      StringBuffer buffer, CanonicalName name, SerializationState? state) {
-    StringBuffer sb = new StringBuffer();
-    writeName(name, sb);
-    const DartString().writeTo(buffer, sb.toString(), state);
-  }
-}
-
-const TextSerializer<StaticGet> staticGetSerializer =
-    const Wrapped(unwrapStaticGet, wrapStaticGet, canonicalNameSerializer);
-
-CanonicalName unwrapStaticGet(StaticGet expression) {
-  return expression.targetReference.canonicalName!;
-}
-
-StaticGet wrapStaticGet(CanonicalName name) {
-  return new StaticGet.byReference(name.reference);
-}
-
-const TextSerializer<StaticTearOff> staticTearOffSerializer =
-    const Wrapped<CanonicalName, StaticTearOff>(
-        unwrapStaticTearOff, wrapStaticTearOff, canonicalNameSerializer);
-
-CanonicalName unwrapStaticTearOff(StaticTearOff expression) {
-  return expression.targetReference.canonicalName!;
-}
-
-StaticTearOff wrapStaticTearOff(CanonicalName name) {
-  return new StaticTearOff.byReference(name.reference);
-}
-
-const TextSerializer<ConstructorTearOff> constructorTearOffSerializer =
-    const Wrapped<CanonicalName, ConstructorTearOff>(unwrapConstructorTearOff,
-        wrapConstructorTearOff, canonicalNameSerializer);
-
-CanonicalName unwrapConstructorTearOff(ConstructorTearOff expression) {
-  return expression.targetReference.canonicalName!;
-}
-
-ConstructorTearOff wrapConstructorTearOff(CanonicalName name) {
-  return new ConstructorTearOff.byReference(name.reference);
-}
-
-const TextSerializer<RedirectingFactoryTearOff>
-    redirectingFactoryTearOffSerializer =
-    const Wrapped<CanonicalName, RedirectingFactoryTearOff>(
-        unwrapRedirectingFactoryTearOff,
-        wrapRedirectingFactoryTearOff,
-        canonicalNameSerializer);
-
-CanonicalName unwrapRedirectingFactoryTearOff(
-    RedirectingFactoryTearOff expression) {
-  return expression.targetReference.canonicalName!;
-}
-
-RedirectingFactoryTearOff wrapRedirectingFactoryTearOff(CanonicalName name) {
-  return new RedirectingFactoryTearOff.byReference(name.reference);
-}
-
-final TextSerializer<TypedefTearOff> typedefTearOffSerializer = new Wrapped<
-        Tuple2<List<TypeParameter>, Tuple2<Expression, List<DartType>>>,
-        TypedefTearOff>(
-    unwrapTypedefTearOff,
-    wrapTypedefTearOff,
-    Bind(
-        typeParametersSerializer,
-        Tuple2Serializer(
-            expressionSerializer, ListSerializer(dartTypeSerializer))));
-
-Tuple2<List<TypeParameter>, Tuple2<Expression, List<DartType>>>
-    unwrapTypedefTearOff(TypedefTearOff node) {
-  return new Tuple2(
-      node.typeParameters, new Tuple2(node.expression, node.typeArguments));
-}
-
-TypedefTearOff wrapTypedefTearOff(
-    Tuple2<List<TypeParameter>, Tuple2<Expression, List<DartType>>> tuple) {
-  return new TypedefTearOff(
-      tuple.first, tuple.second.first, tuple.second.second);
-}
-
-TextSerializer<StaticSet> staticSetSerializer =
-    new Wrapped<Tuple2<CanonicalName, Expression>, StaticSet>(
-        unwrapStaticSet,
-        wrapStaticSet,
-        new Tuple2Serializer(canonicalNameSerializer, expressionSerializer));
-
-Tuple2<CanonicalName, Expression> unwrapStaticSet(StaticSet expression) {
-  return new Tuple2(
-      expression.targetReference.canonicalName!, expression.value);
-}
-
-StaticSet wrapStaticSet(Tuple2<CanonicalName, Expression> tuple) {
-  return new StaticSet.byReference(tuple.first.reference, tuple.second);
-}
-
-TextSerializer<StaticInvocation> staticInvocationSerializer =
-    new Wrapped<Tuple2<CanonicalName, Arguments>, StaticInvocation>(
-        unwrapStaticInvocation,
-        wrapStaticInvocation,
-        new Tuple2Serializer(canonicalNameSerializer, argumentsSerializer));
-
-Tuple2<CanonicalName, Arguments> unwrapStaticInvocation(
-    StaticInvocation expression) {
-  return new Tuple2(
-      expression.targetReference.canonicalName!, expression.arguments);
-}
-
-StaticInvocation wrapStaticInvocation(Tuple2<CanonicalName, Arguments> tuple) {
-  return new StaticInvocation.byReference(tuple.first.reference, tuple.second,
-      isConst: false);
-}
-
-TextSerializer<StaticInvocation> constStaticInvocationSerializer =
-    new Wrapped<Tuple2<CanonicalName, Arguments>, StaticInvocation>(
-        unwrapStaticInvocation,
-        wrapConstStaticInvocation,
-        new Tuple2Serializer(canonicalNameSerializer, argumentsSerializer));
-
-StaticInvocation wrapConstStaticInvocation(
-    Tuple2<CanonicalName, Arguments> tuple) {
-  return new StaticInvocation.byReference(tuple.first.reference, tuple.second,
-      isConst: true);
-}
-
-TextSerializer<ConstructorInvocation> constructorInvocationSerializer =
-    new Wrapped<Tuple2<CanonicalName, Arguments>, ConstructorInvocation>(
-        unwrapConstructorInvocation,
-        wrapConstructorInvocation,
-        new Tuple2Serializer(canonicalNameSerializer, argumentsSerializer));
-
-Tuple2<CanonicalName, Arguments> unwrapConstructorInvocation(
-    ConstructorInvocation expression) {
-  return new Tuple2(
-      expression.targetReference.canonicalName!, expression.arguments);
-}
-
-ConstructorInvocation wrapConstructorInvocation(
-    Tuple2<CanonicalName, Arguments> tuple) {
-  return new ConstructorInvocation.byReference(
-      tuple.first.reference, tuple.second,
-      isConst: false);
-}
-
-TextSerializer<ConstructorInvocation> constConstructorInvocationSerializer =
-    new Wrapped<Tuple2<CanonicalName, Arguments>, ConstructorInvocation>(
-        unwrapConstructorInvocation,
-        wrapConstConstructorInvocation,
-        Tuple2Serializer(canonicalNameSerializer, argumentsSerializer));
-
-ConstructorInvocation wrapConstConstructorInvocation(
-    Tuple2<CanonicalName, Arguments> tuple) {
-  return new ConstructorInvocation.byReference(
-      tuple.first.reference, tuple.second,
-      isConst: true);
-}
-
-TextSerializer<FunctionExpression> functionExpressionSerializer =
-    new Wrapped<FunctionNode, FunctionExpression>(unwrapFunctionExpression,
-        wrapFunctionExpression, functionNodeSerializer);
-
-FunctionNode unwrapFunctionExpression(FunctionExpression expression) {
-  return expression.function;
-}
-
-FunctionExpression wrapFunctionExpression(FunctionNode node) {
-  return new FunctionExpression(node);
-}
-
-TextSerializer<ListConcatenation> listConcatenationSerializer =
-    Wrapped<Tuple2<DartType, List<Expression>>, ListConcatenation>(
-        (lc) => Tuple2(lc.typeArgument, lc.lists),
-        (t) => ListConcatenation(t.second, typeArgument: t.first),
-        Tuple2Serializer(
-            dartTypeSerializer, ListSerializer(expressionSerializer)));
-
-TextSerializer<SetConcatenation> setConcatenationSerializer =
-    Wrapped<Tuple2<DartType, List<Expression>>, SetConcatenation>(
-        (sc) => Tuple2(sc.typeArgument, sc.sets),
-        (t) => SetConcatenation(t.second, typeArgument: t.first),
-        Tuple2Serializer(
-            dartTypeSerializer, ListSerializer(expressionSerializer)));
-
-TextSerializer<MapConcatenation> mapConcatenationSerializer =
-    Wrapped<Tuple3<DartType, DartType, List<Expression>>, MapConcatenation>(
-        (mc) => Tuple3(mc.keyType, mc.valueType, mc.maps),
-        (t) => MapConcatenation(t.third, keyType: t.first, valueType: t.second),
-        Tuple3Serializer(dartTypeSerializer, dartTypeSerializer,
-            ListSerializer(expressionSerializer)));
-
-TextSerializer<BlockExpression> blockExpressionSerializer =
-    Wrapped<Tuple2<List<Statement>, Expression?>, BlockExpression>(
-        (w) => Tuple2(w.body.statements, w.value),
-        (u) => BlockExpression(Block(u.first), u.second!),
-        const BlockSerializer());
-
-TextSerializer<Instantiation> instantiationSerializer =
-    Wrapped<Tuple2<Expression, List<DartType>>, Instantiation>(
-        (i) => Tuple2(i.expression, i.typeArguments),
-        (t) => Instantiation(t.first, t.second),
-        Tuple2Serializer(
-            expressionSerializer, ListSerializer(dartTypeSerializer)));
-
-TextSerializer<NullCheck> nullCheckSerializer = Wrapped<Expression, NullCheck>(
-    (nc) => nc.operand, (op) => NullCheck(op), expressionSerializer);
-
-TextSerializer<FileUriExpression> fileUriExpressionSerializer =
-    Wrapped<Tuple2<Expression, Uri>, FileUriExpression>(
-        (fue) => Tuple2(fue.expression, fue.fileUri),
-        (t) => FileUriExpression(t.first, t.second),
-        Tuple2Serializer(expressionSerializer, const UriSerializer()));
-
-TextSerializer<CheckLibraryIsLoaded> checkLibraryIsLoadedSerializer =
-    Wrapped<LibraryDependency, CheckLibraryIsLoaded>((clil) => clil.import,
-        (i) => CheckLibraryIsLoaded(i), libraryDependencySerializer);
-
-TextSerializer<LoadLibrary> loadLibrarySerializer =
-    Wrapped<LibraryDependency, LoadLibrary>(
-        (ll) => ll.import, (i) => LoadLibrary(i), libraryDependencySerializer);
-
-TextSerializer<ConstantExpression> constantExpressionSerializer =
-    Wrapped<Tuple2<Constant, DartType>, ConstantExpression>(
-        (ce) => Tuple2(ce.constant, ce.type),
-        (t) => ConstantExpression(t.first, t.second),
-        Tuple2Serializer(constantSerializer, dartTypeSerializer));
-
-TextSerializer<InstanceCreation> instanceCreationSerializer = Wrapped<
-        Tuple6<CanonicalName, List<DartType>, List<CanonicalName>,
-            List<Expression>, List<AssertStatement>, List<Expression>>,
-        InstanceCreation>(
-    (ic) => Tuple6(
-        ic.classReference.canonicalName!,
-        ic.typeArguments,
-        ic.fieldValues.keys.map((r) => r.canonicalName!).toList(),
-        ic.fieldValues.values.toList(),
-        ic.asserts,
-        ic.unusedArguments),
-    (t) => InstanceCreation(
-        t.first.reference,
-        t.second,
-        Map.fromIterables(t.third.map((cn) => cn.reference), t.fourth),
-        t.fifth,
-        t.sixth),
-    Tuple6Serializer(
-        CanonicalNameSerializer(),
-        ListSerializer(dartTypeSerializer),
-        ListSerializer(CanonicalNameSerializer()),
-        ListSerializer(expressionSerializer),
-        ListSerializer(assertStatementSerializer),
-        ListSerializer(expressionSerializer)));
-
-Case<Expression> expressionSerializer =
-    new Case.uninitialized(const ExpressionTagger());
-
-TextSerializer<Expression?> nullableExpressionSerializer =
-    new Optional(expressionSerializer);
-
-TextSerializer<NamedExpression> namedExpressionSerializer =
-    new Wrapped<Tuple2<String, Expression>, NamedExpression>(
-        unwrapNamedExpression,
-        wrapNamedExpression,
-        new Tuple2Serializer(const DartString(), expressionSerializer));
-
-Tuple2<String, Expression> unwrapNamedExpression(NamedExpression expression) {
-  return new Tuple2(expression.name, expression.value);
-}
-
-NamedExpression wrapNamedExpression(Tuple2<String, Expression> tuple) {
-  return new NamedExpression(tuple.first, tuple.second);
-}
-
-TextSerializer<Arguments> argumentsSerializer = new Wrapped<
-        Tuple3<List<DartType>, List<Expression>, List<NamedExpression>>,
-        Arguments>(
-    unwrapArguments,
-    wrapArguments,
-    Tuple3Serializer(
-        new ListSerializer(dartTypeSerializer),
-        new ListSerializer(expressionSerializer),
-        new ListSerializer(namedExpressionSerializer)));
-
-Tuple3<List<DartType>, List<Expression>, List<NamedExpression>> unwrapArguments(
-    Arguments arguments) {
-  return new Tuple3(arguments.types, arguments.positional, arguments.named);
-}
-
-Arguments wrapArguments(
-    Tuple3<List<DartType>, List<Expression>, List<NamedExpression>> tuple) {
-  return new Arguments(tuple.second, types: tuple.first, named: tuple.third);
-}
-
-const Map<int, String> variableDeclarationFlagToName = const {
-  VariableDeclaration.FlagFinal: "final",
-  VariableDeclaration.FlagConst: "const",
-  VariableDeclaration.FlagInitializingFormal: "field-formal",
-  VariableDeclaration.FlagCovariantByDeclaration: "covariant",
-  VariableDeclaration.FlagCovariantByClass: "generic-covariant-impl",
-  VariableDeclaration.FlagLate: "late",
-  VariableDeclaration.FlagRequired: "required",
-  VariableDeclaration.FlagLowered: "lowered",
-  VariableDeclaration.FlagHasDeclaredInitializer: "has-declared-initializer",
-};
-
-class VariableDeclarationFlagTagger implements Tagger<int> {
-  @override
-  String tag(int flag) {
-    return variableDeclarationFlagToName[flag] ??
-        (throw StateError("Unknown VariableDeclaration flag value: ${flag}."));
-  }
-}
-
-TextSerializer<int> variableDeclarationFlagsSerializer =
-    Wrapped<List<int>, int>(
-        (w) => List.generate(30, (i) => w & (1 << i))
-            .where((f) => f != 0)
-            .toList(),
-        (u) => u.fold(0, (fs, f) => fs |= f),
-        ListSerializer(Case(VariableDeclarationFlagTagger(),
-            convertFlagsMap(variableDeclarationFlagToName))));
-
-TextSerializer<VariableDeclaration> variableDeclarationSerializer =
-    Wrapped<Tuple2<String?, VariableDeclaration>, VariableDeclaration>(
-        (v) => Tuple2(v.name, v),
-        (t) => t.second..name = t.first,
-        Binder<VariableDeclaration>(
-          new Wrapped<Tuple4<int, DartType, Expression?, List<Expression>>,
-                  VariableDeclaration>(
-              (w) => Tuple4(w.flags, w.type, w.initializer, w.annotations),
-              (u) => u.fourth.fold(
-                  VariableDeclaration(null,
-                      flags: u.first, type: u.second, initializer: u.third),
-                  (v, a) => v..addAnnotation(a)),
-              Tuple4Serializer(
-                  variableDeclarationFlagsSerializer,
-                  dartTypeSerializer,
-                  new Optional(expressionSerializer),
-                  new ListSerializer(expressionSerializer))),
-        ));
-
-TextSerializer<TypeParameter> typeParameterSerializer =
-    Wrapped<Tuple2<String?, TypeParameter>, TypeParameter>(
-        (p) => Tuple2(p.name, p),
-        (t) => t.second..name = t.first,
-        Binder<TypeParameter>(Wrapped<void, TypeParameter>(
-            (_) => null, (_) => TypeParameter(), const Nothing())));
-
-TextSerializer<List<TypeParameter>> typeParametersSerializer = new Zip(
-    new Rebind(
-        new Zip(
-            new Rebind(new ListSerializer(typeParameterSerializer),
-                new ListSerializer(dartTypeSerializer)),
-            zipTypeParameterBound,
-            unzipTypeParameterBound),
-        new ListSerializer(dartTypeSerializer)),
-    zipTypeParameterDefaultType,
-    unzipTypeParameterDefaultType);
-
-TypeParameter zipTypeParameterBound(TypeParameter node, DartType bound) {
-  return node..bound = bound;
-}
-
-Tuple2<TypeParameter, DartType> unzipTypeParameterBound(TypeParameter node) {
-  return new Tuple2(node, node.bound);
-}
-
-TypeParameter zipTypeParameterDefaultType(
-    TypeParameter node, DartType defaultType) {
-  return node..defaultType = defaultType;
-}
-
-Tuple2<TypeParameter, DartType> unzipTypeParameterDefaultType(
-    TypeParameter node) {
-  return new Tuple2(node, node.defaultType);
-}
-
-class DartTypeTagger extends DartTypeVisitor<String>
-    implements Tagger<DartType> {
-  const DartTypeTagger();
-
-  @override
-  String tag(DartType type) => type.accept(this);
-
-  @override
-  String visitInvalidType(InvalidType _) => "invalid";
-  @override
-  String visitDynamicType(DynamicType _) => "dynamic";
-  @override
-  String visitVoidType(VoidType _) => "void";
-  @override
-  String visitFunctionType(FunctionType _) => "->";
-  @override
-  String visitTypeParameterType(TypeParameterType _) => "par";
-  @override
-  String visitInterfaceType(InterfaceType _) => "interface";
-  @override
-  String visitNeverType(NeverType _) => "never";
-  @override
-  String visitTypedefType(TypedefType _) => "typedef";
-  @override
-  String visitFutureOrType(FutureOrType _) => "futureor";
-  @override
-  String visitNullType(NullType _) => "null-type";
-
-  @override
-  String defaultDartType(DartType node) {
-    throw UnimplementedError('Unimplemented type $node (${node.runtimeType})');
-  }
-}
-
-const TextSerializer<InvalidType> invalidTypeSerializer =
-    const Wrapped<void, InvalidType>(
-        unwrapInvalidType, wrapInvalidType, const Nothing());
-
-void unwrapInvalidType(InvalidType type) {}
-
-InvalidType wrapInvalidType(void ignored) => const InvalidType();
-
-const TextSerializer<DynamicType> dynamicTypeSerializer =
-    const Wrapped<void, DynamicType>(
-        unwrapDynamicType, wrapDynamicType, const Nothing());
-
-void unwrapDynamicType(DynamicType type) {}
-
-DynamicType wrapDynamicType(void ignored) => const DynamicType();
-
-const TextSerializer<VoidType> voidTypeSerializer =
-    const Wrapped<void, VoidType>(
-        unwrapVoidType, wrapVoidType, const Nothing());
-
-void unwrapVoidType(VoidType type) {}
-
-VoidType wrapVoidType(void ignored) => const VoidType();
-
-const TextSerializer<NeverType> neverTypeSerializer =
-    const Wrapped<void, NeverType>(
-        unwrapNeverType, wrapNeverType, const Nothing());
-
-void unwrapNeverType(NeverType type) {}
-
-NeverType wrapNeverType(void ignored) => const NeverType.legacy();
-
-// TODO(cstefantsova):  Also handle nameParameters, and typedefType.
-TextSerializer<FunctionType> functionTypeSerializer = new Wrapped<
-        Tuple2<List<TypeParameter>,
-            Tuple4<List<DartType>, List<DartType>, List<NamedType>, DartType>>,
-        FunctionType>(
-    unwrapFunctionType,
-    wrapFunctionType,
-    new Bind(
-        typeParametersSerializer,
-        new Tuple4Serializer(
-            new ListSerializer(dartTypeSerializer),
-            new ListSerializer(dartTypeSerializer),
-            new ListSerializer(namedTypeSerializer),
-            dartTypeSerializer)));
-
-Tuple2<List<TypeParameter>,
-        Tuple4<List<DartType>, List<DartType>, List<NamedType>, DartType>>
-    unwrapFunctionType(FunctionType type) {
-  return new Tuple2(
-      type.typeParameters,
-      new Tuple4(
-          type.positionalParameters.sublist(0, type.requiredParameterCount),
-          type.positionalParameters.sublist(type.requiredParameterCount),
-          type.namedParameters,
-          type.returnType));
-}
-
-FunctionType wrapFunctionType(
-    Tuple2<List<TypeParameter>,
-            Tuple4<List<DartType>, List<DartType>, List<NamedType>, DartType>>
-        tuple) {
-  return new FunctionType(tuple.second.first + tuple.second.second,
-      tuple.second.fourth, Nullability.legacy,
-      requiredParameterCount: tuple.second.first.length,
-      typeParameters: tuple.first,
-      namedParameters: tuple.second.third);
-}
-
-TextSerializer<NamedType> namedTypeSerializer =
-    new Wrapped<Tuple2<String, DartType>, NamedType>(
-        unwrapNamedType,
-        wrapNamedType,
-        Tuple2Serializer(const DartString(), dartTypeSerializer));
-
-Tuple2<String, DartType> unwrapNamedType(NamedType namedType) {
-  return new Tuple2(namedType.name, namedType.type);
-}
-
-NamedType wrapNamedType(Tuple2<String, DartType> tuple) {
-  return new NamedType(tuple.first, tuple.second);
-}
-
-TextSerializer<TypeParameterType> typeParameterTypeSerializer =
-    new Wrapped<Tuple2<TypeParameter, DartType?>, TypeParameterType>(
-        unwrapTypeParameterType,
-        wrapTypeParameterType,
-        Tuple2Serializer(
-            new ScopedUse<TypeParameter>(), new Optional(dartTypeSerializer)));
-
-Tuple2<TypeParameter, DartType?> unwrapTypeParameterType(
-    TypeParameterType node) {
-  return new Tuple2(node.parameter, node.promotedBound);
-}
-
-TypeParameterType wrapTypeParameterType(
-    Tuple2<TypeParameter, DartType?> tuple) {
-  return new TypeParameterType(tuple.first, Nullability.legacy, tuple.second);
-}
-
-TextSerializer<InterfaceType> interfaceTypeSerializer =
-    new Wrapped<Tuple2<CanonicalName, List<DartType>>, InterfaceType>(
-        unwrapInterfaceType,
-        wrapInterfaceType,
-        Tuple2Serializer(
-            canonicalNameSerializer, new ListSerializer(dartTypeSerializer)));
-
-Tuple2<CanonicalName, List<DartType>> unwrapInterfaceType(InterfaceType node) {
-  return new Tuple2(node.className.canonicalName!, node.typeArguments);
-}
-
-InterfaceType wrapInterfaceType(Tuple2<CanonicalName, List<DartType>> tuple) {
-  return new InterfaceType.byReference(
-      tuple.first.reference, Nullability.legacy, tuple.second);
-}
-
-TextSerializer<TypedefType> typedefTypeSerializer =
-    new Wrapped<Tuple2<CanonicalName, List<DartType>>, TypedefType>(
-        unwrapTypedefType,
-        wrapTypedefType,
-        Tuple2Serializer(
-            canonicalNameSerializer, new ListSerializer(dartTypeSerializer)));
-
-Tuple2<CanonicalName, List<DartType>> unwrapTypedefType(TypedefType node) {
-  return new Tuple2(node.typedefReference.canonicalName!, node.typeArguments);
-}
-
-TypedefType wrapTypedefType(Tuple2<CanonicalName, List<DartType>> tuple) {
-  return new TypedefType.byReference(
-      tuple.first.reference, Nullability.legacy, tuple.second);
-}
-
-TextSerializer<FutureOrType> futureOrTypeSerializer =
-    new Wrapped<DartType, FutureOrType>(
-        unwrapFutureOrType, wrapFutureOrType, dartTypeSerializer);
-
-DartType unwrapFutureOrType(FutureOrType node) {
-  return node.typeArgument;
-}
-
-FutureOrType wrapFutureOrType(DartType typeArgument) {
-  return new FutureOrType(typeArgument, Nullability.legacy);
-}
-
-TextSerializer<NullType> nullTypeSerializer =
-    new Wrapped<void, NullType>(unwrapNullType, wrapNullType, const Nothing());
-
-void unwrapNullType(NullType type) {}
-
-NullType wrapNullType(void ignored) => const NullType();
-
-Case<DartType> dartTypeSerializer =
-    new Case.uninitialized(const DartTypeTagger());
-
-class StatementTagger extends StatementVisitor<String>
-    implements Tagger<Statement> {
-  const StatementTagger();
-
-  @override
-  String tag(Statement statement) => statement.accept(this);
-
-  @override
-  String visitExpressionStatement(ExpressionStatement _) => "expr";
-  @override
-  String visitReturnStatement(ReturnStatement node) {
-    return node.expression == null ? "ret-void" : "ret";
-  }
-
-  @override
-  String visitYieldStatement(YieldStatement _) => "yield";
-  @override
-  String visitBlock(Block _) => "block";
-  @override
-  String visitVariableDeclaration(VariableDeclaration _) => "local";
-  @override
-  String visitIfStatement(IfStatement node) {
-    return node.otherwise == null ? "if" : "if-else";
-  }
-
-  @override
-  String visitEmptyStatement(EmptyStatement node) => "skip";
-  @override
-  String visitWhileStatement(WhileStatement node) => "while";
-  @override
-  String visitDoStatement(DoStatement node) => "do-while";
-  @override
-  String visitForStatement(ForStatement node) => "for";
-  @override
-  String visitForInStatement(ForInStatement node) {
-    return node.isAsync ? "await-for-in" : "for-in";
-  }
-
-  @override
-  String visitAssertStatement(AssertStatement node) => "assert";
-  @override
-  String visitAssertBlock(AssertBlock node) => "assert-block";
-  @override
-  String visitLabeledStatement(LabeledStatement node) => "label";
-  @override
-  String visitBreakStatement(BreakStatement node) => "break";
-  @override
-  String visitTryFinally(TryFinally node) => "try-finally";
-  @override
-  String visitTryCatch(TryCatch node) => "try-catch";
-  @override
-  String visitSwitchStatement(SwitchStatement node) => "switch";
-  @override
-  String visitContinueSwitchStatement(ContinueSwitchStatement node) =>
-      "continue";
-  @override
-  String visitFunctionDeclaration(FunctionDeclaration node) => "local-fun";
-
-  @override
-  String defaultStatement(Statement node) {
-    throw new UnimplementedError(
-        "Unimplemented statement $node (${node.runtimeType})");
-  }
-}
-
-TextSerializer<ExpressionStatement> expressionStatementSerializer =
-    new Wrapped<Expression, ExpressionStatement>(unwrapExpressionStatement,
-        wrapExpressionStatement, expressionSerializer);
-
-Expression unwrapExpressionStatement(ExpressionStatement statement) {
-  return statement.expression;
-}
-
-ExpressionStatement wrapExpressionStatement(Expression expression) {
-  return new ExpressionStatement(expression);
-}
-
-TextSerializer<ReturnStatement> returnStatementSerializer =
-    new Wrapped<Expression?, ReturnStatement>(
-        unwrapReturnStatement, wrapReturnStatement, expressionSerializer);
-
-Expression? unwrapReturnStatement(ReturnStatement statement) {
-  return statement.expression;
-}
-
-ReturnStatement wrapReturnStatement(Expression? expression) {
-  return new ReturnStatement(expression);
-}
-
-TextSerializer<ReturnStatement> returnVoidStatementSerializer =
-    new Wrapped<void, ReturnStatement>(
-        unwrapReturnVoidStatement, wrapReturnVoidStatement, const Nothing());
-
-void unwrapReturnVoidStatement(void ignored) {}
-
-ReturnStatement wrapReturnVoidStatement(void ignored) => new ReturnStatement();
-
-TextSerializer<YieldStatement> yieldStatementSerializer =
-    new Wrapped<Expression, YieldStatement>(
-        unwrapYieldStatement, wrapYieldStatement, expressionSerializer);
-
-Expression unwrapYieldStatement(YieldStatement node) => node.expression;
-
-YieldStatement wrapYieldStatement(Expression expression) {
-  return new YieldStatement(expression);
-}
-
-TextSerializer<AssertStatement> assertStatementSerializer =
-    Wrapped<Tuple4<Expression, Expression?, int, int>, AssertStatement>(
-        (a) => Tuple4(a.condition, a.message, a.conditionStartOffset,
-            a.conditionEndOffset),
-        (t) => AssertStatement(t.first,
-            message: t.second,
-            conditionStartOffset: t.third,
-            conditionEndOffset: t.fourth),
-        Tuple4Serializer(expressionSerializer, nullableExpressionSerializer,
-            const DartInt(), const DartInt()));
-
-TextSerializer<Block> blockSerializer =
-    Wrapped<Tuple2<List<Statement>, Expression?>, Block>(
-        (w) => Tuple2(w.statements, null),
-        (u) => Block(u.first),
-        const BlockSerializer());
-
-TextSerializer<AssertBlock> assertBlockSerializer =
-    Wrapped<Tuple2<List<Statement>, Expression?>, AssertBlock>(
-        (w) => Tuple2(w.statements, null),
-        (u) => AssertBlock(u.first),
-        const BlockSerializer());
-
-/// Serializer for [Block]s.
-///
-/// [BlockSerializer] is a combination of [ListSerializer] and [Bind].  As in
-/// the case of [ListSerializer], [BlockSerializer] is a sequence of statements.
-/// As in the case of [Bind], a statement in a block can be a
-/// [VariableDeclaration] introducing binders that are bound in the rest of the
-/// statements in the block.  Effectively, [BlockSerializer] could have been
-/// expressed in terms of [ListSerializer] and [Bind], but that would transform
-/// blocks like {stmt1; stmt2; stmt3;} into {stmt1; {stmt2; {stmt3; {}}}} via
-/// the round-trip, and an extra pass will be required to flatten the
-/// unnecessary nested blocks.  Instead, [BlockSerializer] is implemented
-/// without direct invocations of either [ListSerializer] or [Bind], but with a
-/// certain internal correspondence to how they work.
-class BlockSerializer
-    extends TextSerializer<Tuple2<List<Statement>, Expression?>> {
-  const BlockSerializer();
-
-  @override
-  Tuple2<List<Statement>, Expression?> readFrom(
-      Iterator<Object?> stream, DeserializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No deserialization state provided for ${runtimeType}.readFrom.");
-    }
-    Object? iterator = stream.current;
-    if (iterator is! Iterator) {
-      throw StateError("Expected a list, found an atom: '${iterator}'.");
-    }
-    iterator.moveNext();
-    List<Statement> statements = [];
-    DeserializationState currentState = state;
-    while (iterator.current != null) {
-      currentState = new DeserializationState(
-          new DeserializationEnvironment(currentState.environment),
-          currentState.nameRoot);
-      statements.add(statementSerializer.readFrom(iterator, currentState));
-      currentState.environment.extend();
-    }
-    stream.moveNext();
-    Expression? expression =
-        nullableExpressionSerializer.readFrom(stream, currentState);
-    return new Tuple2(statements, expression);
-  }
-
-  @override
-  void writeTo(StringBuffer buffer, Tuple2<List<Statement>, Expression?> tuple,
-      SerializationState? state) {
-    if (state == null) {
-      throw StateError(
-          "No serialization state provided for ${runtimeType}.writeTo.");
-    }
-    buffer.write('(');
-    SerializationState currentState = state;
-    for (int i = 0; i < tuple.first.length; ++i) {
-      if (i != 0) buffer.write(' ');
-      currentState = new SerializationState(
-          new SerializationEnvironment(currentState.environment));
-      statementSerializer.writeTo(buffer, tuple.first[i], currentState);
-      currentState.environment.extend();
-    }
-    buffer.write(') ');
-    nullableExpressionSerializer.writeTo(buffer, tuple.second, currentState);
-  }
-}
-
-TextSerializer<IfStatement> ifStatementSerializer =
-    new Wrapped<Tuple2<Expression, Statement>, IfStatement>(
-        unwrapIfStatement,
-        wrapIfStatement,
-        Tuple2Serializer(expressionSerializer, statementSerializer));
-
-Tuple2<Expression, Statement> unwrapIfStatement(IfStatement node) {
-  return new Tuple2(node.condition, node.then);
-}
-
-IfStatement wrapIfStatement(Tuple2<Expression, Statement> tuple) {
-  return new IfStatement(tuple.first, tuple.second, null);
-}
-
-TextSerializer<IfStatement> ifElseStatementSerializer =
-    new Wrapped<Tuple3<Expression, Statement, Statement?>, IfStatement>(
-        unwrapIfElseStatement,
-        wrapIfElseStatement,
-        Tuple3Serializer<Expression, Statement, Statement?>(
-            expressionSerializer, statementSerializer, statementSerializer));
-
-Tuple3<Expression, Statement, Statement?> unwrapIfElseStatement(
-    IfStatement node) {
-  return new Tuple3(node.condition, node.then, node.otherwise);
-}
-
-IfStatement wrapIfElseStatement(
-    Tuple3<Expression, Statement, Statement?> tuple) {
-  return new IfStatement(tuple.first, tuple.second, tuple.third);
-}
-
-TextSerializer<EmptyStatement> emptyStatementSerializer =
-    new Wrapped<void, EmptyStatement>(
-        unwrapEmptyStatement, wrapEmptyStatement, const Nothing());
-
-void unwrapEmptyStatement(EmptyStatement node) {}
-
-EmptyStatement wrapEmptyStatement(void ignored) => new EmptyStatement();
-
-TextSerializer<WhileStatement> whileStatementSerializer =
-    new Wrapped<Tuple2<Expression, Statement>, WhileStatement>(
-        unwrapWhileStatement,
-        wrapWhileStatement,
-        new Tuple2Serializer(expressionSerializer, statementSerializer));
-
-Tuple2<Expression, Statement> unwrapWhileStatement(WhileStatement node) {
-  return new Tuple2(node.condition, node.body);
-}
-
-WhileStatement wrapWhileStatement(Tuple2<Expression, Statement> tuple) {
-  return new WhileStatement(tuple.first, tuple.second);
-}
-
-TextSerializer<DoStatement> doStatementSerializer =
-    new Wrapped<Tuple2<Statement, Expression>, DoStatement>(
-        unwrapDoStatement,
-        wrapDoStatement,
-        new Tuple2Serializer(statementSerializer, expressionSerializer));
-
-Tuple2<Statement, Expression> unwrapDoStatement(DoStatement node) {
-  return new Tuple2(node.body, node.condition);
-}
-
-DoStatement wrapDoStatement(Tuple2<Statement, Expression> tuple) {
-  return new DoStatement(tuple.first, tuple.second);
-}
-
-TextSerializer<ForStatement> forStatementSerializer = Wrapped<
-        Tuple2<List<VariableDeclaration>,
-            Tuple3<Expression?, List<Expression>, Statement>>,
-        ForStatement>(
-    (w) => Tuple2(w.variables, Tuple3(w.condition, w.updates, w.body)),
-    (u) =>
-        ForStatement(u.first, u.second.first, u.second.second, u.second.third),
-    new Bind(
-        ListSerializer(variableDeclarationSerializer),
-        new Tuple3Serializer(Optional(expressionSerializer),
-            new ListSerializer(expressionSerializer), statementSerializer)));
-
-TextSerializer<ForInStatement> forInStatementSerializer = new Wrapped<
-        Tuple2<Expression, Tuple2<VariableDeclaration, Statement>>,
-        ForInStatement>(
-    unwrapForInStatement,
-    wrapForInStatement,
-    new Tuple2Serializer(expressionSerializer,
-        new Bind(variableDeclarationSerializer, statementSerializer)));
-
-Tuple2<Expression, Tuple2<VariableDeclaration, Statement>> unwrapForInStatement(
-    ForInStatement node) {
-  return new Tuple2(node.iterable, new Tuple2(node.variable, node.body));
-}
-
-ForInStatement wrapForInStatement(
-    Tuple2<Expression, Tuple2<VariableDeclaration, Statement>> tuple) {
-  return new ForInStatement(
-      tuple.second.first, tuple.first, tuple.second.second);
-}
-
-TextSerializer<ForInStatement> awaitForInStatementSerializer = new Wrapped<
-        Tuple2<Expression, Tuple2<VariableDeclaration, Statement>>,
-        ForInStatement>(
-    unwrapForInStatement,
-    wrapAwaitForInStatement,
-    new Tuple2Serializer(expressionSerializer,
-        new Bind(variableDeclarationSerializer, statementSerializer)));
-
-ForInStatement wrapAwaitForInStatement(
-    Tuple2<Expression, Tuple2<VariableDeclaration, Statement>> tuple) {
-  return new ForInStatement(
-      tuple.second.first, tuple.first, tuple.second.second,
-      isAsync: true);
-}
-
-TextSerializer<LabeledStatement> labeledStatementSerializer =
-    Wrapped<Tuple2<LabeledStatement, Statement>, LabeledStatement>(
-        (ls) => Tuple2(ls, ls.body),
-        (t) => t.first..body = t.second,
-        Bind(
-            Wrapped<Tuple2<String?, LabeledStatement>, LabeledStatement>(
-                (ls) => Tuple2("L", ls),
-                (t) => t.second,
-                Binder(Wrapped<void, LabeledStatement>(
-                    (_) => null, (_) => LabeledStatement(null), Nothing()))),
-            statementSerializer));
-
-TextSerializer<BreakStatement> breakSerializer =
-    new Wrapped<LabeledStatement, BreakStatement>(unwrapBreakStatement,
-        wrapBreakStatement, const ScopedUse<LabeledStatement>());
-
-LabeledStatement unwrapBreakStatement(BreakStatement node) {
-  return node.target;
-}
-
-BreakStatement wrapBreakStatement(LabeledStatement node) {
-  return new BreakStatement(node);
-}
-
-TextSerializer<TryFinally> tryFinallySerializer =
-    Wrapped<Tuple2<Statement, Statement>, TryFinally>(
-        (w) => Tuple2(w.body, w.finalizer),
-        (u) => TryFinally(u.first, u.second),
-        Tuple2Serializer(statementSerializer, statementSerializer));
-
-TextSerializer<TryCatch> tryCatchSerializer =
-    Wrapped<Tuple2<Statement, List<Catch>>, TryCatch>(
-        (w) => Tuple2(w.body, w.catches),
-        (u) => TryCatch(u.first, u.second),
-        Tuple2Serializer(statementSerializer, ListSerializer(catchSerializer)));
-
-TextSerializer<Catch> catchSerializer =
-    Wrapped<
-            Tuple2<
-                DartType,
-                Tuple2<Tuple2<VariableDeclaration?, VariableDeclaration?>,
-                    Statement>>,
-            Catch>(
-        (w) =>
-            Tuple2(w.guard, Tuple2(Tuple2(w.exception, w.stackTrace), w.body)),
-        (u) => Catch(u.second.first.first, u.second.second,
-            stackTrace: u.second.first.second, guard: u.first),
-        Tuple2Serializer(
-            dartTypeSerializer,
-            Bind(
-                Tuple2Serializer(Optional(variableDeclarationSerializer),
-                    Optional(variableDeclarationSerializer)),
-                statementSerializer)));
-
-TextSerializer<SwitchStatement> switchStatementSerializer =
-    Wrapped<Tuple2<Expression, List<SwitchCase>>, SwitchStatement>(
-        (w) => Tuple2(w.expression, w.cases),
-        (u) => SwitchStatement(u.first, u.second),
-        Tuple2Serializer(
-            expressionSerializer,
-            Zip(
-                Bind(ListSerializer<SwitchCase>(switchCaseSerializer),
-                    ListSerializer(statementSerializer)),
-                (SwitchCase c, Statement b) => c..body = b,
-                (SwitchCase z) => Tuple2(z, z.body))));
-
-class SwitchCaseTagger implements Tagger<SwitchCase> {
-  @override
-  String tag(SwitchCase node) {
-    return node.isDefault ? "default" : "case";
-  }
-}
-
-TextSerializer<SwitchCase> switchCaseCaseSerializer =
-    Wrapped<Tuple2<String?, SwitchCase>, SwitchCase>(
-        (w) => Tuple2("L", w),
-        (u) => u.second,
-        Binder(Wrapped<List<Expression>, SwitchCase>(
-            (w) => w.expressions,
-            (u) => SwitchCase(u, List.filled(u.length, 0), null),
-            ListSerializer(expressionSerializer))));
-
-TextSerializer<SwitchCase> switchCaseDefaultSerializer =
-    Wrapped<Tuple2<String?, SwitchCase>, SwitchCase>(
-        (w) => Tuple2("L", w),
-        (u) => u.second,
-        Binder(Wrapped<void, SwitchCase>(
-            (w) => null, (u) => SwitchCase.defaultCase(null), Nothing())));
-
-TextSerializer<SwitchCase> switchCaseSerializer = Case(SwitchCaseTagger(), {
-  "case": switchCaseCaseSerializer,
-  "default": switchCaseDefaultSerializer,
-});
-
-TextSerializer<ContinueSwitchStatement> continueSwitchStatementSerializer =
-    Wrapped<SwitchCase, ContinueSwitchStatement>(
-        (w) => w.target, (u) => ContinueSwitchStatement(u), ScopedUse());
-
-TextSerializer<FunctionDeclaration> functionDeclarationSerializer =
-    Wrapped<Tuple2<VariableDeclaration, FunctionNode>, FunctionDeclaration>(
-        (w) => Tuple2(w.variable, w.function),
-        (u) => FunctionDeclaration(u.first, u.second),
-        Rebind(variableDeclarationSerializer, functionNodeSerializer));
-
-Case<Statement> statementSerializer =
-    new Case.uninitialized(const StatementTagger());
-
-const Map<AsyncMarker, String> asyncMarkerToName = {
-  AsyncMarker.Async: "async",
-  AsyncMarker.Sync: "sync",
-  AsyncMarker.AsyncStar: "async-star",
-  AsyncMarker.SyncStar: "sync-star",
-  AsyncMarker.SyncYielding: "sync-yielding",
-};
-
-class AsyncMarkerTagger implements Tagger<AsyncMarker> {
-  const AsyncMarkerTagger();
-
-  @override
-  String tag(AsyncMarker node) {
-    return asyncMarkerToName[node] ?? (throw new UnsupportedError("${node}"));
-  }
-}
-
-TextSerializer<AsyncMarker> asyncMarkerSerializer =
-    Case(AsyncMarkerTagger(), convertFlagsMap(asyncMarkerToName));
-
-// '/**/' comments added to guide formatting.
-
-TextSerializer<Tuple2<FunctionNode, List<Initializer>?>> /**/
-    functionNodeWithInitializersSerializer = Wrapped<
-            Tuple2<
-                AsyncMarker,
-                Tuple2<
-                    /**/
-                    Tuple2<
-                        /**/
-                        List<TypeParameter>,
-                        Tuple3<
-                            List<VariableDeclaration>,
-                            List<VariableDeclaration>,
-                            List<VariableDeclaration>>>,
-                    Tuple3<DartType, List<Initializer>?, Statement?>>>,
-            Tuple2<FunctionNode, List<Initializer>?>>(
-        (w) => Tuple2(
-            w.first.asyncMarker,
-            Tuple2(
-                Tuple2(
-                    w.first.typeParameters,
-                    Tuple3(
-                        w.first.positionalParameters
-                            .sublist(0, w.first.requiredParameterCount),
-                        w.first.positionalParameters
-                            .sublist(w.first.requiredParameterCount),
-                        w.first.namedParameters)),
-                Tuple3(w.first.returnType, w.second, w.first.body))),
-        (u) => Tuple2(
-            FunctionNode(u.second.second.third,
-                typeParameters: u.second.first.first,
-                positionalParameters:
-                    u.second.first.second.first + u.second.first.second.second,
-                namedParameters: u.second.first.second.third,
-                requiredParameterCount: u.second.first.second.first.length,
-                returnType: u.second.second.first,
-                asyncMarker: u.first),
-            u.second.second.second),
-        Tuple2Serializer(
-            asyncMarkerSerializer,
-            Bind(
-                Rebind(
-                    typeParametersSerializer,
-                    Tuple3Serializer(
-                        ListSerializer(variableDeclarationSerializer),
-                        ListSerializer(variableDeclarationSerializer),
-                        ListSerializer(variableDeclarationSerializer))),
-                Tuple3Serializer(
-                    dartTypeSerializer,
-                    Optional(ListSerializer(initializerSerializer)),
-                    Optional(statementSerializer)))));
-
-TextSerializer<FunctionNode> functionNodeSerializer =
-    Wrapped<Tuple2<FunctionNode, List<Initializer>?>, FunctionNode>(
-        (w) => Tuple2(w, null),
-        (u) => u.first,
-        functionNodeWithInitializersSerializer);
-
-const Map<int, String> procedureFlagToName = const {
-  Procedure.FlagStatic: "static",
-  Procedure.FlagAbstract: "abstract",
-  Procedure.FlagExternal: "external",
-  Procedure.FlagConst: "const",
-  Procedure.FlagRedirectingFactory: "redirecting-factory-constructor",
-  Procedure.FlagExtensionMember: "extension-member",
-  Procedure.FlagNonNullableByDefault: "non-nullable-by-default",
-  Procedure.FlagSynthetic: "synthetic",
-};
-
-class ProcedureFlagTagger implements Tagger<int> {
-  const ProcedureFlagTagger();
-
-  @override
-  String tag(int flag) {
-    return procedureFlagToName[flag] ??
-        (throw StateError("Unknown Procedure flag value: ${flag}."));
-  }
-}
-
-TextSerializer<int> procedureFlagsSerializer = Wrapped<List<int>, int>(
-    (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
-    (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(
-        Case(ProcedureFlagTagger(), convertFlagsMap(procedureFlagToName))));
-
-const Map<int, String> fieldFlagToName = const {
-  Field.FlagFinal: "final",
-  Field.FlagConst: "const",
-  Field.FlagStatic: "static",
-  Field.FlagCovariant: "covariant",
-  Field.FlagCovariantByClass: "generic-covariant-impl",
-  Field.FlagLate: "late",
-  Field.FlagExtensionMember: "extension-member",
-  Field.FlagNonNullableByDefault: "non-nullable-by-default",
-  Field.FlagInternalImplementation: "internal-implementation",
-};
-
-class FieldFlagTagger implements Tagger<int> {
-  const FieldFlagTagger();
-
-  @override
-  String tag(int flag) {
-    return fieldFlagToName[flag] ??
-        (throw StateError("Unknown Field flag value: ${flag}."));
-  }
-}
-
-TextSerializer<int> fieldFlagsSerializer = Wrapped<List<int>, int>(
-    (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
-    (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(FieldFlagTagger(), convertFlagsMap(fieldFlagToName))));
-
-const Map<int, String> constructorFlagToName = const {
-  Constructor.FlagConst: "const",
-  Constructor.FlagExternal: "external",
-  Constructor.FlagSynthetic: "synthetic",
-  Constructor.FlagNonNullableByDefault: "non-nullable-by-default",
-};
-
-class ConstructorFlagTagger implements Tagger<int> {
-  const ConstructorFlagTagger();
-
-  @override
-  String tag(int flag) {
-    return constructorFlagToName[flag] ??
-        (throw StateError("Unknown Constructor flag value: ${flag}."));
-  }
-}
-
-TextSerializer<int> constructorFlagsSerializer = Wrapped<List<int>, int>(
-    (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
-    (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(
-        Case(ConstructorFlagTagger(), convertFlagsMap(constructorFlagToName))));
-
-const Map<int, String> redirectingFactoryFlagToName = const {
-  RedirectingFactory.FlagConst: "const",
-  RedirectingFactory.FlagExternal: "external",
-  RedirectingFactory.FlagNonNullableByDefault: "non-nullable-by-default",
-};
-
-class RedirectingFactoryFlagTagger implements Tagger<int> {
-  const RedirectingFactoryFlagTagger();
-
-  @override
-  String tag(int flag) {
-    return redirectingFactoryFlagToName[flag] ??
-        (throw StateError("Unknown RedirectingFactory flag value: ${flag}."));
-  }
-}
-
-TextSerializer<int> redirectingFactoryConstructorFlagsSerializer =
-    Wrapped<List<int>, int>(
-        (w) => List.generate(30, (i) => w & (1 << i))
-            .where((f) => f != 0)
-            .toList(),
-        (u) => u.fold(0, (fs, f) => fs |= f),
-        ListSerializer(Case(RedirectingFactoryFlagTagger(),
-            convertFlagsMap(redirectingFactoryFlagToName))));
-
-class MemberTagger implements Tagger<Member> {
-  const MemberTagger();
-
-  @override
-  String tag(Member node) {
-    if (node is Field) {
-      return node.hasSetter ? "mutable-field" : "immutable-field";
-    } else if (node is Constructor) {
-      return "constructor";
-    } else if (node is RedirectingFactory) {
-      return "redirecting-factory-constructor";
-    } else if (node is Procedure) {
-      switch (node.kind) {
-        case ProcedureKind.Method:
-          return "method";
-        case ProcedureKind.Getter:
-          return "getter";
-        case ProcedureKind.Setter:
-          return "setter";
-        case ProcedureKind.Operator:
-          return "operator";
-        case ProcedureKind.Factory:
-          return "factory";
-        default:
-          throw new UnsupportedError("MemberTagger.tag(${node.kind})");
-      }
-    } else {
-      throw UnimplementedError("MemberTagger.tag(${node.runtimeType})");
-    }
-  }
-}
-
-TextSerializer<Field> mutableFieldSerializer =
-    Wrapped<Tuple5<Name, int, DartType, Expression?, Uri>, Field>(
-        (w) => Tuple5(w.name, w.flags, w.type, w.initializer, w.fileUri),
-        (u) => Field.mutable(u.first,
-            type: u.third, initializer: u.fourth, fileUri: u.fifth)
-          ..flags = u.second,
-        Tuple5Serializer(nameSerializer, fieldFlagsSerializer,
-            dartTypeSerializer, nullableExpressionSerializer, UriSerializer()));
-
-TextSerializer<Field> immutableFieldSerializer =
-    Wrapped<Tuple5<Name, int, DartType, Expression?, Uri>, Field>(
-        (w) => Tuple5(w.name, w.flags, w.type, w.initializer, w.fileUri),
-        (u) => Field.immutable(u.first,
-            type: u.third, initializer: u.fourth, fileUri: u.fifth)
-          ..flags = u.second,
-        Tuple5Serializer(nameSerializer, fieldFlagsSerializer,
-            dartTypeSerializer, nullableExpressionSerializer, UriSerializer()));
-
-TextSerializer<Procedure> methodSerializer =
-    Wrapped<Tuple4<Name, int, FunctionNode, Uri>, Procedure>(
-        (w) => Tuple4(w.name, w.flags, w.function, w.fileUri),
-        (u) =>
-            Procedure(u.first, ProcedureKind.Method, u.third, fileUri: u.fourth)
-              ..flags = u.second,
-        Tuple4Serializer(nameSerializer, procedureFlagsSerializer,
-            functionNodeSerializer, UriSerializer()));
-
-TextSerializer<Procedure> getterSerializer =
-    Wrapped<Tuple4<Name, int, FunctionNode, Uri>, Procedure>(
-        (w) => Tuple4(w.name, w.flags, w.function, w.fileUri),
-        (u) =>
-            Procedure(u.first, ProcedureKind.Getter, u.third, fileUri: u.fourth)
-              ..flags = u.second,
-        Tuple4Serializer(nameSerializer, procedureFlagsSerializer,
-            functionNodeSerializer, UriSerializer()));
-
-TextSerializer<Procedure> setterSerializer =
-    Wrapped<Tuple4<Name, int, FunctionNode, Uri>, Procedure>(
-        (w) => Tuple4(w.name, w.flags, w.function, w.fileUri),
-        (u) =>
-            Procedure(u.first, ProcedureKind.Setter, u.third, fileUri: u.fourth)
-              ..flags = u.second,
-        Tuple4Serializer(nameSerializer, procedureFlagsSerializer,
-            functionNodeSerializer, UriSerializer()));
-
-TextSerializer<Procedure> operatorSerializer =
-    Wrapped<Tuple4<Name, int, FunctionNode, Uri>, Procedure>(
-        (w) => Tuple4(w.name, w.flags, w.function, w.fileUri),
-        (u) => Procedure(u.first, ProcedureKind.Operator, u.third,
-            fileUri: u.fourth)
-          ..flags = u.second,
-        Tuple4Serializer(nameSerializer, procedureFlagsSerializer,
-            functionNodeSerializer, UriSerializer()));
-
-TextSerializer<Procedure> factorySerializer =
-    Wrapped<Tuple4<Name, int, FunctionNode, Uri>, Procedure>(
-        (w) => Tuple4(w.name, w.flags, w.function, w.fileUri),
-        (u) => Procedure(u.first, ProcedureKind.Factory, u.third,
-            fileUri: u.fourth)
-          ..flags = u.second,
-        Tuple4Serializer(nameSerializer, procedureFlagsSerializer,
-            functionNodeSerializer, UriSerializer()));
-
-TextSerializer<Constructor> constructorSerializer = Wrapped<
-        Tuple4<Name, int, Tuple2<FunctionNode, List<Initializer>?>, Uri>,
-        Constructor>(
-    (w) =>
-        Tuple4(w.name, w.flags, Tuple2(w.function, w.initializers), w.fileUri),
-    (u) => Constructor(u.third.first,
-        name: u.first, initializers: u.third.second, fileUri: u.fourth)
-      ..flags = u.second,
-    Tuple4Serializer(nameSerializer, constructorFlagsSerializer,
-        functionNodeWithInitializersSerializer, UriSerializer()));
-
-TextSerializer<RedirectingFactory> redirectingFactoryConstructorSerializer
-    // Comment added to direct formatter.
-    = Wrapped<
-            Tuple6<Name, int, FunctionNode, CanonicalName, List<DartType>, Uri>,
-            RedirectingFactory>(
-        (w) => Tuple6(w.name, w.flags, w.function,
-            w.targetReference!.canonicalName!, w.typeArguments, w.fileUri),
-        (u) => RedirectingFactory(u.fourth.reference,
-            name: u.first,
-            function: u.third,
-            typeArguments: u.fifth,
-            fileUri: u.sixth)
-          ..flags = u.second,
-        Tuple6Serializer(
-            nameSerializer,
-            redirectingFactoryConstructorFlagsSerializer,
-            functionNodeSerializer,
-            CanonicalNameSerializer(),
-            ListSerializer(dartTypeSerializer),
-            UriSerializer()));
-
-Case<Member> memberSerializer = new Case.uninitialized(const MemberTagger());
-
-TextSerializer<LibraryPart> libraryPartSerializer =
-    Wrapped<Tuple2<String, List<Expression>>, LibraryPart>(
-        (w) => Tuple2(w.partUri, w.annotations),
-        (u) => LibraryPart(u.second, u.first),
-        Tuple2Serializer(DartString(), ListSerializer(expressionSerializer)));
-
-class LibraryTagger implements Tagger<Library> {
-  const LibraryTagger();
-
-  @override
-  String tag(Library node) {
-    return node.isNonNullableByDefault ? "null-safe" : "legacy";
-  }
-}
-
-const Map<int, String> libraryFlagToName = const {
-  Library.SyntheticFlag: "synthetic",
-  Library.NonNullableByDefaultFlag: "nnbd",
-  Library.NonNullableByDefaultModeBit1: "nnbd-bit1",
-  Library.NonNullableByDefaultModeBit2: "nnbd-bit2",
-};
-
-class LibraryFlagTagger implements Tagger<int> {
-  const LibraryFlagTagger();
-
-  @override
-  String tag(int flag) {
-    return libraryFlagToName[flag] ??
-        (throw StateError("Unknown Library flag value: ${flag}."));
-  }
-}
-
-TextSerializer<int> libraryFlagsSerializer = Wrapped<List<int>, int>(
-    (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
-    (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(
-        Case(LibraryFlagTagger(), convertFlagsMap(libraryFlagToName))));
-
-TextSerializer<Library> librarySerializer = new Wrapped<
-    Tuple8<Uri, int, List<LibraryPart>, List<Member>, List<Class>,
-        List<Typedef>, List<Extension>, Uri>,
-    Library>(
-  (w) => Tuple8(w.importUri, w.flags, w.parts, [...w.fields, ...w.procedures],
-      w.classes, w.typedefs, w.extensions, w.fileUri),
-  (u) => Library(u.first,
-      parts: u.third,
-      fields: u.fourth.where((m) => m is Field).cast<Field>().toList(),
-      procedures:
-          u.fourth.where((m) => m is Procedure).cast<Procedure>().toList(),
-      classes: u.fifth,
-      typedefs: u.sixth,
-      extensions: u.seventh,
-      fileUri: u.eighth)
-    ..flags = u.second,
-  Tuple8Serializer(
-      UriSerializer(),
-      libraryFlagsSerializer,
-      ListSerializer(libraryPartSerializer),
-      ListSerializer(memberSerializer),
-      ListSerializer(classSerializer),
-      ListSerializer(typedefSerializer),
-      ListSerializer(extensionSerializer),
-      UriSerializer()),
-);
-
-TextSerializer<Component> componentSerializer =
-    Wrapped<List<Library>, Component>(
-        (w) => w.libraries,
-        (u) => Component(nameRoot: CanonicalName.root(), libraries: u),
-        ListSerializer(librarySerializer));
-
-class ShowHideTagger implements Tagger<Combinator> {
-  @override
-  String tag(Combinator node) => node.isShow ? "show" : "hide";
-}
-
-TextSerializer<Combinator> showSerializer = Wrapped<List<String>, Combinator>(
-    (c) => c.names, (ns) => Combinator(true, ns), ListSerializer(DartString()));
-
-TextSerializer<Combinator> hideSerializer = Wrapped<List<String>, Combinator>(
-    (c) => c.names,
-    (ns) => Combinator(false, ns),
-    ListSerializer(DartString()));
-
-Case<Combinator> showHideSerializer = new Case(ShowHideTagger(), {
-  "show": showSerializer,
-  "hide": hideSerializer,
-});
-
-TextSerializer<LibraryDependency> libraryDependencySerializer = Wrapped<
-        Tuple5<CanonicalName, String?, List<Combinator>, int, List<Expression>>,
-        LibraryDependency>(
-    (ld) => Tuple5(ld.importedLibraryReference.canonicalName!, ld.name,
-        ld.combinators, ld.flags, ld.annotations),
-    (t) => LibraryDependency.byReference(
-        t.fourth, t.fifth, t.first.reference, t.second, t.third),
-    Tuple5Serializer(
-        CanonicalNameSerializer(),
-        Optional(DartString()),
-        ListSerializer(showHideSerializer),
-        DartInt(),
-        ListSerializer(expressionSerializer)));
-
-class ConstantTagger extends ConstantVisitor<String>
-    implements Tagger<Constant> {
-  const ConstantTagger();
-
-  @override
-  String tag(Constant node) => node.accept(this);
-
-  @override
-  String visitBoolConstant(BoolConstant node) => "const-bool";
-  @override
-  String visitDoubleConstant(DoubleConstant node) => "const-double";
-  @override
-  String visitInstanceConstant(InstanceConstant node) => "const-object";
-  @override
-  String visitIntConstant(IntConstant node) => "const-int";
-  @override
-  String visitListConstant(ListConstant node) => "const-list";
-  @override
-  String visitMapConstant(MapConstant node) => "const-map";
-  @override
-  String visitNullConstant(NullConstant node) => "const-null";
-  @override
-  String visitInstantiationConstant(InstantiationConstant node) =>
-      "const-apply";
-  @override
-  String visitSetConstant(SetConstant node) => "const-set";
-  @override
-  String visitStringConstant(StringConstant node) => "const-string";
-  @override
-  String visitSymbolConstant(SymbolConstant node) => "const-symbol";
-  @override
-  String visitStaticTearOffConstant(StaticTearOffConstant node) =>
-      "const-tearoff-static";
-  @override
-  String visitConstructorTearOffConstant(ConstructorTearOffConstant node) =>
-      "const-tearoff-constructor";
-  @override
-  String visitRedirectingFactoryTearOffConstant(
-          RedirectingFactoryTearOffConstant node) =>
-      "const-tearoff-redirecting-factory";
-  @override
-  String visitTypedefTearOffConstant(TypedefTearOffConstant node) =>
-      "const-tearoff-typedef";
-  @override
-  String visitTypeLiteralConstant(TypeLiteralConstant node) => "const-type";
-  @override
-  String visitUnevaluatedConstant(UnevaluatedConstant node) => "const-expr";
-
-  @override
-  String defaultConstant(Constant node) {
-    throw new UnimplementedError(
-        'Unimplemented constant $node (${node.runtimeType})');
-  }
-}
-
-TextSerializer<BoolConstant> boolConstantSerializer =
-    Wrapped<bool, BoolConstant>(
-        (w) => w.value, (u) => BoolConstant(u), DartBool());
-
-TextSerializer<DoubleConstant> doubleConstantSerializer =
-    Wrapped<double, DoubleConstant>(
-        (w) => w.value, (u) => DoubleConstant(u), DartDouble());
-
-TextSerializer<IntConstant> intConstantSerializer =
-    Wrapped<int, IntConstant>((w) => w.value, (u) => IntConstant(u), DartInt());
-
-TextSerializer<ListConstant> listConstantSerializer =
-    Wrapped<Tuple2<DartType, List<Constant>>, ListConstant>(
-        (w) => Tuple2(w.typeArgument, w.entries),
-        (u) => ListConstant(u.first, u.second),
-        Tuple2Serializer(
-            dartTypeSerializer, ListSerializer(constantSerializer)));
-
-TextSerializer<MapConstant> mapConstantSerializer =
-    Wrapped<Tuple3<DartType, DartType, List<ConstantMapEntry>>, MapConstant>(
-        (w) => Tuple3(w.keyType, w.valueType, w.entries),
-        (u) => MapConstant(u.first, u.second, u.third),
-        Tuple3Serializer(
-            dartTypeSerializer,
-            dartTypeSerializer,
-            Zip(
-                Tuple2Serializer(ListSerializer(constantSerializer),
-                    ListSerializer(constantSerializer)),
-                (Constant k, Constant v) => ConstantMapEntry(k, v),
-                (z) => Tuple2(z.key, z.value))));
-
-TextSerializer<NullConstant> nullConstantSerializer =
-    Wrapped<void, NullConstant>((w) => null, (u) => NullConstant(), Nothing());
-
-TextSerializer<InstantiationConstant> instantiationConstantSerializer =
-    Wrapped<Tuple2<Constant, List<DartType>>, InstantiationConstant>(
-        (w) => Tuple2(w.tearOffConstant, w.types),
-        (u) => InstantiationConstant(u.first, u.second),
-        Tuple2Serializer(
-            constantSerializer, ListSerializer(dartTypeSerializer)));
-
-TextSerializer<SetConstant> setConstantSerializer =
-    Wrapped<Tuple2<DartType, List<Constant>>, SetConstant>(
-        (w) => Tuple2(w.typeArgument, w.entries),
-        (u) => SetConstant(u.first, u.second),
-        Tuple2Serializer(
-            dartTypeSerializer, ListSerializer(constantSerializer)));
-
-TextSerializer<StringConstant> stringConstantSerializer =
-    Wrapped<String, StringConstant>(
-        (w) => w.value, (u) => StringConstant(u), DartString());
-
-TextSerializer<SymbolConstant> symbolConstantSerializer =
-    Wrapped<Tuple2<String, CanonicalName?>, SymbolConstant>(
-        (w) => Tuple2(w.name, w.libraryReference?.canonicalName),
-        (u) => SymbolConstant(u.first, u.second?.reference),
-        Tuple2Serializer(DartString(), Optional(CanonicalNameSerializer())));
-
-TextSerializer<StaticTearOffConstant> staticTearOffConstantSerializer =
-    Wrapped<CanonicalName, StaticTearOffConstant>(
-        (w) => w.targetReference.canonicalName!,
-        (u) => StaticTearOffConstant.byReference(u.reference),
-        CanonicalNameSerializer());
-
-TextSerializer<ConstructorTearOffConstant>
-    constructorTearOffConstantSerializer =
-    Wrapped<CanonicalName, ConstructorTearOffConstant>(
-        (w) => w.targetReference.canonicalName!,
-        (u) => ConstructorTearOffConstant.byReference(u.reference),
-        CanonicalNameSerializer());
-
-TextSerializer<RedirectingFactoryTearOffConstant>
-    redirectingFactoryTearOffConstantSerializer =
-    Wrapped<CanonicalName, RedirectingFactoryTearOffConstant>(
-        (w) => w.targetReference.canonicalName!,
-        (u) => RedirectingFactoryTearOffConstant.byReference(u.reference),
-        CanonicalNameSerializer());
-
-final TextSerializer<TypedefTearOffConstant> typedefTearOffConstantSerializer =
-    new Wrapped<Tuple2<List<TypeParameter>, Tuple2<Constant, List<DartType>>>,
-            TypedefTearOffConstant>(
-        unwrapTypedefTearOffConstant,
-        wrapTypedefTearOffConstant,
-        Bind(
-            typeParametersSerializer,
-            Tuple2Serializer(
-                constantSerializer, ListSerializer(dartTypeSerializer))));
-
-Tuple2<List<TypeParameter>, Tuple2<Constant, List<DartType>>>
-    unwrapTypedefTearOffConstant(TypedefTearOffConstant node) {
-  return new Tuple2(
-      node.parameters, new Tuple2(node.tearOffConstant, node.types));
-}
-
-TypedefTearOffConstant wrapTypedefTearOffConstant(
-    Tuple2<List<TypeParameter>, Tuple2<Constant, List<DartType>>> tuple) {
-  return new TypedefTearOffConstant(
-      tuple.first, tuple.second.first as TearOffConstant, tuple.second.second);
-}
-
-TextSerializer<TypeLiteralConstant> typeLiteralConstantSerializer =
-    Wrapped<DartType, TypeLiteralConstant>(
-        (w) => w.type, (u) => TypeLiteralConstant(u), dartTypeSerializer);
-
-TextSerializer<UnevaluatedConstant> unevaluatedConstantSerializer =
-    Wrapped<Expression, UnevaluatedConstant>((w) => w.expression,
-        (u) => UnevaluatedConstant(u), expressionSerializer);
-
-TextSerializer<InstanceConstant> instanceConstantSerializer =
-    Wrapped<
-            Tuple4<CanonicalName, List<DartType>, List<CanonicalName>,
-                List<Constant>>,
-            InstanceConstant>(
-        (w) => Tuple4(
-            w.classReference.canonicalName!,
-            w.typeArguments,
-            w.fieldValues.keys.map((r) => r.canonicalName!).toList(),
-            w.fieldValues.values.toList()),
-        (u) => InstanceConstant(u.first.reference, u.second,
-            Map.fromIterables(u.third.map((c) => c.reference), u.fourth)),
-        Tuple4Serializer(
-            CanonicalNameSerializer(),
-            ListSerializer(dartTypeSerializer),
-            ListSerializer(CanonicalNameSerializer()),
-            ListSerializer(constantSerializer)));
-
-Case<Constant> constantSerializer = Case.uninitialized(ConstantTagger());
-
-class InitializerTagger implements Tagger<Initializer> {
-  const InitializerTagger();
-
-  @override
-  String tag(Initializer node) {
-    if (node is AssertInitializer) {
-      return "assert";
-    } else if (node is FieldInitializer) {
-      return "field";
-    } else if (node is InvalidInitializer) {
-      return "invalid";
-    } else if (node is LocalInitializer) {
-      return "local";
-    } else if (node is RedirectingInitializer) {
-      return "redirecting";
-    } else if (node is SuperInitializer) {
-      return "super";
-    } else {
-      throw UnimplementedError("InitializerTagger.tag(${node.runtimeType}).");
-    }
-  }
-}
-
-TextSerializer<AssertInitializer> assertInitializerSerializer =
-    Wrapped<Statement, AssertInitializer>((w) => w.statement,
-        (u) => AssertInitializer(u as AssertStatement), statementSerializer);
-
-TextSerializer<FieldInitializer> fieldInitializerSerializer =
-    Wrapped<Tuple2<CanonicalName, Expression>, FieldInitializer>(
-        (w) => Tuple2(w.fieldReference.canonicalName!, w.value),
-        (u) => FieldInitializer.byReference(u.first.reference, u.second),
-        Tuple2Serializer(CanonicalNameSerializer(), expressionSerializer));
-
-TextSerializer<InvalidInitializer> invalidInitializerSerializer =
-    Wrapped<void, InvalidInitializer>(
-        (_) => null, (_) => InvalidInitializer(), Nothing());
-
-TextSerializer<LocalInitializer> localInitializerSerializer =
-    Wrapped<VariableDeclaration, LocalInitializer>((w) => w.variable,
-        (u) => LocalInitializer(u), variableDeclarationSerializer);
-
-TextSerializer<RedirectingInitializer> redirectingInitializerSerializer =
-    Wrapped<Tuple2<CanonicalName, Arguments>, RedirectingInitializer>(
-        (w) => Tuple2(w.targetReference.canonicalName!, w.arguments),
-        (u) => RedirectingInitializer.byReference(u.first.reference, u.second),
-        Tuple2Serializer(CanonicalNameSerializer(), argumentsSerializer));
-
-TextSerializer<SuperInitializer> superInitializerSerializer =
-    Wrapped<Tuple2<CanonicalName, Arguments>, SuperInitializer>(
-        (w) => Tuple2(w.targetReference.canonicalName!, w.arguments),
-        (u) => SuperInitializer.byReference(u.first.reference, u.second),
-        Tuple2Serializer(CanonicalNameSerializer(), argumentsSerializer));
-
-Case<Initializer> initializerSerializer =
-    Case.uninitialized(InitializerTagger());
-
-TextSerializer<Supertype> supertypeSerializer =
-    Wrapped<Tuple2<CanonicalName, List<DartType>>, Supertype>(
-        (w) => Tuple2(w.className.canonicalName!, w.typeArguments),
-        (u) => Supertype.byReference(u.first.reference, u.second),
-        Tuple2Serializer(
-            CanonicalNameSerializer(), ListSerializer(dartTypeSerializer)));
-
-const Map<int, String> classFlagToName = const {
-  Class.FlagAbstract: "abstract",
-  Class.FlagEnum: "enum",
-  Class.FlagAnonymousMixin: "anonymous-mixin",
-  Class.FlagEliminatedMixin: "eliminated-mixin",
-  Class.FlagMixinDeclaration: "mixin-declaration",
-  Class.FlagHasConstConstructor: "has-const-constructor",
-  Class.FlagMacro: "macro",
-};
-
-class ClassFlagTagger implements Tagger<int> {
-  const ClassFlagTagger();
-
-  @override
-  String tag(int flag) {
-    return classFlagToName[flag] ??
-        (throw StateError("Unknown Class flag value: ${flag}."));
-  }
-}
-
-TextSerializer<int> classFlagsSerializer = Wrapped<List<int>, int>(
-    (w) => List.generate(30, (i) => w & (1 << i)).where((f) => f != 0).toList(),
-    (u) => u.fold(0, (fs, f) => fs |= f),
-    ListSerializer(Case(ClassFlagTagger(), convertFlagsMap(classFlagToName))));
-
-TextSerializer<Class> classSerializer = Wrapped<
-        Tuple4<
-            String,
-            int,
-            Uri,
-            Tuple2<
-                List<TypeParameter>,
-                /* Comment added to guide formatting. */
-                Tuple4<Supertype?, Supertype?, List<Supertype>, List<Member>>>>,
-        Class>(
-    (w) => Tuple4(
-        w.name,
-        w.flags,
-        w.fileUri,
-        Tuple2(
-            w.typeParameters,
-            Tuple4(w.supertype, w.mixedInType, w.implementedTypes,
-                <Member>[...w.fields, ...w.constructors, ...w.procedures]))),
-    (u) => Class(
-        name: u.first,
-        typeParameters: u.fourth.first,
-        supertype: u.fourth.second.first,
-        mixedInType: u.fourth.second.second,
-        implementedTypes: u.fourth.second.third,
-        fields: u.fourth.second.fourth
-            .where((m) => m is Field)
-            .cast<Field>()
-            .toList(),
-        constructors: u.fourth.second.fourth
-            .where((m) => m is Constructor)
-            .cast<Constructor>()
-            .toList(),
-        procedures: u.fourth.second.fourth
-            .where((m) => m is Procedure)
-            .cast<Procedure>()
-            .toList(),
-        fileUri: u.third)
-      ..flags = u.second,
-    Tuple4Serializer(
-        DartString(),
-        classFlagsSerializer,
-        UriSerializer(),
-        Bind(
-            typeParametersSerializer,
-            Tuple4Serializer(
-                Optional(supertypeSerializer),
-                Optional(supertypeSerializer),
-                ListSerializer(supertypeSerializer),
-                ListSerializer(memberSerializer)))));
-
-TextSerializer<Typedef> typedefSerializer = Wrapped<
-        Tuple3<String, Tuple2<List<TypeParameter>, DartType>, Uri>, Typedef>(
-    (w) => Tuple3(w.name, Tuple2(w.typeParameters, w.type!), w.fileUri),
-    (u) => Typedef(u.first, u.second.second,
-        typeParameters: u.second.first, fileUri: u.third),
-    Tuple3Serializer(DartString(),
-        Bind(typeParametersSerializer, dartTypeSerializer), UriSerializer()));
-
-const Map<int, String> extensionMemberDescriptorFlagToName = const {
-  ExtensionMemberDescriptor.FlagStatic: "static",
-};
-
-class ExtensionMemberDescriptorFlagTagger implements Tagger<int> {
-  const ExtensionMemberDescriptorFlagTagger();
-
-  @override
-  String tag(int flag) {
-    return extensionMemberDescriptorFlagToName[flag] ??
-        (throw StateError(
-            "Unknown ExtensionMemberDescriptor flag value: ${flag}."));
-  }
-}
-
-TextSerializer<int> extensionMemberDescriptorFlagsSerializer =
-    Wrapped<List<int>, int>(
-        (w) => List.generate(30, (i) => w & (1 << i))
-            .where((f) => f != 0)
-            .toList(),
-        (u) => u.fold(0, (fs, f) => fs |= f),
-        ListSerializer(Case(ExtensionMemberDescriptorFlagTagger(),
-            convertFlagsMap(extensionMemberDescriptorFlagToName))));
-
-const Map<ExtensionMemberKind, String> extensionMemberKindToName = const {
-  ExtensionMemberKind.Field: "field",
-  ExtensionMemberKind.Method: "method",
-  ExtensionMemberKind.Getter: "getter",
-  ExtensionMemberKind.Setter: "setter",
-  ExtensionMemberKind.Operator: "operator",
-  ExtensionMemberKind.TearOff: "tearOff",
-};
-
-class ExtensionMemberKindTagger implements Tagger<ExtensionMemberKind> {
-  const ExtensionMemberKindTagger();
-
-  @override
-  String tag(ExtensionMemberKind kind) {
-    return extensionMemberKindToName[kind] ??
-        (throw StateError("Unknown ExtensionMemberKind flag value: ${kind}."));
-  }
-}
-
-TextSerializer<ExtensionMemberKind> extensionMemberKindSerializer = Case(
-    ExtensionMemberKindTagger(), convertFlagsMap(extensionMemberKindToName));
-
-TextSerializer<ExtensionMemberDescriptor> extensionMemberDescriptorSerializer =
-    Wrapped<Tuple4<Name, ExtensionMemberKind, int, CanonicalName>,
-            ExtensionMemberDescriptor>(
-        (w) => Tuple4(w.name, w.kind, w.flags, w.member.canonicalName!),
-        (u) => ExtensionMemberDescriptor(
-            name: u.first, kind: u.second, member: u.fourth.reference)
-          ..flags = u.third,
-        Tuple4Serializer(
-            nameSerializer,
-            extensionMemberKindSerializer,
-            extensionMemberDescriptorFlagsSerializer,
-            CanonicalNameSerializer()));
-
-TextSerializer<Extension> extensionSerializer = Wrapped<
-        Tuple4<String, Tuple2<List<TypeParameter>, DartType>,
-            List<ExtensionMemberDescriptor>, Uri>,
-        Extension>(
-    (w) => Tuple4(
-        w.name, Tuple2(w.typeParameters, w.onType), w.members, w.fileUri),
-    (u) => Extension(
-        name: u.first,
-        typeParameters: u.second.first,
-        onType: u.second.second,
-        members: u.third,
-        fileUri: u.fourth),
-    Tuple4Serializer(
-        DartString(),
-        Bind(typeParametersSerializer, dartTypeSerializer),
-        ListSerializer(extensionMemberDescriptorSerializer),
-        UriSerializer()));
-
-void initializeSerializers() {
-  expressionSerializer.registerTags({
-    "string": stringLiteralSerializer,
-    "int": intLiteralSerializer,
-    "double": doubleLiteralSerializer,
-    "bool": boolLiteralSerializer,
-    "null": nullLiteralSerializer,
-    "invalid": invalidExpressionSerializer,
-    "not": notSerializer,
-    "&&": logicalAndSerializer,
-    "||": logicalOrSerializer,
-    "concat": stringConcatenationSerializer,
-    "symbol": symbolLiteralSerializer,
-    "this": thisExpressionSerializer,
-    "rethrow": rethrowSerializer,
-    "throw": throwSerializer,
-    "await": awaitExpressionSerializer,
-    "cond": conditionalExpressionSerializer,
-    "is": isExpressionSerializer,
-    "as": asExpressionSerializer,
-    "type": typeLiteralSerializer,
-    "list": listLiteralSerializer,
-    "const-list": constListLiteralSerializer,
-    "set": setLiteralSerializer,
-    "const-set": constSetLiteralSerializer,
-    "map": mapLiteralSerializer,
-    "const-map": constMapLiteralSerializer,
-    "let": letSerializer,
-    "get-instance": instanceGetSerializer,
-    "set-instance": instanceSetSerializer,
-    "get-dynamic": dynamicGetSerializer,
-    "set-dynamic": dynamicSetSerializer,
-    "tearoff-instance": instanceTearOffSerializer,
-    "tearoff-function": functionTearOffSerializer,
-    "get-super": superPropertyGetSerializer,
-    "set-super": superPropertySetSerializer,
-    "invoke-instance": instanceInvocationSerializer,
-    "invoke-instance-getter": instanceGetterInvocationSerializer,
-    "invoke-dynamic": dynamicInvocationSerializer,
-    "invoke-function": functionInvocationSerializer,
-    "invoke-local-function": localFunctionInvocationSerializer,
-    "equals-null": equalsNullSerializer,
-    "equals-call": equalsCallSerializer,
-    "invoke-super": superMethodInvocationSerializer,
-    "get-var": variableGetSerializer,
-    "set-var": variableSetSerializer,
-    "get-static": staticGetSerializer,
-    "set-static": staticSetSerializer,
-    "tearoff-static": staticTearOffSerializer,
-    "tearoff-constructor": constructorTearOffSerializer,
-    "tearoff-redirecting-factory": redirectingFactoryTearOffSerializer,
-    "tearoff-typedef": typedefTearOffSerializer,
-    "invoke-static": staticInvocationSerializer,
-    "invoke-const-static": constStaticInvocationSerializer,
-    "invoke-constructor": constructorInvocationSerializer,
-    "invoke-const-constructor": constConstructorInvocationSerializer,
-    "fun": functionExpressionSerializer,
-    "lists": listConcatenationSerializer,
-    "sets": setConcatenationSerializer,
-    "maps": mapConcatenationSerializer,
-    "let-block": blockExpressionSerializer,
-    "apply": instantiationSerializer,
-    "not-null": nullCheckSerializer,
-    "with-uri": fileUriExpressionSerializer,
-    "is-loaded": checkLibraryIsLoadedSerializer,
-    "load": loadLibrarySerializer,
-    "const": constantExpressionSerializer,
-    "object": instanceCreationSerializer,
-  });
-  dartTypeSerializer.registerTags({
-    "invalid": invalidTypeSerializer,
-    "dynamic": dynamicTypeSerializer,
-    "void": voidTypeSerializer,
-    "->": functionTypeSerializer,
-    "par": typeParameterTypeSerializer,
-    "interface": interfaceTypeSerializer,
-    "never": neverTypeSerializer,
-    "typedef": typedefTypeSerializer,
-    "futureor": futureOrTypeSerializer,
-    "null-type": nullTypeSerializer,
-  });
-  statementSerializer.registerTags({
-    "expr": expressionStatementSerializer,
-    "ret": returnStatementSerializer,
-    "ret-void": returnVoidStatementSerializer,
-    "yield": yieldStatementSerializer,
-    "block": blockSerializer,
-    "local": variableDeclarationSerializer,
-    "if": ifStatementSerializer,
-    "if-else": ifElseStatementSerializer,
-    "skip": emptyStatementSerializer,
-    "while": whileStatementSerializer,
-    "do-while": doStatementSerializer,
-    "for": forStatementSerializer,
-    "for-in": forInStatementSerializer,
-    "await-for-in": awaitForInStatementSerializer,
-    "assert": assertStatementSerializer,
-    "assert-block": assertBlockSerializer,
-    "label": labeledStatementSerializer,
-    "break": breakSerializer,
-    "try-finally": tryFinallySerializer,
-    "try-catch": tryCatchSerializer,
-    "switch": switchStatementSerializer,
-    "continue": continueSwitchStatementSerializer,
-    "local-fun": functionDeclarationSerializer,
-  });
-  memberSerializer.registerTags({
-    "mutable-field": mutableFieldSerializer,
-    "immutable-field": immutableFieldSerializer,
-    "method": methodSerializer,
-    "getter": getterSerializer,
-    "setter": setterSerializer,
-    "operator": operatorSerializer,
-    "factory": factorySerializer,
-    "constructor": constructorSerializer,
-    "redirecting-factory-constructor": redirectingFactoryConstructorSerializer,
-  });
-  constantSerializer.registerTags({
-    "const-bool": boolConstantSerializer,
-    "const-double": doubleConstantSerializer,
-    "const-int": intConstantSerializer,
-    "const-list": listConstantSerializer,
-    "const-map": mapConstantSerializer,
-    "const-null": nullConstantSerializer,
-    "const-apply": instantiationConstantSerializer,
-    "const-set": setConstantSerializer,
-    "const-string": stringConstantSerializer,
-    "const-symbol": symbolConstantSerializer,
-    "const-tearoff-static": staticTearOffConstantSerializer,
-    "const-tearoff-constructor": constructorTearOffConstantSerializer,
-    "const-tearoff-redirecting-factory":
-        redirectingFactoryTearOffConstantSerializer,
-    "const-tearoff-typedef": typedefTearOffConstantSerializer,
-    "const-type": typeLiteralConstantSerializer,
-    "const-expr": unevaluatedConstantSerializer,
-    "const-object": instanceConstantSerializer,
-  });
-  initializerSerializer.registerTags({
-    "assert": assertInitializerSerializer,
-    "field": fieldInitializerSerializer,
-    "invalid": invalidInitializerSerializer,
-    "local": localInitializerSerializer,
-    "redirecting": redirectingInitializerSerializer,
-    "super": superInitializerSerializer,
-  });
-}
-
-Map<String, Wrapped<void, T>> convertFlagsMap<T>(Map<T, String> map) {
-  return map.entries.toMap(
-      key: (e) => e.value,
-      value: (e) => Wrapped<void, T>((_) => null, (_) => e.key, Nothing()));
-}
-
-extension MapFromIterable<E> on Iterable<E> {
-  Map<K, V> toMap<K, V>(
-      {required K Function(E) key, required V Function(E) value}) {
-    return {for (E e in this) key(e): value(e)};
-  }
-}
diff --git a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart b/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
deleted file mode 100644
index 4261086..0000000
--- a/pkg/kernel/test/text_serializer_from_kernel_nodes_test.dart
+++ /dev/null
@@ -1,628 +0,0 @@
-// 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.
-
-library kernel.text_serializer_from_kernel_nodes_test;
-
-import 'package:kernel/ast.dart';
-import 'package:kernel/text/serializer_combinators.dart';
-import 'package:kernel/text/text_reader.dart';
-import 'package:kernel/text/text_serializer.dart';
-
-void main() {
-  initializeSerializers();
-  test();
-}
-
-class TestCase<T extends Node> {
-  final String name;
-  final T node;
-  final SerializationState Function() makeSerializationState;
-  final DeserializationState Function() makeDeserializationState;
-  final String expectation;
-  final TextSerializer<T> serializer;
-
-  TestCase(
-      {required this.name,
-      required this.node,
-      required this.expectation,
-      required this.serializer,
-      SerializationState Function()? makeSerializationState,
-      DeserializationState Function()? makeDeserializationState})
-      // ignore: unnecessary_null_comparison
-      : assert(node != null),
-        // ignore: unnecessary_null_comparison
-        assert(expectation != null),
-        // ignore: unnecessary_null_comparison
-        assert(serializer != null),
-        this.makeSerializationState = makeSerializationState ??
-            (() => new SerializationState(new SerializationEnvironment(null))),
-        this.makeDeserializationState = makeDeserializationState ??
-            (() => new DeserializationState(
-                new DeserializationEnvironment(null),
-                new CanonicalName.root()));
-
-  T readNode(String input, DeserializationState state) {
-    TextIterator stream = new TextIterator(input, 0);
-    stream.moveNext();
-    T result = serializer.readFrom(stream, state);
-    if (stream.moveNext()) {
-      throw new StateError("Found extra tokens at the end.");
-    }
-    return result;
-  }
-
-  String writeNode(T node, SerializationState state) {
-    StringBuffer buffer = new StringBuffer();
-    serializer.writeTo(buffer, node, state);
-    return buffer.toString();
-  }
-}
-
-void test() {
-  List<String> failures = [];
-  List<TestCase> tests = <TestCase>[
-    new TestCase<Statement>(
-        name: 'let dynamic x = 42 in x;',
-        node: () {
-          VariableDeclaration x = new VariableDeclaration('x',
-              type: const DynamicType(), initializer: new IntLiteral(42));
-          return new ExpressionStatement(new Let(x, new VariableGet(x)));
-        }(),
-        expectation: ''
-            '(expr (let "x^0" () (dynamic) (int 42) ()'
-            ' (get-var "x^0" _)))',
-        serializer: statementSerializer),
-    new TestCase<Statement>(
-        name: 'let dynamic x = 42 in let Null x^0 = null in x;',
-        node: () {
-          VariableDeclaration outerLetVar = new VariableDeclaration('x',
-              type: const DynamicType(), initializer: new IntLiteral(42));
-          VariableDeclaration innerLetVar = new VariableDeclaration('x',
-              type: const NullType(), initializer: new NullLiteral());
-          return new ExpressionStatement(new Let(
-              outerLetVar, new Let(innerLetVar, new VariableGet(outerLetVar))));
-        }(),
-        expectation: ''
-            '(expr (let "x^0" () (dynamic) (int 42) ()'
-            ' (let "x^1" () (null-type) (null) ()'
-            ' (get-var "x^0" _))))',
-        serializer: statementSerializer),
-    new TestCase<Statement>(
-        name: 'let dynamic x = 42 in let Null x^0 = null in x^0;',
-        node: () {
-          VariableDeclaration outerLetVar = new VariableDeclaration('x',
-              type: const DynamicType(), initializer: new IntLiteral(42));
-          VariableDeclaration innerLetVar = new VariableDeclaration('x',
-              type: const NullType(), initializer: new NullLiteral());
-          return new ExpressionStatement(new Let(
-              outerLetVar, new Let(innerLetVar, new VariableGet(innerLetVar))));
-        }(),
-        expectation: ''
-            '(expr (let "x^0" () (dynamic) (int 42) ()'
-            ' (let "x^1" () (null-type) (null) ()'
-            ' (get-var "x^1" _))))',
-        serializer: statementSerializer),
-    () {
-      VariableDeclaration x =
-          new VariableDeclaration('x', type: const DynamicType());
-      return new TestCase<Statement>(
-          name: '/* suppose: dynamic x; */ x = 42;',
-          node: new ExpressionStatement(new VariableSet(x, new IntLiteral(42))),
-          expectation: '(expr (set-var "x^0" (int 42)))',
-          makeSerializationState: () => new SerializationState(
-                new SerializationEnvironment(null)
-                  ..addBinder(x, nameClue: x.name)
-                  ..extend(),
-              ),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null)
-                ..addBinder(x, "x^0")
-                ..extend(),
-              new CanonicalName.root()),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Field field = new Field.immutable(new Name('field'),
-          type: const DynamicType(), fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, fields: <Field>[field]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-      return new TestCase<Statement>(
-          name: '/* suppose top-level: dynamic field; */ field;',
-          node: new ExpressionStatement(new StaticGet(field)),
-          expectation: ''
-              '(expr (get-static "package:foo/bar.dart::@getters::field"))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Field field = new Field.mutable(new Name('field'),
-          type: const DynamicType(), fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, fields: <Field>[field]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-      return new TestCase<Statement>(
-          name: '/* suppose top-level: dynamic field; */ field;',
-          node: new ExpressionStatement(new StaticGet(field)),
-          expectation: ''
-              '(expr (get-static "package:foo/bar.dart::@getters::field"))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Field field = new Field.mutable(new Name('field'),
-          type: const DynamicType(), fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, fields: <Field>[field]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-      return new TestCase<Statement>(
-          name: '/* suppose top-level: dynamic field; */ field = 1;',
-          node:
-              new ExpressionStatement(new StaticSet(field, new IntLiteral(1))),
-          expectation: ''
-              '(expr'
-              ' (set-static "package:foo/bar.dart::@setters::field" (int 1)))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Procedure topLevelProcedure = new Procedure(
-          new Name('foo'),
-          ProcedureKind.Method,
-          new FunctionNode(null, positionalParameters: <VariableDeclaration>[
-            new VariableDeclaration('x', type: const DynamicType())
-          ]),
-          isStatic: true,
-          fileUri: uri);
-      Library library = new Library(uri,
-          fileUri: uri, procedures: <Procedure>[topLevelProcedure]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-      return new TestCase<Statement>(
-          name: '/* suppose top-level: foo(dynamic x) {...}; */ foo(42);',
-          node: new ExpressionStatement(new StaticInvocation.byReference(
-              topLevelProcedure.reference,
-              new Arguments(<Expression>[new IntLiteral(42)]),
-              isConst: false)),
-          expectation: ''
-              '(expr (invoke-static "package:foo/bar.dart::@methods::foo"'
-              ' () ((int 42)) ()))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Procedure factoryConstructor = new Procedure(
-          new Name('foo'), ProcedureKind.Factory, new FunctionNode(null),
-          isStatic: true, isConst: true, fileUri: uri);
-      Class klass = new Class(
-          name: 'A', procedures: <Procedure>[factoryConstructor], fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, classes: <Class>[klass]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-      return new TestCase<Statement>(
-          name: ''
-              '/* suppose A { const A(); const factory A.foo() = A; } */'
-              ' const A.foo();',
-          node: new ExpressionStatement(new StaticInvocation.byReference(
-              factoryConstructor.reference, new Arguments([]), isConst: true)),
-          expectation: ''
-              '(expr (invoke-const-static'
-              ' "package:foo/bar.dart::A::@factories::foo"'
-              ' () () ()))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Field field = new Field.immutable(new Name('field'),
-          type: const DynamicType(), fileUri: uri);
-      Class klass = new Class(name: 'A', fields: <Field>[field], fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, classes: <Class>[klass]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-
-      VariableDeclaration x =
-          new VariableDeclaration('x', type: const DynamicType());
-      return new TestCase<Statement>(
-          name: '/* suppose A {dynamic field;} A x; */ x.{A::field};',
-          node: new ExpressionStatement(new InstanceGet.byReference(
-              InstanceAccessKind.Instance, new VariableGet(x), field.name,
-              interfaceTargetReference: field.getterReference,
-              resultType: field.getterType)),
-          expectation: ''
-              '(expr (get-instance (instance) (get-var "x^0" _) '
-              '(public "field") "package:foo/bar.dart::A::@getters::field" '
-              '(dynamic)))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)
-                ..addBinder(x, nameClue: 'x')
-                ..extend()),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null)
-                ..addBinder(x, "x^0")
-                ..extend(),
-              component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Field field = new Field.mutable(new Name('field'),
-          type: const DynamicType(), fileUri: uri);
-      Class klass = new Class(name: 'A', fields: <Field>[field], fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, classes: <Class>[klass]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-
-      VariableDeclaration x =
-          new VariableDeclaration('x', type: const DynamicType());
-      return new TestCase<Statement>(
-          name: '/* suppose A {dynamic field;} A x; */ x.{A::field};',
-          node: new ExpressionStatement(new InstanceGet.byReference(
-              InstanceAccessKind.Instance, new VariableGet(x), field.name,
-              interfaceTargetReference: field.getterReference,
-              resultType: field.getterType)),
-          expectation: ''
-              '(expr (get-instance (instance) (get-var "x^0" _) '
-              '(public "field") "package:foo/bar.dart::A::@getters::field" '
-              '(dynamic)))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)
-                ..addBinder(x, nameClue: 'x')
-                ..extend()),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null)
-                ..addBinder(x, "x^0")
-                ..extend(),
-              component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Field field = new Field.mutable(new Name('field'),
-          type: const DynamicType(), fileUri: uri);
-      Class klass = new Class(name: 'A', fields: <Field>[field], fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, classes: <Class>[klass]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-
-      VariableDeclaration x =
-          new VariableDeclaration('x', type: const DynamicType());
-      return new TestCase<Statement>(
-          name: '/* suppose A {dynamic field;} A x; */ x.{A::field} = 42;',
-          node: new ExpressionStatement(InstanceSet.byReference(
-              InstanceAccessKind.Instance,
-              new VariableGet(x),
-              field.name,
-              new IntLiteral(42),
-              interfaceTargetReference: field.setterReference!)),
-          expectation: ''
-              '(expr (set-instance (instance) (get-var "x^0" _) '
-              '(public "field") (int 42) '
-              '"package:foo/bar.dart::A::@setters::field"))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)
-                ..addBinder(x, nameClue: 'x')
-                ..extend()),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null)
-                ..addBinder(x, "x^0")
-                ..extend(),
-              component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Procedure method = new Procedure(
-          new Name('foo'), ProcedureKind.Method, new FunctionNode(null),
-          isStatic: true, isConst: true, fileUri: uri);
-      Class klass =
-          new Class(name: 'A', procedures: <Procedure>[method], fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, classes: <Class>[klass]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-
-      VariableDeclaration x =
-          new VariableDeclaration('x', type: const DynamicType());
-      return new TestCase<Statement>(
-          name: '/* suppose A {foo() {...}} A x; */ x.{A::foo}();',
-          node: new ExpressionStatement(new InstanceInvocation.byReference(
-              InstanceAccessKind.Instance,
-              new VariableGet(x),
-              method.name,
-              new Arguments([]),
-              interfaceTargetReference: method.reference,
-              functionType: method.getterType as FunctionType)),
-          expectation: ''
-              '(expr (invoke-instance (instance) (get-var "x^0" _) '
-              '(public "foo") () () () '
-              '"package:foo/bar.dart::A::@methods::foo" '
-              '(-> () () () () () () (dynamic))))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)
-                ..addBinder(x, nameClue: 'x')
-                ..extend()),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null)
-                ..addBinder(x, "x^0")
-                ..extend(),
-              component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Constructor constructor = new Constructor(new FunctionNode(null),
-          name: new Name('foo'), fileUri: uri);
-      Class klass = new Class(
-          name: 'A', constructors: <Constructor>[constructor], fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, classes: <Class>[klass]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-      return new TestCase<Statement>(
-          name: '/* suppose A {A.foo();} */ new A();',
-          node: new ExpressionStatement(new ConstructorInvocation.byReference(
-              constructor.reference, new Arguments([]))),
-          expectation: ''
-              '(expr (invoke-constructor'
-              ' "package:foo/bar.dart::A::@constructors::foo"'
-              ' () () ()))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = new Uri(scheme: 'package', path: 'foo/bar.dart');
-      Constructor constructor = new Constructor(new FunctionNode(null),
-          name: new Name('foo'), isConst: true, fileUri: uri);
-      Class klass = new Class(
-          name: 'A', constructors: <Constructor>[constructor], fileUri: uri);
-      Library library = new Library(uri, fileUri: uri, classes: <Class>[klass]);
-      Component component = new Component(libraries: <Library>[library]);
-      component.computeCanonicalNames();
-      return new TestCase<Statement>(
-          name: '/* suppose A {const A.foo();} */ const A();',
-          node: new ExpressionStatement(new ConstructorInvocation.byReference(
-              constructor.reference, new Arguments([]), isConst: true)),
-          expectation: ''
-              '(expr (invoke-const-constructor'
-              ' "package:foo/bar.dart::A::@constructors::foo"'
-              ' () () ()))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: statementSerializer);
-    }(),
-    () {
-      TypeParameter outerParam =
-          new TypeParameter('T', const DynamicType(), const DynamicType());
-      TypeParameter innerParam =
-          new TypeParameter('T', const DynamicType(), const DynamicType());
-      return new TestCase<Statement>(
-          name: '/* T Function<T>(T Function<T>()); */',
-          node: new ExpressionStatement(new TypeLiteral(new FunctionType(
-              [
-                new FunctionType(
-                    [],
-                    new TypeParameterType(innerParam, Nullability.legacy),
-                    Nullability.legacy,
-                    typeParameters: [innerParam])
-              ],
-              new TypeParameterType(outerParam, Nullability.legacy),
-              Nullability.legacy,
-              typeParameters: [outerParam]))),
-          expectation: ''
-              '(expr (type (-> ("T^0") ((dynamic)) ((dynamic)) '
-              '((-> ("T^1") ((dynamic)) ((dynamic)) () () () '
-              '(par "T^1" _))) () () (par "T^0" _))))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), new CanonicalName.root()),
-          serializer: statementSerializer);
-    }(),
-    () {
-      TypeParameter t =
-          new TypeParameter('T', const DynamicType(), const DynamicType());
-      VariableDeclaration t1 = new VariableDeclaration('t1',
-          type: new TypeParameterType(t, Nullability.legacy));
-      VariableDeclaration t2 = new VariableDeclaration('t2',
-          type: new TypeParameterType(t, Nullability.legacy));
-      return new TestCase<Statement>(
-          name: '/* <T>(T t1, [T t2]) => t1; */',
-          node: new ExpressionStatement(new FunctionExpression(new FunctionNode(
-              new ReturnStatement(new VariableGet(t1)),
-              typeParameters: [t],
-              positionalParameters: [t1, t2],
-              requiredParameterCount: 1,
-              namedParameters: [],
-              returnType: new TypeParameterType(t, Nullability.legacy),
-              asyncMarker: AsyncMarker.Sync))),
-          expectation: ''
-              '(expr (fun (sync) ("T^0") ((dynamic)) ((dynamic)) ("t1^1" '
-              '() (par "T^0" _) _ ()) ("t2^2" () (par "T^0" _) '
-              '_ ()) () (par "T^0" _) _ (ret (get-var "t1^1" _))))',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), new CanonicalName.root()),
-          serializer: statementSerializer);
-    }(),
-    () {
-      Uri uri = Uri(scheme: 'package', path: 'foo/bar.dart');
-      VariableDeclaration x = VariableDeclaration('x', type: DynamicType());
-      Procedure foo = Procedure(
-          Name('foo'),
-          ProcedureKind.Method,
-          FunctionNode(ReturnStatement(VariableGet(x)),
-              positionalParameters: [x]),
-          isStatic: true,
-          fileUri: uri);
-      Library library = Library(uri, fileUri: uri, procedures: [foo]);
-      Component component = Component(libraries: [library]);
-      component.computeCanonicalNames();
-      return new TestCase<Member>(
-          name: 'foo(x) => x;',
-          node: foo,
-          expectation: ''
-              '(method (public "foo") ((static))'
-              ' (sync) () () () ("x^0" () (dynamic) _ ()) () ()'
-              ' (dynamic) _ (ret (get-var "x^0" _))'
-              ' "package:foo/bar.dart")',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: memberSerializer);
-    }(),
-    () {
-      Uri uri = Uri(scheme: 'package', path: 'foo/bar.dart');
-      VariableDeclaration x1 = VariableDeclaration('x', type: DynamicType());
-      VariableDeclaration x2 = VariableDeclaration('x', type: DynamicType());
-      Procedure foo = Procedure(
-          Name('foo'),
-          ProcedureKind.Method,
-          FunctionNode(ReturnStatement(VariableGet(x1)),
-              positionalParameters: [x1]),
-          isStatic: true,
-          fileUri: uri);
-      Procedure bar = Procedure(
-          Name('bar'),
-          ProcedureKind.Method,
-          FunctionNode(
-              ReturnStatement(
-                  StaticInvocation(foo, Arguments([VariableGet(x2)]))),
-              positionalParameters: [x2]),
-          isStatic: true,
-          fileUri: uri);
-      Library library = Library(uri, fileUri: uri, procedures: [foo, bar]);
-      Component component = Component(libraries: [library]);
-      component.computeCanonicalNames();
-      return new TestCase<Library>(
-          name: 'foo(x) => x; bar(x) => foo(x);',
-          node: library,
-          expectation: ''
-              '"package:foo/bar.dart" () ()'
-              ''
-              ' ((method (public "foo") ((static))'
-              ' (sync) () () () ("x^0" () (dynamic) _ ()) () () (dynamic)'
-              ' _ (ret (get-var "x^0" _))'
-              ' "package:foo/bar.dart")'
-              ''
-              ' (method (public "bar") ((static))'
-              ' (sync) () () () ("x^0" () (dynamic) _ ()) () () (dynamic)'
-              ' _ (ret'
-              ' (invoke-static "package:foo/bar.dart::@methods::foo"'
-              ' () ((get-var "x^0" _)) ()))'
-              ' "package:foo/bar.dart"))'
-              ''
-              ' ()'
-              ''
-              ' ()'
-              ''
-              ' ()'
-              ''
-              ' "package:foo/bar.dart"',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), new CanonicalName.root()),
-          serializer: librarySerializer);
-    }(),
-    () {
-      Uri uri = Uri(scheme: "package", path: "foo/bar.dart");
-      Class a = Class(name: "A", fileUri: uri);
-      Procedure foo = Procedure(
-          Name("foo"),
-          ProcedureKind.Method,
-          FunctionNode(ReturnStatement(NullLiteral()),
-              returnType: InterfaceType(a, Nullability.legacy)),
-          isStatic: true,
-          fileUri: uri);
-      Library library =
-          Library(uri, fileUri: uri, classes: [a], procedures: [foo]);
-      Component component = Component(libraries: [library]);
-      component.computeCanonicalNames();
-      return new TestCase<Library>(
-          name: 'class A{} A foo() => null;',
-          node: library,
-          expectation: ''
-              '"package:foo/bar.dart" () ()'
-              ''
-              ' ((method (public "foo") ((static))'
-              ' (sync) () () () () () () (interface "package:foo/bar.dart::A" ())'
-              ' _ (ret (null))'
-              ' "package:foo/bar.dart"))'
-              ''
-              ' ("A" () "package:foo/bar.dart" () () () _ _ () ())'
-              ''
-              ' ()'
-              ''
-              ' ()'
-              ''
-              ' "package:foo/bar.dart"',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), component.root),
-          serializer: librarySerializer);
-    }(),
-    () {
-      return new TestCase<Statement>(
-          name: 'dynamic x;',
-          node: VariableDeclaration('x', type: const DynamicType()),
-          expectation: '(local "x^0" () (dynamic) _ ())',
-          makeSerializationState: () =>
-              new SerializationState(new SerializationEnvironment(null)),
-          makeDeserializationState: () => new DeserializationState(
-              new DeserializationEnvironment(null), new CanonicalName.root()),
-          serializer: statementSerializer);
-    }(),
-  ];
-  for (TestCase testCase in tests) {
-    String roundTripInput =
-        testCase.writeNode(testCase.node, testCase.makeSerializationState());
-    if (roundTripInput != testCase.expectation) {
-      failures.add(''
-          "* initial serialization for test '${testCase.name}'"
-          " gave output:\n    ${roundTripInput}\n"
-          "  but expected:\n    ${testCase.expectation}");
-    }
-
-    Node deserialized =
-        testCase.readNode(roundTripInput, testCase.makeDeserializationState());
-    String roundTripOutput =
-        testCase.writeNode(deserialized, testCase.makeSerializationState());
-    if (roundTripOutput != roundTripInput) {
-      failures.add(''
-          "* input '${testCase.name}' gave output '${roundTripOutput}'");
-    }
-  }
-  if (failures.isNotEmpty) {
-    print('Round trip failures:');
-    failures.forEach(print);
-    throw StateError('Round trip failures');
-  }
-}
diff --git a/pkg/kernel/test/text_serializer_test.dart b/pkg/kernel/test/text_serializer_test.dart
deleted file mode 100644
index a08ce79..0000000
--- a/pkg/kernel/test/text_serializer_test.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2018, 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.
-
-library kernel.text_serializer_test;
-
-import 'package:kernel/ast.dart';
-import 'package:kernel/text/serializer_combinators.dart';
-import 'package:kernel/text/text_reader.dart';
-import 'package:kernel/text/text_serializer.dart';
-
-void main() {
-  initializeSerializers();
-  TestRunner testRunner = new TestRunner();
-  testRunner.run();
-  if (testRunner.failures.isNotEmpty) {
-    print('Round trip failures:');
-    testRunner.failures.forEach(print);
-    throw StateError('Round trip failures');
-  }
-}
-
-// Wrappers for testing.
-Expression readExpression(String input) {
-  TextIterator stream = new TextIterator(input, 0);
-  stream.moveNext();
-  Expression result = expressionSerializer.readFrom(
-      stream,
-      new DeserializationState(
-          new DeserializationEnvironment(null), new CanonicalName.root()));
-  if (stream.moveNext()) {
-    throw StateError("extra cruft in basic literal");
-  }
-  return result;
-}
-
-String writeExpression(Expression expression) {
-  StringBuffer buffer = new StringBuffer();
-  expressionSerializer.writeTo(buffer, expression,
-      new SerializationState(new SerializationEnvironment(null)));
-  return buffer.toString();
-}
-
-class TestRunner {
-  final List<String> failures = [];
-
-  void run() {
-    test('(get-super (public "hashCode"))');
-    test('(let "x^0" () (dynamic) (int 0) () (null))');
-    test('(let "x^0" () (dynamic) _ () (null))');
-    test('(let "x^0" ((const)) (dynamic) (int 0) () (null))');
-    test('(let "x^0" ((const)) (dynamic) _ () (null))');
-    test('(let "x^0" ((final)) (dynamic) (int 0) () (null))');
-    test('(let "x^0" ((final)) (dynamic) _ () (null))');
-    test(r'''(string "Hello, 'string'!")''');
-    test(r'''(string "Hello, \"string\"!")''');
-    test(r'''(string "Yeah nah yeah, here is\nthis really long string haiku\n'''
-        r'''blowing in the wind\n")''');
-    test('(int 42)');
-    test('(int 0)');
-    test('(int -1001)');
-    test('(double 3.14159)');
-    test('(bool true)');
-    test('(bool false)');
-    test('(null)');
-    test(r'''(invalid "You can't touch this" (null))''');
-    test('(not (bool true))');
-    test('(&& (bool true) (bool false))');
-    test('(|| (&& (bool true) (not (bool true))) (bool true))');
-    test('(concat ((string "The opposite of ") (int 3) '
-        '(string " is ") (int 7)))');
-    test('(symbol "unquote-splicing")');
-    test('(this)');
-    test('(rethrow)');
-    test('(throw (string "error"))');
-    test('(await (null))');
-    test('(cond (bool true) (dynamic) (int 0) (int 1))');
-    test('(is (bool true) (invalid))');
-    test('(as (bool true) (void))');
-    test('(type (null-type))');
-    test('(list (dynamic) ((null) (null) (null)))');
-    test('(const-list (dynamic) ((int 0) (int 1) (int 2)))');
-    test('(set (dynamic) ((bool true) (bool false) (int 0)))');
-    test('(const-set (dynamic) ((int 0) (int 1) (int 2)))');
-    test('(map (dynamic) (void)'
-        ' ((int 0) (null) (int 1) (null) (int 2) (null)))');
-    test('(const-map (dynamic) (void) ((int 0) (null) (int 1) (null) '
-        '(int 2) (null)))');
-    test('(type (-> () () () ((dynamic)) () () (dynamic)))');
-    test('(type (-> () () () () ((dynamic)) () (dynamic)))');
-    test('(type (-> () () () ((dynamic) (dynamic)) () () (dynamic)))');
-    test('(type (-> () () () () () () (dynamic)))');
-    test('(type (-> () () () ((-> () () () ((dynamic)) () () (dynamic))) () () '
-        '(dynamic)))');
-    test('(type (-> ("T^0") ((dynamic)) ((dynamic)) () () () (dynamic)))');
-    test('(type (-> ("T^0") ((dynamic)) ((dynamic)) ((par "T^0" _)) () () '
-        '(par "T^0" _)))');
-    test('(type (-> ("T^0" "S^1") ((par "S^1" _) (par "T^0" _)) ((dynamic) '
-        '(dynamic)) () () () (dynamic)))');
-  }
-
-  void test(String input) {
-    var kernelAst = readExpression(input);
-    var output = writeExpression(kernelAst);
-    if (output != input) {
-      failures.add('* input "${input}" gave output "${output}"');
-    }
-  }
-}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index b7d1949..2fd2aac 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -56,7 +56,6 @@
 front_end/test/fasta/bootstrap_test: Pass, Slow
 front_end/test/fasta/rasta/*: SkipByDesign # Anything in rasta is input to fasta unit tests and shouldn't be run as tests.
 front_end/test/fasta/sdk_test: SkipByDesign # sdk_test would take too long to complete, and should be run in a different way.
-front_end/test/fasta/text_serialization_test: Pass, ExtraSlow
 front_end/test/fasta/types/dart2js_benchmark_test: Pass, Slow
 front_end/test/fasta/types/large_app_benchmark_test: Pass, ExtraSlow
 front_end/test/incremental_compiler_leak_test: Pass, ExtraSlow
@@ -148,7 +147,6 @@
 [ $system == windows ]
 front_end/test/fasta/bootstrap_test: Skip # Issue 31902
 front_end/test/fasta/strong_test: Pass, Slow, Timeout
-front_end/test/fasta/text_serialization_test: Pass, Slow, Timeout
 front_end/test/incremental_dart2js_load_from_dill_test: Pass, Slow
 
 [ $browser ]
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index d20cf54..84694a6 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1739,13 +1739,6 @@
   // how the vm_tag (kEmbedderTagId) can be set, these tags need to
   // move to the OSThread structure.
   set_user_tag(UserTags::kDefaultUserTag);
-
-  if (group()->obfuscate()) {
-    OS::PrintErr(
-        "Warning: This VM has been configured to obfuscate symbol information "
-        "which violates the Dart standard.\n"
-        "         See dartbug.com/30524 for more information.\n");
-  }
 }
 
 #undef REUSABLE_HANDLE_SCOPE_INIT
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 47633fe..8814320 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -25878,12 +25878,6 @@
         isolate_instructions_image.instructions_relocated_address();
     auto const vm_relocated_address =
         vm_instructions_image.instructions_relocated_address();
-    // The Dart standard requires the output of StackTrace.toString to include
-    // all pending activations with precise source locations (i.e., to expand
-    // inlined frames and provide line and column numbers).
-    buffer.Printf(
-        "Warning: This VM has been configured to produce stack traces "
-        "that violate the Dart standard.\n");
     // This prologue imitates Android's debuggerd to make it possible to paste
     // the stack trace into ndk-stack.
     buffer.Printf(
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index f4da9ca..ca05fc6 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -109,7 +109,6 @@
         CastStreamTransformer,
         checkNotNullable,
         EmptyIterator,
-        isNullFuture,
         IterableElementError,
         nullFuture,
         printToZone,
diff --git a/sdk/lib/async/future.dart b/sdk/lib/async/future.dart
index 908e5e1..f83386d 100644
--- a/sdk/lib/async/future.dart
+++ b/sdk/lib/async/future.dart
@@ -223,6 +223,13 @@
 /// it's very clearly documented.
 @pragma("wasm:entry-point")
 abstract class Future<T> {
+  /// A `Future<Null>` completed with `null`.
+  ///
+  /// Currently shared with `dart:internal`.
+  /// If that future can be removed, then change this back to
+  /// `_Future<Null>.zoneValue(null, _rootZone);`
+  static final _Future<Null> _nullFuture = nullFuture as _Future<Null>;
+
   /// A `Future<bool>` completed with `false`.
   static final _Future<bool> _falseFuture =
       new _Future<bool>.zoneValue(false, _rootZone);
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index bb942d9..038c3bb 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -515,7 +515,7 @@
       controller
         ..onCancel = () {
           timer.cancel();
-          return nullFuture;
+          return Future._nullFuture;
         }
         ..onPause = () {
           watch.stop();
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 2d381c5..2baf008 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -588,10 +588,7 @@
   Future<void> get done => _ensureDoneFuture();
 
   Future<void> _ensureDoneFuture() =>
-      _doneFuture ??
-      (_isCanceled
-          ? nullFuture as Future<void>
-          : _doneFuture = _Future<void>());
+      _doneFuture ??= _isCanceled ? Future._nullFuture : _Future<void>();
 
   /// Send or enqueue a data event.
   void add(T value) {
@@ -922,7 +919,7 @@
     var cancel = addSubscription.cancel();
     if (cancel == null) {
       addStreamFuture._asyncComplete(null);
-      return nullFuture;
+      return Future._nullFuture;
     }
     return cancel.whenComplete(() {
       addStreamFuture._asyncComplete(null);
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 9065c46..b4fb5d8 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -197,7 +197,7 @@
     if (!_isCanceled) {
       _cancel();
     }
-    return _cancelFuture ?? nullFuture;
+    return _cancelFuture ?? Future._nullFuture;
   }
 
   Future<E> asFuture<E>([E? futureValue]) {
@@ -217,7 +217,7 @@
     };
     _onError = (Object error, StackTrace stackTrace) {
       Future cancelFuture = cancel();
-      if (!isNullFuture(Zone._current, cancelFuture)) {
+      if (!identical(cancelFuture, Future._nullFuture)) {
         cancelFuture.whenComplete(() {
           result._completeError(error, stackTrace);
         });
@@ -297,7 +297,7 @@
   // Hooks called when the input is paused, unpaused or canceled.
   // These must not throw. If overwritten to call user code, include suitable
   // try/catch wrapping and send any errors to
-  // [Zone._current.handleUncaughtError].
+  // [_Zone.current.handleUncaughtError].
   void _onPause() {
     assert(_isInputPaused);
   }
@@ -352,6 +352,7 @@
       // future to finish we must not report the error.
       if (_isCanceled && !_waitsForCancel) return;
       _state |= _STATE_IN_CALLBACK;
+      // TODO(floitsch): this dynamic should be 'void'.
       var onError = _onError;
       if (onError is void Function(Object, StackTrace)) {
         _zone.runBinaryGuarded<Object, StackTrace>(onError, error, stackTrace);
@@ -365,7 +366,8 @@
       _state |= _STATE_WAIT_FOR_CANCEL;
       _cancel();
       var cancelFuture = _cancelFuture;
-      if (cancelFuture != null && !isNullFuture(Zone._current, cancelFuture)) {
+      if (cancelFuture != null &&
+          !identical(cancelFuture, Future._nullFuture)) {
         cancelFuture.whenComplete(sendError);
       } else {
         sendError();
@@ -394,7 +396,7 @@
     _cancel();
     _state |= _STATE_WAIT_FOR_CANCEL;
     var cancelFuture = _cancelFuture;
-    if (cancelFuture != null && !isNullFuture(Zone._current, cancelFuture)) {
+    if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
       cancelFuture.whenComplete(sendDone);
     } else {
       sendDone();
@@ -670,7 +672,7 @@
     }
   }
 
-  Future cancel() => nullFuture;
+  Future cancel() => Future._nullFuture;
 
   Future<E> asFuture<E>([E? futureValue]) {
     E resultValue;
@@ -817,7 +819,7 @@
 
   Future cancel() {
     _stream._cancelSubscription();
-    return nullFuture;
+    return Future._nullFuture;
   }
 
   bool get isPaused {
@@ -961,7 +963,7 @@
       }
       return subscription.cancel();
     }
-    return nullFuture;
+    return Future._nullFuture;
   }
 
   void _onData(T data) {
diff --git a/sdk/lib/async/stream_pipe.dart b/sdk/lib/async/stream_pipe.dart
index 78ad675..cd707be 100644
--- a/sdk/lib/async/stream_pipe.dart
+++ b/sdk/lib/async/stream_pipe.dart
@@ -26,7 +26,7 @@
 void _cancelAndError(StreamSubscription subscription, _Future future,
     Object error, StackTrace stackTrace) {
   var cancelFuture = subscription.cancel();
-  if (cancelFuture != null && !isNullFuture(Zone._current, cancelFuture)) {
+  if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
     cancelFuture.whenComplete(() => future._completeError(error, stackTrace));
   } else {
     future._completeError(error, stackTrace);
@@ -55,7 +55,7 @@
   before completing with a value. */
 void _cancelAndValue(StreamSubscription subscription, _Future future, value) {
   var cancelFuture = subscription.cancel();
-  if (cancelFuture != null && !isNullFuture(Zone._current, cancelFuture)) {
+  if (cancelFuture != null && !identical(cancelFuture, Future._nullFuture)) {
     cancelFuture.whenComplete(() => future._complete(value));
   } else {
     future._complete(value);
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 4bc1905..671f68a 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -37302,7 +37302,7 @@
   }
 
   Future cancel() {
-    if (_canceled) return Future<void>.value(null);
+    if (_canceled) return nullFuture;
 
     _unlisten();
     // Clear out the target to indicate this is complete.
diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart
index a763b12..ff3d890 100644
--- a/sdk/lib/internal/internal.dart
+++ b/sdk/lib/internal/internal.dart
@@ -136,7 +136,7 @@
   return digit1 * 16 + digit2 - (digit2 & 256);
 }
 
-/// A reusable `null`-valued future per zone used by `dart:async`.
+/// A reusable `null`-valued future used by `dart:async`.
 ///
 /// **DO NOT USE.**
 ///
@@ -156,14 +156,7 @@
 /// This future will be removed again if we can ever do so.
 /// Do not use it for anything other than preserving timing
 /// during the null safety migration.
-Future<Null> get nullFuture => _nullFutures[Zone.current] ??= 
-    Future<Null>.value(null);
-
-/// Whether [future] is the null future of the current zone.
-bool isNullFuture(Zone zone, Future future) =>
-    identical(_nullFutures[zone], future);
-
-final Expando<Future<Null>> _nullFutures = Expando<Future<Null>>();
+final Future<Null> nullFuture = Zone.root.run(() => Future<Null>.value(null));
 
 /// A default hash function used by the platform in various places.
 ///
diff --git a/tests/lib/async/null_future_zone_test.dart b/tests/lib/async/null_future_zone_test.dart
index 34201e7..9a266be 100644
--- a/tests/lib/async/null_future_zone_test.dart
+++ b/tests/lib/async/null_future_zone_test.dart
@@ -13,32 +13,21 @@
     Expect.isFalse(await it.moveNext());
 
     late Future nullFuture;
-
-    bool nullFutureZoneUsed = false;
-    runZoned(() {
-      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
-    }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
-        (Zone self, ZoneDelegate parent, Zone zone, void f()) {
-      Expect.identical(zone, self);
-      nullFutureZoneUsed = true;
-      parent.scheduleMicrotask(zone, f);
-    }));
-
-    nullFuture.then((value) {
-      Expect.isNull(value);
-      Expect.isTrue(nullFutureZoneUsed);
-      asyncEnd();
-    });
-
     late Future falseFuture;
 
     runZoned(() {
+      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
       falseFuture = it.moveNext();
     }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
         (Zone self, ZoneDelegate parent, Zone zone, void f()) {
       Expect.fail("Should not be called");
     }));
 
+    nullFuture.then((value) {
+      Expect.isNull(value);
+      asyncEnd();
+    });
+
     falseFuture.then((value) {
       Expect.isFalse(value);
       asyncEnd();
diff --git a/tests/lib_2/async/null_future_zone_test.dart b/tests/lib_2/async/null_future_zone_test.dart
index 77cb1b7..3322916 100644
--- a/tests/lib_2/async/null_future_zone_test.dart
+++ b/tests/lib_2/async/null_future_zone_test.dart
@@ -15,32 +15,21 @@
     Expect.isFalse(await it.moveNext());
 
     Future nullFuture;
-
-    bool nullFutureZoneUsed = false;
-    runZoned(() {
-      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
-    }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
-        (Zone self, ZoneDelegate parent, Zone zone, void f()) {
-      Expect.identical(zone, self);
-      nullFutureZoneUsed = true;
-      parent.scheduleMicrotask(zone, f);
-    }));
-
-    nullFuture.then((value) {
-      Expect.isNull(value);
-      Expect.isTrue(nullFutureZoneUsed);
-      asyncEnd();
-    });
-
     Future falseFuture;
 
     runZoned(() {
+      nullFuture = (new StreamController()..stream.listen(null).cancel()).done;
       falseFuture = it.moveNext();
     }, zoneSpecification: new ZoneSpecification(scheduleMicrotask:
         (Zone self, ZoneDelegate parent, Zone zone, void f()) {
       Expect.fail("Should not be called");
     }));
 
+    nullFuture.then((value) {
+      Expect.isNull(value);
+      asyncEnd();
+    });
+
     falseFuture.then((value) {
       Expect.isFalse(value);
       asyncEnd();
diff --git a/tools/VERSION b/tools/VERSION
index 05a2446..1e379b9 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 212
+PRERELEASE 213
 PRERELEASE_PATCH 0
\ No newline at end of file
