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 db738dd..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));
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/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/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 ]
